RT_Thread自问自答
在看韦东山老师“RT-Thread内部机制”的视频,挺有意思的,有些概念的理解还是要深究一下,不然可能就是“我知道,这不就是那个....那个....那个”,哪个嘛,并不是因为嘴笨说不好,是因为确实没想过真说不清楚,下面是一些自问自答。
1、线程是什么?
我的理解,线程就是指挥函数的运行。【一个线程对应一个入口函数】
- 控制ta在何时运行,可以运行多久;
- 暂停运行去切换别的线程时,保存当前的环境,以便下次继续运行;
2、线程切换时要保存的环境是什么?
首先函数是存在FLASH中的,不需要保存;
其次就是函数用到的变量,包括全局变量和局部变量,全局变量是大家都能用的不需要线程保存,局部变量是存放在各自的线程栈中的;
如果不知道线程临走时要带什么,可以想想当继续运行时要干什么?
要知道从哪一条(汇编)语句开始执行,执行中又会用到哪些CPU中寄存器的值,这就是我们要保存的。
P.S. CPU中寄存器,包括参数寄存器,状态寄存器,所谓“执行到哪”的程序计数器PC等。
3、创建线程时做了什么?
用rt_thread_init或rt_thread_create创建线程,我们传了一些参数:入口函数、函数参数、线程栈、优先级、时间片,然后线程就创建好了。
emm...鸭子和啤酒放进锅里,是不会变成啤酒鸭的。
以rt_thread_create为例:
- 申请线程控制块的内存;申请线程栈的内存;
- 初始化线程链表;
- 初始化线程控制块的各种参数:函数入口、函数参数、栈的起始地址、栈大小、线程掩码、初始时间片、剩余时间片、线程错误代码、线程状态、线程清除函数、用户数据;
- 初始化线程栈;
- 初始化线程定时器;
- 初始化线程钩子函数;
3.1、初始化线程栈
先将申请到的线程栈的内存,全部初始化为'#';
rt_memset(thread->stack_addr, '#', thread->stack_size);
然后调用rt_hw_stack_init函数初始化栈;
thread->sp = (void *)rt_hw_stack_init(thread->entry, thread->parameter,(rt_uint8_t *)((char *)thread->stack_addr + thread->stack_size - sizeof(rt_ubase_t)),(void *)rt_thread_exit);
第三个参数stack_addr+stack_size-8,stack_addr是申请内存时分配出的地址,指示栈底的低地址,加stack_size就到了栈顶,然后减8。进入函数里又加4,以8位倍数向下对齐,反正一通操作就是找到对齐后栈顶的地址。
函数里有一个结构体stack_frame,里面是保存CPU寄存器的值的,定义如下:
struct exception_stack_frame
{rt_uint32_t r0;rt_uint32_t r1;rt_uint32_t r2;rt_uint32_t r3;rt_uint32_t r12;rt_uint32_t lr;rt_uint32_t pc;rt_uint32_t psr;
};struct stack_frame
{
#if USE_FPUrt_uint32_t flag;
#endif /* USE_FPU *//* r4 ~ r11 register */rt_uint32_t r4;rt_uint32_t r5;rt_uint32_t r6;rt_uint32_t r7;rt_uint32_t r8;rt_uint32_t r9;rt_uint32_t r10;rt_uint32_t r11;struct exception_stack_frame exception_stack_frame;
};
3.2、初始化线程钩子函数
- 初始化线程的钩子函数,调用的是代码1;
- RT_OBJECT_HOOK_CALL是个宏,宏定义是代码2;
- 假设func != NULL,将宏展开是代码3;
- rt_thread_inited_hook是个函数指针,定义是代码4;
- 这个函数指针rt_thread_inited_hook在函数rt_thread_inited_sethook中被赋值,如下代码5;
- 最后,rt_thread_inited_sethook是给用户使用的,设置的钩子函数会在线程初始化的时候调用;
1、RT_OBJECT_HOOK_CALL(rt_thread_inited_hook, (thread));
2、#define RT_OBJECT_HOOK_CALL(func, argv) \do { if ((func) != RT_NULL) func argv; } while (0)
3、rt_thread_inited_hook(thread);
4、static void (*rt_thread_inited_hook) (rt_thread_t thread);
5、 void rt_thread_inited_sethook(void (*hook)(rt_thread_t thread)){rt_thread_inited_hook = hook;}
4、创建完线程后,线程启动rt_thread_startup做了什么?
简而言之就是线程从初始态进入了就绪态,线程插入了就绪队列,然后rt_schedule内核调度,具体如下:
5、SysTick_Handler里有哪些操作?
SysTick_Handler里调用了rt_tick_increase,rt_tick_increase主要做了两件事:
- 检查当前运行的线程,看看时间片有没有用完,用完了执行rt_schedule调度切换线程;
- 检查定时器链表,看有没有超时溢出的,执行定时器回调函数;
RT_Thread自问自答相关推荐
- [python]自问自答:python -m参数? (转)
python -m xxx.py 作用是:把xxx.py文件当做模块启动 但是我一直不明白当做模块启动到底有什么用.python xxx.py和python -m xxx.py有什么区别! 自问自答: ...
- JAVA容器-自问自答学HashMap
前言 这次我和大家一起学习HashMap,HashMap我们在工作中经常会使用,而且面试中也很频繁会问到,因为它里面蕴含着很多知识点,可以很好的考察个人基础.但一个这么重要的东西,我为什么没有在一开始 ...
- 分享蔡澜老师的自问自答
蔡澜老师的个人网站上有个「访问自己」的板块,里面记录了很多蔡澜老师的「自问自答」,问题和回答都很有趣,从中挑选了一部分.喜欢这种洒脱率真的生活态度. 附上网址 http://blog.sina.com ...
- Golang 数组的一些自问自答
基于Go-1.17.一些研究Go数组的自问自答,可以考虑作为面试题 image-20211227100817481 所有代码基于Go-1.17.一些研究Go数组的自问自答,可以考虑作为面试题. 问题: ...
- Maven 自问自答
Maven 自问自答 Maven 自问自答 maven有什么用 POM 是一个什么东西 解读pom Build Lifecycle maven 三条指令运行web项目 maven常用指令 maven结 ...
- 干货!JAVA容器-自问自答学HashMap
前言 这次我和大家一起学习HashMap,HashMap我们在工作中经常会使用,而且面试中也很频繁会问到,因为它里面蕴含着很多知识点,可以很好的考察个人基础.但一个这么重要的东西,我为什么没有在一开始 ...
- vue 源码自问自答-响应式原理
vue 源码自问自答-响应式原理 最近看了 Vue 源码和源码分析类的文章,感觉明白了很多,但是仔细想想却说不出个所以然. 所以打算把自己掌握的知识,试着组织成自己的语言表达出来 不打算平铺直叙的写清 ...
- 自问自答:在VB中如何实现像C++一样printf的功能
问: 每个整型都转换成5位的字符串,不足的在前面补0.比如:1转换成"00001",10转换成"00010".怎么实现? 答: format(1,"0 ...
- Java 疑问自问自答
1.为什么把关闭资源放finally中? 答:保证即使前面发生一些异常情况也会最终正常执行finally中的代码,用于保证资源释放. 来源:https://bbs.csdn.net/topics/36 ...
最新文章
- Cmake,source_group
- 新建angular-cli项目
- Kudu安装(官网推荐的步骤)(installing build Kudu from source)
- nacos如何做配置中心?自带自动刷新配置功能?这一篇文章让你明明白白!
- hdu2457:DNA repair
- HTML表格和列表笔记练习!DOCTYPE html html lang=en head meta charset=UTF-8 title关于表格的一些练...
- 工作流牛人 Jan Mendling
- centos7.4 kubeadm安装Kubernetes 1.14.1 集群
- html中body呈现属性,HTML body 标签
- 蛮牛精选七款Unity插件
- D4 数据分析实例:分析movielens电影数据+pandas核心数据结构
- A1,A2,A3,A4,A5,A6,A7,A8纸张大小图解
- Android的SharedPreferences和SQLite
- java支付宝app支付代码
- GitChat·Python | 零基础小白如何入门 Python 编程
- Python开发【十一章】:RabbitMQ队列
- 看看一位清华计算机专业的学生怎么看LINUX与WINDOWS的
- C 语言 某人在国外留学,不熟悉当地的天气预报中的华氏温度值,请编程按每隔10°输出0°到300°之间的华氏温度的对照表,方便他对照查找
- WiFi基本概念(十三)射频(一)(EVM)
- mysql 类型_MySQL 数据类型有哪些?
热门文章
- 江苏赛区|2021年数学建模国赛江苏赛区获奖名单
- 【线上讲座】如果转型为AI人工智能?
- 云和恩墨多个标杆案例入选《2021年信创产业发展报告》,将持续推动数据库产业进步...
- 微信小程序微信授权登录,使用getPhoneNumber()部分手机无法获取动态令牌code(Taro)
- 输入某辆小轿车三次的 耗油量(升)和行驶里程(公里),计算平均油耗(升/百公里)。
- 触控笔有必要买吗?苹果平板触控笔排行榜
- 全球响应,维谛技术(Vertiv)助力EPC企业出海“加速度”
- floyd-warshall算法浅理解
- 大陆首款车量AI芯片 开启国产替代新纪元
- 爬虫实例:唐诗宋词爬虫