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

2019-07-14 12:52发布

最近做一个东西需要使用网络协议,使用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函数中还需要使用中断则需要注意中断嵌套等问题。