LwIP源码分析(2):tcpip_init和tcpip_thread函数分析
- 环境:FreeRTOS & LwIP 2.2.0
- 文章中的所有参数检测的断言代码都删除以使代码更清晰
LwIP通过调用tcpip_init
来初始化TCPIP协议栈,函数如下所示,函数中代码的含义见注释:
static tcpip_init_done_fn tcpip_init_done;
static void *tcpip_init_done_arg;
static sys_mbox_t tcpip_mbox;
sys_mutex_t lock_tcpip_core;void tcpip_init(tcpip_init_done_fn initfunc, void *arg)
{/* 初始化LwIP */lwip_init();/* 初始化完毕后调用的回调函数,可传NULL,在tcpip_thread开头调用 */tcpip_init_done = initfunc;tcpip_init_done_arg = arg;/* 创建message box,实际上是FreeRTOS的Queue* 每个项目大小为一个指针的大小(4B),队列长度为TCPIP_MBOX_SIZE */if (sys_mbox_new(&tcpip_mbox, TCPIP_MBOX_SIZE) != ERR_OK) {LWIP_ASSERT("failed to create tcpip_thread mbox", 0);}#if LWIP_TCPIP_CORE_LOCKING/* 创建互斥锁:用户可以通过这个锁在代码中实现LwIP的一些操作,而不需要在tcpip_thread的callback中实现 */if (sys_mutex_new(&lock_tcpip_core) != ERR_OK) {LWIP_ASSERT("failed to create lock_tcpip_core", 0);}#endif /* LWIP_TCPIP_CORE_LOCKING *//* 创建FreeRTOS任务tcpip_thread */sys_thread_new(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO);
}
其中lwip_init
函数内容如下(各个初始化需要打开相应的宏定义,这里略去#ifdef...#endif
的宏定义以方便阅读代码):
void lwip_init(void)
{/* 统计模块初始化,这里只是初始化lwip_stats.mem.name为MEM */stats_init();/* 带操作系统时的初始化:函数中暂时没有内容 */sys_init();/* 初始化内存堆的起始地址、结束地址以及空闲列表 */mem_init();/* 初始化LwIP内存池 */memp_init();/* 初始化pbuf:函数中暂时没有内容 */pbuf_init();/* 初始化netif:主要是环回的ip,网关,子网掩码以及netif的添加和配置 */netif_init();/* 兼容老版本:函数中暂时没有内容 */ip_init();/* 兼容老版本:函数中暂时没有内容 */etharp_init();/* 兼容老版本:函数中暂时没有内容 */raw_init();/* 初始化UDP端口号(随机分配),范围:0xc000~0xffff */udp_init();/* 初始化TCP端口号(随机分配),范围:0xc000~0xffff */tcp_init();/* 初始化组播IP */igmp_init();/* 初始化DNS解析:设置UDP PCB并配置默认服务器 */dns_init();/* 初始化PPP:根据配置分配相关的结构体内存和初始化魔术字(PPP连接需要用到) */ppp_init();/* 初始化软件定时器 */sys_timeouts_init();
}
最后,可以看到tcpip_init
最终调用sys_thread_new
创建了一个tcpip_thread
任务,看看它做了什么:
static void tcpip_thread(void *arg)
{struct tcpip_msg *msg;/* 上锁 */LOCK_TCPIP_CORE();/* 调用前面设置的回调函数 */if (tcpip_init_done != NULL) {tcpip_init_done(tcpip_init_done_arg);}while (1) {/* 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_MBOX_FETCH
来等待消息,这个函数中还有定时器的检查,具体解释参考:LwIP源码分析(1):软件定时器。
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();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;}
}
对于这边的互斥锁,tcpip_thread
一上来就调用LOCK_TCPIP_CORE
上锁,在TCPIP_MBOX_FETCH
中等待消息队列阻塞时释放这个锁,等待完这个队列,无论有没有消息到来,sys_arch_mbox_fetch
返回后就立即上锁,因为在此期间tcpip_thread
已经阻塞死等,此时用户可以调用部分LwIP内核函数。
对于消息处理函数tcpip_thread_handle_msg(msg)
相关的结构体和实现需要在了解TCP/IP原理之后进行分析,这样知道在哪里在何时会往这个mbox发送消息,我们才能知道每个消息的定义,不同的消息需要执行什么操作。后续循序渐进地分析完LwIP相关代码后,我会写一个博客来分析,这里暂不讨论。
LwIP源码分析(2):tcpip_init和tcpip_thread函数分析相关推荐
- LWIP源码分析——ip4.c
LWIP源码分析--ip4.c ipv4是IP栈中重要的一部分,实现功能使用了上千行代码,分析起来可能会稍显复杂,这部分采用的分析的思路是,重点思想总结部分放在前面,剩下的结合代码穿插分析 1.ipv ...
- 【Android 10 源码】healthd 模块 HAL 2.0 分析
Android 9 引入了从 health@1.0 HAL 升级的主要版本 android.hardware.health HAL 2.0.这一新 HAL 具有以下优势: 框架代码和供应商代码之间的区 ...
- vue+django 微博舆情系统源码、深度学习+舆情扩散消失分析、舆情紧急等级、属地分析、按话题、情感预测、话题评论获取、提取观点、正面负面舆情、按区域检测舆情
项目背景 315又马上要到了,现在有开始对食品安全话题的关注地提升了,因此,本文系统对微博的食品安全话题进行分析,有如下的功能 1.展示当前食品安全事件相关的热点信息以及提供根据食品关键词,食品安全类 ...
- Postgresql源码(82)SPI模块拆解分析一:执行简单SQL获取结果
相关 <Postgresql源码(76)执行器专用元组格式TupleTableSlot> <Postgresql源码(82)SPI模块拆解分析一:执行简单SQL获取结果> &l ...
- 抖音seo优化源码搭建/搜索排名系统,技术理论分析搭建中。
抖音seo系统源码SaaS+源码私有化部署搭建,抖音seo源码,抖音seo系统源码,抖音seo系统搭建部署,抖音已经成为了当今最为流行的短视频平台之一,拥有着庞大的用户群体和海量的视频资源.对于一些商 ...
- [附源码]计算机毕业设计JAVA学生考试成绩分析系统
[附源码]计算机毕业设计JAVA学生考试成绩分析系统 项目运行 环境配置: Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(In ...
- Postgresql源码(69)常规锁细节分析
相关: <Postgresql源码(40)Latch的原理分析和应用场景> <Postgresql源码(67)LWLock锁的内存结构与初始化> <Postgresql源 ...
- 4、Eureka 源码解析 之 Eureka Client 启动原理分析
在前面的一篇文章 3.Eureka 源码解析 之 Eureka Server 启动原理分析当中我们分析了一下 Eureka Server 的启动.在集群环境下 Eureka Server 相互之前需要 ...
- 抖音SEO优化源码,搜索排名系统,技术理论分析,抖音矩阵,抖音seo系统。
前言:抖音SEO优化源码,搜索排名系统,技术理论分析,抖音矩阵,抖音seo系统.抖音seo矩阵系统底层框架上支持了ai视频混剪,视频产出,视频AI制作,多账号多平台矩阵,视频一键内部分发,站内实现搜索 ...
最新文章
- NOIP2012-摆花
- 学好人工智能,其实不难,从以下几点开始
- ABP 重写主键ID
- Unity Time的使用
- SAP Spartacus B2B table的配置信息从哪里来?
- 学习笔记~~~~~python基础
- 说说C#的async和await
- Luogu P2664 树上游戏 dfs+树上统计
- creo扫描选择多条链作为轨迹_Proe/Creo曲面造型·蓝牙耳机纹理曲面纹理
- 深度学习怎么入门?零基础快速入门深度学习
- 在线图片尺寸怎么修改?图片在线修改尺寸大小方法
- mysql获取今天的最后一秒_Oracle取得当天0时0分0秒和23时59分59秒
- Redis生成自增流水号,每日清零
- 百万钱包借款时填资料一直显示服务器异常,百万钱包有连续放款失败,然后突然推过的吗?我已经失败四五...
- threejs粒子效果
- 《Flask Web开发:基于Python的Web应用开发实战》笔记(原创)
- vue登录页面实现记住密码的操作
- 班得瑞轻音乐全集[下载]
- hbuilder怎么做登录界面_HBuilder如何安装和使用?(教程)
- linux计划任务如何关闭程序,Linux进程控制和计划任务管理
热门文章
- Jx_Python基础库入门_2: 基本数据类型
- 百度统计搜索词是广告怎么办?建议设置过滤规则排除
- 【Bug】python requests发起请求,报“Max retries exceeded with url”
- Max retries exceeded with url问题解决
- testng执行参数_TestNG参数化测试
- 超融合一体流式引擎,打造分布式数据库新纪元
- 让视频丝滑流畅——N/A通用补帧傻瓜解决方案
- 拉黑技巧/幻隐网络科技
- PCB绘制与制作的总结
- 在SNAP中用sentinel-1数据制作DEM