多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
从前面的章节我们也知道,LwIP在操作系统的环境下,LwIP内核是作为操作系统的一个线程运行的,在协议栈初始化的时候就会创建tcpip\_thread线程,那么我们现在来看看tcpip\_thread线程到底是怎么样的东西,具体见代码清单 9‑7。 ``` 1 static void 2 tcpip_thread(void *arg) 3 { 4 struct tcpip_msg *msg; 5 LWIP_UNUSED_ARG(arg); 6 7 LWIP_MARK_TCPIP_THREAD(); 8 9 LOCK_TCPIP_CORE(); 10 if (tcpip_init_done != NULL) 11 { 12 tcpip_init_done(tcpip_init_done_arg); 13 } 14 15 while (1) 16 { 17 LWIP_TCPIP_THREAD_ALIVE(); 18 /* 等待消息,等待时处理超时 */ 19 TCPIP_MBOX_FETCH(&tcpip_mbox, (void **)&msg); (1) 20 if (msg == NULL) 21 { 22 continue; (2) 23 } 24 tcpip_thread_handle_msg(msg); (3) 25 } 26 } ``` (1):LwIP将函数tcpip_timeouts_mbox_fetch()定义为带参宏TCPIP_MBOX_FETCH,所以在这里就是等待消息并且处理超时事件。 (2):如果没有等到消息就继续等待。 (3):等待到消息就对消息进行处理,这个函数具体见代码清单 9 8。 ``` 1 static void 2 tcpip_thread_handle_msg(struct tcpip_msg *msg) 3 { 4 switch (msg->type) 5 { 6 #if !LWIP_TCPIP_CORE_LOCKING 7 case TCPIP_MSG_API: 8 msg->msg.api_msg.function(msg->msg.api_msg.msg); (1) 9 break; 10 case TCPIP_MSG_API_CALL: 11 msg->msg.api_call.arg->err = 12 msg->msg.api_call.function(msg->msg.api_call.arg); (2) 13 sys_sem_signal(msg->msg.api_call.sem); 14 break; 15 #endif /* !LWIP_TCPIP_CORE_LOCKING */ 16 17 #if !LWIP_TCPIP_CORE_LOCKING_INPUT 18 case TCPIP_MSG_INPKT: 19 if (msg->msg.inp.input_fn(msg->msg.inp.p, msg->msg.inp.netif) != ERR_OK) (3) 20 { 21 pbuf_free(msg->msg.inp.p); 22 } 23 memp_free(MEMP_TCPIP_MSG_INPKT, msg); 24 break; 25 #endif /* !LWIP_TCPIP_CORE_LOCKING_INPUT */ 26 27 #if LWIP_TCPIP_TIMEOUT && LWIP_TIMERS 28 case TCPIP_MSG_TIMEOUT: 29 sys_timeout(msg->msg.tmo.msecs, msg->msg.tmo.h, msg->msg.tmo.arg);(4) 30 memp_free(MEMP_TCPIP_MSG_API, msg); 31 break; 32 case TCPIP_MSG_UNTIMEOUT: 33 sys_untimeout(msg->msg.tmo.h, msg->msg.tmo.arg); (5) 34 memp_free(MEMP_TCPIP_MSG_API, msg); 35 break; 36 #endif /* LWIP_TCPIP_TIMEOUT && LWIP_TIMERS */ 37 38 case TCPIP_MSG_CALLBACK: 39 msg->msg.cb.function(msg->msg.cb.ctx); (6) 40 memp_free(MEMP_TCPIP_MSG_API, msg); 41 break; 42 43 case TCPIP_MSG_CALLBACK_STATIC: 44 msg->msg.cb.function(msg->msg.cb.ctx); (7) 45 break; 46 47 default: 48 break; 49 } 50 } ``` (1)(2):根据消息中的不同类型进行不同的处理,对于TCPIP_MSG_API类型,就执行对应的API函数。 (3):对于TCPIP_MSG_INPKT类型,直接交给ARP层处理。 (4):对于TCPIP_MSG_TIMEOUT类型,表示上层注册一个超时事件,直接执行注册超时事件即可。 (5):相反的,对于TCPIP_MSG_ UNTIMEOUT类型,表示上层删除一个超时事件,直接执行删除超时事件即可。 (6)(7):对于TCPIP_MSG_CALLBACK或者是TCPIP_MSG_CALLBACK_STATIC类型,表示上层通过回调方式执行一个回调函数,那么就执行对应的回调函数即可。