如果使用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的地址,即指针的指针,其实是指针的地址。