lwip rawapi TCP接收数据函数调用链

最近做一个东西需要使用网络协议,使用SPI接亚信AX88796C。 使用开源的LWIP协议栈。看了一下从tcp_recv到底层驱动的调用,以便移植。查了一下tcp_recv
/**
 * Used to specify the function that should be called when a TCP
 * connection receives data.
 *
 * @param pcb tcp_pcb to set the recv callback
 * @param recv callback function to call for this pcb when data is received
 */ 
void
tcp_recv(struct tcp_pcb *pcb,
   err_t (* recv)(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err))
{
  pcb->recv = recv;
}

只是把用户的接收函数挂在pcb结构里。需要找到recv真正调用的地方。

其实是下面这个宏:

#define TCP_EVENT_RECV(pcb,p,err,ret)                           \
  do {                                                          \
    if((pcb)->recv != NULL) {                                   \
      (ret) = (pcb)->recv((pcb)->callback_arg,(pcb),(p),(err)); \
    } else {                                                    \
      (ret) = ERR_OK;                                           \
      if (p != NULL)                                            \
        pbuf_free(p);                                           \
    }                                                           \
  } while (0)

找到这个宏是在

/**
 * The initial input processing of TCP. It verifies the TCP header, demultiplexes
 * the segment between the PCBs and passes it on to tcp_process(), which implements
 * the TCP finite state machine. This function is called by the IP layer (in
 * ip_input()).
 *
 * @param p received TCP segment to process (p->payload pointing to the IP header)
 * @param inp network interface on which this segment was received
 */
void
tcp_input(struct pbuf *p, struct netif *inp)
{
				:
          /* Notify application that data has been received. */
          TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err);
				:
}






在tcp_in.c中有段注释

/**
 * @file
 * Transmission Control Protocol, incoming traffic
 *
 * The input processing functions of the TCP layer.
 *
 * These functions are generally called in the order (ip_input() ->)
 * tcp_input() -> * tcp_process() -> tcp_receive() (-> application).
 * 
 */

就是数据的处理流程从ip到tcp到用户的app,就是这个顺序。在数据准备好之后调用TCP_EVENT_RECV().

ip_input()则由ethernet_input调用。

ethernet_input则在xxxx_if.c中被xxxxif_input()调用

xxxxif_input()是在网络芯片的中断函数中调用。


所以基本流程就是

中断处理函数----〉xxxxif_input()-----〉ethernet_input() -----〉ip_input()------〉tcp_input()------〉tcp_process()-----〉 tcp_receive() (-> application)

|

|

--------〉CP_EVENT_RECV()


所以用户的recv函数应该也是属于在中断中执行的,如果recv函数中还需要使用中断则需要注意中断嵌套等问题。

你可能感兴趣的:(嵌入式)