【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_FETCH是tcpip_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;}
}
相关文章:
【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函数调用。…...
求猫用宠物空气净化器推荐,有没有吸毛强、噪音小的产品
自从成为铲屎官,真的和当妈没有区别了。家里的毛孩子成天掉毛,我就跟在它屁股后面默默收拾,一举一动都要时刻关注。最近换季,家里还多了不少浮毛,全飘在空气中,阳光照射下非常明显。 我妈看到后各种吐槽&a…...
pycharm中python控制台出现CommandNotFoundError: No command ‘conda run‘.
1、错误现象 pycharm中打开python控制台出现CommandNotFoundError: No command conda run.的错误。 2、背景 conda是4.6版本,在Anaconda Prompt可以正常运行虚拟环境。 3、解决方法 更新conda版本,基本命令,会自动更新到最新版本。 con…...
架构师备考-架构基本概念
目录 基本概念 架构设计与生命周期 需求分析 设计阶段 实现阶段 构件组装阶段 部署阶段 后开发阶段 动态软件体系结构 体系结构恢复与重建 软件架构设计的重要性 基本概念 软件架构(Software Architecture)设计主要关注软件构件的结构、属性和…...
信奥赛C++知识点
参加信息学奥林匹克竞赛(信奥赛)所需学习的C知识点,以下是一个详细的知识点列表: 一、C语言基础 程序结构 头文件:包含必要的头文件,如<iostream>用于输入输出。 命名空间:使用using …...
高并发内存池扩展 -- 处理大内存,优化释放时需要传入空间大小,加入定长内存池,存放映射关系的容器的锁机制,优化性能(基数树,优势,优化前后对比)
目录 高并发内存池 扩展 测试 大内存 介绍 代码 优化释放时需要传入空间大小 介绍 赋值 代码 加入定长内存池 引入 介绍 代码 存放映射关系的容器 锁机制 写入 读取 优化性能 引入 基数树 单级基数树 两级基数树 三级基数树 优势 引入代码 优化前后…...
Composite(组合)
1)意图 将对象组合成树型结构以表示“部分-整体”的层次结构。Composite 使得用户对单个对象和组合对象的使用具有一致性。 2)结构 组合模式的结构如图 7-33 所示。 其中: Component 为组合中的对象声明接口;在适当情况下实现所有类共有接口的默认行为;声明一个接口用于访问…...
有Bootloader,为什么还要BROM?
有Bootloader,为什么还要BROM? 不少硬件平台都提供类似Boot ROM或者PBL(高通平台)固化的一段程序,出厂后用户一定不能修改。BROM可以引导Bootloader程序。大家知道,每个可启动的平台都会在存储设备,例如EMMC/NAND/UFS保存Bootloa…...
【MATLAB代码】CV和CA模型组成的IMM(滤波方式为UKF),可复制粘贴源代码
该MATLAB代码实现了基于无迹卡尔曼滤波器(UKF)的交互式多模型(IMM)滤波算法,旨在跟踪目标在不同运动模式(匀速直线运动CV和匀速圆周运动CT)的位置和速度。订阅专栏后,直接复制粘贴代码到MATLAB空脚本中,即可运行 文章目录 运行结果源代码程序介绍1. 初始化和参数设定2…...
【网络】传输层协议TCP(下)
目录 四次挥手状态变化 流量控制 PSH标记位 URG标记位 滑动窗口 快重传 拥塞控制 延迟应答 mtu TCP异常情况 四次挥手状态变化 之前我们讲了四次挥手的具体过程以及为什么要进行四次挥手,下面是四次挥手的状态变化 那么我们下面可以来验证一下CLOSE_WAIT这…...
服务器数据恢复—EVA存储故障导致上层应用不可用的数据恢复案例
服务器存储数据恢复环境: 一台EVA某型号控制器EVA扩展柜FC磁盘。 服务器存储故障&检测: 磁盘故障导致该EVA存储中LUN不可用,导致上层应用无法正常使用。 服务器存储数据恢复过程: 1、将所有磁盘做好标记后从扩展柜中取出。硬…...
支持向量机相关证明 解的稀疏性
主要涉及拉格朗日乘子法,对偶问题求解...
静态ip和动态ip适合什么场景
静态住宅ip由于他的ip位置保持不变的,更加适合: 1、账号管理。 使用静态住宅来注册和管理社交媒体账号,例如facebook、领英等,包括电商类的账号也是可以的,例如亚马逊等 2、网站测试 很多网站会检测使用者是否为机器…...
Istio Gateway发布服务
1. Istio Gateway发布服务 在集群中部署一个 tomcat 应用程序。然后将部署一个 Gateway 资源和一个与 Gateway 绑定的 VirtualService,以便在外部 IP 地址上公开该应用程序。 1.1 部署 Gateway 资源 vim ingressgateway.yaml --- apiVersion: networking.istio.…...
前端vue3若依框架pnpm run dev启动报错
今天前端vue3若依框架pnpm run dev启动报错信息: > ruoyi3.8.8 dev D:\AYunShe\2024-11-6【无锡出门证】\wuxi-exit-permit-web > vite error when starting dev server: Error: listen EACCES: permission denied 0.0.0.0:80 at Server.setupListenHand…...
python线条爱心
效果图 代码 import math from turtle import * def hearta(k):return 15*math.sin(k)**3 def heartb(k):return 12*math.cos(k)-5*\math.cos(2*k)-2*\math.cos(3*k)-\math.cos(4*k) speed(1000) bgcolor("black") for i in range(6000):goto(hearta(i)*20,heartb(…...
GPU的内存是什么?
GPU(图形处理器)的内存是指专门用于 GPU 存储数据的内存,也被称为显存。 一、显存的作用: 1、存储图像数据 当计算机要显示图像时,显存会存储屏幕上每个像素点的颜色、亮度等信息。例如,对于一个分辨率为 1…...
Linux - 弯路系列1:xshell能够连接上linux,但xftp连不上(子账号可以连接,但不能上传数据)
问题如题目阐述。 注:所有操作在root账户下操作。 解决办法: 1、确认连接设置 服务器地址和端口:确保在 Xftp 中输入的服务器地址和端口号与 Xshell 使用的相同。默认情况下,SFTP 使用端口 22。 用户凭证:检查用户名…...
数组逆序重存放
题目描述 将一个数组中的值按逆序重新存放。例如,原来的顺序为8,6,5,4,1。要求改为1,4,5,6,8。 输入 输入为两行:第一行数组中元素的个数n(1<n<100),第二行是n个整数,每两个整数之间用空格分隔。 输出 输出…...
归并排序:高效算法的深度解析
一、归并排序概述 归并排序是一种基于分治思想的经典排序算法。它的核心操作分为三个主要步骤:分割、排序和合并。 首先是分割步骤,将待排序的数组不断地分成更小的子数组,直到每个子数组中只有一个元素。例如,对于一个包含多个…...
接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...
【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...
基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...
Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...
Golang——9、反射和文件操作
反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一:使用Read()读取文件2.3、方式二:bufio读取文件2.4、方式三:os.ReadFile读取2.5、写…...
Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)
引言 工欲善其事,必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后,我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集,就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...
