PPP LWIP中断安全 线程安全

 在做ppp驱动3G/4G模块时,用的LWIP协议栈,循环接收处理串口数据时,会调用这2个函数中的一个
pppos_input();
pppos_input_tcpip()

看下面这段话,我理解的意思是,pppos_input_tcpip()是线程安全的,可以随便调用, 但是也不要从串口收到一个字节就调用1 次, 而pppos_input()是线程不安全的,如果在运行pppos_input()的时候,不能调用NEVER call pppos_connect(), pppos_listen() and ppp_free() ,这些函数。




PPPoS input path (raw API, IRQ safe API, TCPIP API)
=====================================================

Received data on serial port should be sent to lwIP using the pppos_input()
function or the pppos_input_tcpip() function.

If NO_SYS is 1 and if PPP_INPROC_IRQ_SAFE is 0 (the default), pppos_input()
is not IRQ safe and then *MUST* only be called inside your main loop.

Whatever the NO_SYS value, if PPP_INPROC_IRQ_SAFE is 1, pppos_input() is IRQ
safe and can be safely called from an interrupt context, using that is going
to reduce your need of buffer if pppos_input() is called byte after byte in
your rx serial interrupt.

if NO_SYS is 0, the thread safe way outside an interrupt context is to use
the pppos_input_tcpip() function to pass input data to the lwIP core thread
using the TCPIP API. This is thread safe in all cases but you should avoid
passing data byte after byte because it uses heavy locking (mailbox) and it
allocates pbuf, better fill them !

if NO_SYS is 0 and if PPP_INPROC_IRQ_SAFE is 1, you may also use pppos_input()
from an RX thread, however pppos_input() is not thread safe by itself. You can
do that *BUT* you should NEVER call pppos_connect(), pppos_listen() and
ppp_free() if pppos_input() can still be running, doing this is NOT thread safe
at all. Using PPP_INPROC_IRQ_SAFE from an RX thread is discouraged unless you
really know what you are doing, your move ;-)


下面只分析pppos_input_tcpip,因为这个简单,
err_t
pppos_input_tcpip(ppp_pcb *ppp, u8_t *s, int l)
{
  struct pbuf *p;
  err_t err;

  p = pbuf_alloc(PBUF_RAW, l, PBUF_POOL);
  if (!p) {
    return ERR_MEM;
  }
  pbuf_take(p, s, l);

  err = tcpip_inpkt(p, ppp_netif(ppp), pppos_input_sys);
  if (err != ERR_OK) {
     pbuf_free(p);
  }
  return err;
}

上面可以看出来,它是怎么实现线程安全的,当pppos_input_tcpip收到数据时,它直接分配1个pbuf,把数据放在pbuf中,然后提交处理,这种办法的缺点也是很明显的,数据每次收到的串口数据较少时,会频率的分配内存释放内存,严重浪费了CPU资源, 它是以占用内存,占用CPU资源为代价来实现线程安全的。

pppos_input就不分析了,大概就是直接分析pppos串口数据,剔除escaped转义字符,直接给上层(TCPIP)提交ether报文,我认为这样处理效率高多了。

你可能感兴趣的:(tcpip,线程安全,ppp)