由lwip的mbox中netbuf传递看指针的指针

如果使用netconn API的话,udp接收过程需要用到mbox传递接收的包(传递的是指针)

mbox发送过程:

api_msg.c中recv_udp中会将接收的包发送给udp的接收mbox

 sys_mbox_trypost传送的仅仅是netbuf的指针

 1 static void
 2 recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
 3    const ip_addr_t *addr, u16_t port)
 4 {
 5   struct netbuf *buf;
 6   struct netconn *conn;
 7   u16_t len;
 8 
 9 
10   buf = (struct netbuf *)memp_malloc(MEMP_NETBUF);
11   if (buf == NULL) {
12     pbuf_free(p);
13     return;
14   } else {
15     buf->p = p;
16     buf->ptr = p;
17     ip_addr_set(&buf->addr, addr);
18     buf->port = port;
19   }
20 
21   len = p->tot_len;
22   if (sys_mbox_trypost(&conn->recvmbox, buf) != ERR_OK) {
23     netbuf_delete(buf);
24     return;
25   } else {
26     /* Register event with callback */
27     API_EVENT(conn, NETCONN_EVT_RCVPLUS, len);
28   }
29 }

在sys_mbox_trypost中,调用FreeRTOS的消息队列发送函数,这里传送的就是buf的地址了,即netbuf的指针的指针

 1 err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
 2 {
 3 err_t result;
 4 
 5    if ( xQueueSend( *mbox, &msg, 0 ) == pdPASS )
 6    {
 7       result = ERR_OK;
 8    }
 9    else {
10       // could not post, queue must be full
11       result = ERR_MEM;
12    }
13 
14    return result;
15 }

mbox接收过程:

api_lib.c中完成udp的接收过程,netconn_recv主要完成TCP的接收,对于UDP其实是在netconn_recv_data函数中

 1 static err_t
 2 netconn_recv_data(struct netconn *conn, void **new_buf)
 3 {
 4   void *buf = NULL;
 5   u16_t len;
 6 
 7   *new_buf = NULL;
 8 
 9 
10 #if LWIP_SO_RCVTIMEO
11   if (sys_arch_mbox_fetch(&conn->recvmbox, &buf, conn->recv_timeout) == SYS_ARCH_TIMEOUT) {
12     return ERR_TIMEOUT;
13   }
14 #else
15   sys_arch_mbox_fetch(&conn->recvmbox, &buf, 0);
16 #endif /* LWIP_SO_RCVTIMEO*/
17 
18 
19 #if (LWIP_UDP || LWIP_RAW)
20   {
21     LWIP_ASSERT("buf != NULL", buf != NULL);
22     len = netbuf_len((struct netbuf*)buf);
23   }
24 #endif /* (LWIP_UDP || LWIP_RAW) */
25 
26 
27   /* Register event with callback */
28   API_EVENT(conn, NETCONN_EVT_RCVMINUS, len);
29 
30   LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_recv_data: received %p, len=%"U16_F"
", buf, len));
31 
32   *new_buf = buf;
33   /* don't set conn->last_err: it's only ERR_OK, anyway */
34   return ERR_OK;
35 }

在sys_arch_mbox_fetch中,msg的参数是一个指针的指针,因为要修改指针指向的位置,调用FreeRTOS的消息队列接收函数(该函数只有void*),xQrecv用的只是指针,前面post的可是指针的指针啊?

 1 u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
 2 {
 3 void *dummyptr;
 4 portTickType StartTime, EndTime, Elapsed;
 5 
 6     StartTime = xTaskGetTickCount();
 7         
 8     if ( timeout != 0 )
 9     {
10         if ( pdTRUE == xQueueReceive( *mbox, &(*msg), timeout / portTICK_RATE_MS ) )
11         {
12             EndTime = xTaskGetTickCount();
13             Elapsed = (EndTime - StartTime) * portTICK_RATE_MS;
14             
15             return ( Elapsed );
16         }
17         else // timed out blocking for message
18         {
19             *msg = NULL;
20             
21             return SYS_ARCH_TIMEOUT;
22         }
23     }
24     else // block forever for a message.
25     {
26         while( pdTRUE != xQueueReceive( *mbox, &(*msg), portMAX_DELAY ) ){} // time is arbitrary
27         EndTime = xTaskGetTickCount();
28         Elapsed = (EndTime - StartTime) * portTICK_RATE_MS;
29         
30         return ( Elapsed ); // return time blocked TODO test    
31     }
32 }

recv_udp              netconn_recv_data(**)

  netbuf *buf        

  try_post(*)        fetch(**)

    xQsend(**)    xQrecv(**)

 还是没太想明白~~~

 知乎里有一个回答https://www.zhihu.com/question/29180416

传递指针,是需要修改指针指向的变量

传递指针的指针,是需要修改指针本身,即修改指针指向的东西。比如udp_app中定义netbuf* buf,但该指针是空的,没有指向任何东西,在netconn_recv中需要将buf指向协议栈分配的那个netbuf,就需要修改buf指向的东西,所以,需要传递buf的地址,即指针的指针,其实是指针的地址。

原文地址:https://www.cnblogs.com/yanhc/p/8900614.html