【LwIP源码学习4】主线程tcpip_thread

前言

本文对lwip的主要线程tcpip_thread进行分析。

正文

tcpip_thread是lwip最主要的线程,其创建在tcpip_init函数中

sys_thread_new(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO);

tcpip_init函数被TCPIP_Init函数调用。
TCPIP_Init函数被用户应用程序调用。
在这里插入图片描述
创建任务的sys_thread_new函数在sys_arch.c文件中实现,sys_arch.c是操作系统相关的接口文件,在有操作系统环境下移植lwip时要对sys_arch.c中的函数进行实现。
tcpip_thread任务的内容如下:

static void
tcpip_thread(void *arg)
{struct tcpip_msg *msg;LWIP_UNUSED_ARG(arg);LWIP_MARK_TCPIP_THREAD();LOCK_TCPIP_CORE();//tcpip_init_done是一个函数指针//tcpip_init_done_arg是一个变量指针//这两个可以由用户设置,如果想在while循环执行前做些什么if (tcpip_init_done != NULL) {tcpip_init_done(tcpip_init_done_arg);}while (1) {                          /* MAIN Loop *///用户可以在opt.h文件中对下面这个宏进行函数定义//可以根据这个宏使得用户在应用层知道tcpip_thread任务还活着LWIP_TCPIP_THREAD_ALIVE();/* wait for a message, timeouts are processed while waiting *///等待邮箱中出现消息、处理超时事件TCPIP_MBOX_FETCH(&tcpip_mbox, (void **)&msg);if (msg == NULL) {LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: NULL\n"));LWIP_ASSERT("tcpip_thread: invalid message", 0);continue;}//处理接收到的消息tcpip_thread_handle_msg(msg);}
}

tcpip_init_done函数指针和tcpip_init_done_arg变量指针在tcpip_init中被设置

void
tcpip_init(tcpip_init_done_fn initfunc, void *arg)
{
...tcpip_init_done = initfunc;tcpip_init_done_arg = arg;
...
}

而在用户可以修改的sys_arch.c文件中对TCPIP_Init函数的实现:

void TCPIP_Init(void)
{
...tcpip_init(NULL, NULL);
...
}

LWIP_TCPIP_THREAD_ALIVE宏在opt.h文件中被定义

#if !defined LWIP_TCPIP_THREAD_ALIVE || defined __DOXYGEN__
#define LWIP_TCPIP_THREAD_ALIVE()
#endif

如果用于想监测tcpip_thread任务是否一直活着可以在这里进行修改。

TCPIP_MBOX_FETCHtcpip_timeouts_mbox_fetch函数的带参宏定义,用于等待邮箱中是否有需要处理的消息,或者检查是否有超时事件,如果有则执行其回调函数。

static void
tcpip_timeouts_mbox_fetch(sys_mbox_t *mbox, void **msg)
{u32_t sleeptime, res;again:LWIP_ASSERT_CORE_LOCKED();//获取距离最近超时事件的时间sleeptime = sys_timeouts_sleeptime();if (sleeptime == SYS_TIMEOUTS_SLEEPTIME_INFINITE) {//表示系统没有超时事件UNLOCK_TCPIP_CORE();//没有超时事件就无限期的一直等待邮箱中有消息到来sys_arch_mbox_fetch(mbox, msg, 0);LOCK_TCPIP_CORE();return;} else if (sleeptime == 0) {//表示有超时事件需要立刻执行//找出来超时事件并执行其回调函数sys_check_timeouts();/* We try again to fetch a message from the mbox. *///处理完需要立刻执行的超时事件后继续查看最近超时事件时间goto again;}//如果系统有超时事件但不还有一段时间触发,就执行以下代码UNLOCK_TCPIP_CORE();//等到邮箱中是否有消息,等待时间为sleeptime,也就是最近超时事件发生时间res = sys_arch_mbox_fetch(mbox, msg, sleeptime);LOCK_TCPIP_CORE();if (res == SYS_ARCH_TIMEOUT) {//表示邮箱等待超时了,没有等到邮箱中出现新的消息/* If a SYS_ARCH_TIMEOUT value is returned, a timeout occurredbefore a message could be fetched. */sys_check_timeouts(); //处理超时事件/* We try again to fetch a message from the mbox. */goto again; //继续查看是否有超时事件,没有就无限期等邮箱}
}

以上这个函数只有在收到邮箱中的一个消息之后才return返回,否则有超时事件就处理超时事件,没有则无限期等待邮箱中出现消息。
思考:似乎有个bug,如果一开始没有超时事件,在无限性等待邮箱中的消息时又出现超时事件了,那么如果一直等不到邮箱中的消息,新出现的超时事件就一直不会被处理了。可能这种情况不会发生,也可能lwip对这种情况有其他处理,还没看到。
其中等待邮箱中出现消息的sys_arch_mbox_fetch函数在sys_arch.c文件中,由用户移植时进行实现。

接下来调用tcpip_thread_handle_msg函数对消息进行分类处理。

static void
tcpip_thread_handle_msg(struct tcpip_msg *msg)
{switch (msg->type) {case TCPIP_MSG_API:...break;case TCPIP_MSG_API_CALL:...break;case TCPIP_MSG_INPKT:...break;case TCPIP_MSG_TIMEOUT:...break;case TCPIP_MSG_UNTIMEOUT:...break;case TCPIP_MSG_CALLBACK:...break;case TCPIP_MSG_CALLBACK_STATIC:...break;default:...break;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/57893.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

光圈,感光度,感光器件

光圈(通光孔),是一个用来控制光线透过镜头进入机身内感光面光量的装置,通常设置在镜头内。通常,我们用f值来表达光圈大小。通俗来说,摄像机镜头拍照时,不可能随意改变镜头直径,但可以…

Llama 3.2 Vision Molmo:多模态开源生态系统基础

编者按: 视觉功能的融入对模型能力和推理方式的影响如何?当我们需要一个既能看懂图像、又能生成文本的 AI 助手时,是否只能依赖于 GPT-4V 这样的闭源解决方案? 我们今天为大家分享的这篇文章,作者的核心观点是&#xf…

高效视频制作大提速,视频剪辑软件的高级自定义命令功能批量调整视频的色调、饱和度和亮度,轻松驾驭视频编辑技巧

在浩瀚的数字海洋中,视频如同璀璨的星辰,而每一颗星辰都渴望被精心雕琢,闪耀出最独特的光芒。想象一下,你手握一把神奇的钥匙,能够轻松解锁批量视频剪辑的奥秘,让每一帧画面都跃动着你的创意与激情。这把钥…

[RootersCTF2019]ImgXweb

审题 看到robots.txt,看到里面的文件,打开看到 you-will-never-guess这个字符串 进行注册登录 可以看到典型的jwt加密的Cookie 想到之前的字符串可能是密匙,更改为admin,进行登录。 成功后可以看到flag.png。 发现图形打不开 使用curl进…

32单片机HAL库的引脚初始化

在使用HAL库时,GPIO初始化函数定义在stm32f4xx_hal_gpio.c文件中,如下: void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init); 由这个函数可以看出,在初始化GPIO时,需要向函数传入2个结构体&…

ubuntu【桌面】 配置NAT模式固定IP

DHCP分配导致虚拟机IP老变,SSH老要重新配置,设成静态方便些 一、设NAT模式 1、设为NAT模式 2、看模式对应的虚拟网卡 - VMnet8 3、共享主机网卡网络到虚拟网卡 - VMnet8 二、为虚拟网卡设置静态IP 记住这个IP 三、设置ubuntu固定IP 1、关闭DHCP并…

确保企业架构与业务的一致性与合规性:数字化转型中的关键要素与战略实施

在现代企业的数字化转型过程中,确保企业架构(Enterprise Architecture, EA)与企业业务的紧密一致性与合规性至关重要。无论是在战略层面还是运营层面,EA都为企业的未来发展提供了清晰的蓝图,确保企业在应对复杂的业务环…

Pinctrl子需要中client端使用pinctrl过程的驱动分析

往期内容 本专栏往期内容: Pinctrl子系统和其主要结构体引入Pinctrl子系统pinctrl_desc结构体进一步介绍Pinctrl子系统中client端设备树相关数据结构介绍和解析inctrl子系统中Pincontroller构造过程驱动分析:imx_pinctrl_soc_info结构体 input子系统专栏…

Failed to search for file: Cannot update read-only repo

今天在读《Linux就该这么学》并上机操作RedHat Linux 8。结果在执行指令时却出现了问题: 我明明已经是root权限了,我于是上网去找,但也没看到合适的解答。为什么会和书上的操作结果不一样。 后来我突然意识到是不是我打了不该打的空格,于是…

SpringBoot实现验证码案例

目录 实现逻辑前后端交互接口前端代码后端代码 实现逻辑 1、后端功能:随机生成验证码图片,并把交给前端、接收用户输入,验证用户输入的验证码是否正确、 2、前端功能:显示验证码,提供输入框供用户输入他们看到的验证…

OpenCV基本操作(python开发)——(7)实现图像校正

OpenCV基本操作(python开发)——(1) 读取图像、保存图像 OpenCV基本操作(python开发)——(2)图像色彩操作 OpenCV基本操作(python开发)——(3&…

记录新建wordpress站的实践踩坑:wordpress 上传源码新建站因权限问题导致无法访问、配置新站建站向导以及插件主题上传配置的解决办法

官方文档:How to install WordPress – Advanced Administration Handbook | Developer.WordPress.org 但是没写权限问题,可以下载到 wordpress官方包。 把下载的wordpresscn的包解压并上传到服务器目录下,但是因为是root上传导致了权限问题…

qt QBrush详解

1、概述 QBrush是Qt框架中的一个基本图形对象类,它主要用于定义图形的填充模式。QBrush可以用于填充如矩形、椭圆形、多边形等形状,也可以用于绘制背景等。通过QBrush,可以设置填充的颜色、样式(如实心、渐变、纹理等&#xff09…

练习LabVIEW第三十四题

学习目标: 刚学了LabVIEW,在网上找了些题,练习一下LabVIEW,有不对不好不足的地方欢迎指正! 第三十四题: 在一个波形表中显示三条随机数组成的曲线,分别用红,绿,蓝三种…

彻底理解链表(LinkedList)结构

目录 比较操作结构封装单向链表实现面试题 循环链表实现 双向链表实现 链表(Linked List)是一种线性数据结构,由一组节点(Node)组成,每个节点包含两个部分:数据域(存储数据&#xff…

【MySQL系列】字符集设置

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

02- 模块化编程-001 ADC采样与显示

周末把单片机的开发环境理顺了,开始模块化编程的实践,先从外围模块开始,先从独立的模块,然后构建复杂一些的综合应用,条件所限,以protues的仿真为主。 1、单片机内置ADC采样与显示电路 2、电路原理简介 该电路主要由…

VScode设置系统界面字体

现象: 系统界面字体太大,导致菜单栏字体显示不全,每次使用都要先点然后才能打开终端和帮助 缩小字体应该就可以实现全部都看到的效果 解决步骤 1. “齿轮形状”设置中心---->设置 2.输入zoom 3.用户—>窗口—>修改“Window: Zoom…

C++初阶——类和对象(上)

目录 1、类的定义 1.1 类定义格式 1.2 访问限定符 1.3 类域 2、类的实例化 2.1 实例化的概念 3、this指针 1、类的定义 1.1 类定义格式 • class为定义类的关键字,Stack为类的名字,{}中为类的主体,注意类定义结束时后面分号不能省略。…

小北的字节跳动青训营与LangChain系统安装和快速入门学习(持续更新中~~~)

前言 最近,字节跳动的青训营再次扬帆起航,作为第二次参与其中的小北,深感荣幸能借此机会为那些尚未了解青训营的友友们带来一些详细介绍。青训营不仅是一个技术学习与成长的摇篮,更是一个连接未来与梦想的桥梁~ 小北的青训营 X M…