zoukankan      html  css  js  c++  java
  • 由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的地址,即指针的指针,其实是指针的地址。

  • 相关阅读:
    [golang]golang signal.Notify 信号,如何优雅的退出
    解密
    [财务][数据化分析][帆软]报表设计-数据分析(op=view)
    [财务][数据化分析][帆软]报表设计-填报预览
    [财务][数据化分析][帆软]如何量化你的用户价值?RFM模型综合实战
    [数据分析][RFM模型]用数据分析用户
    [帆软][内网穿透][LanProxy]蛋疼的网络架构探讨
    [财务][数据化分析][帆软]报表设计-分页预览
    [财务][数据化分析][帆软]报表设计-模板预览
    [财务][数据化分析][帆软]报表设计-聚合报表设计
  • 原文地址:https://www.cnblogs.com/yanhc/p/8900614.html
Copyright © 2011-2022 走看看