在看韦东山老师“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自问自答相关推荐

  1. [python]自问自答:python -m参数? (转)

    python -m xxx.py 作用是:把xxx.py文件当做模块启动 但是我一直不明白当做模块启动到底有什么用.python xxx.py和python -m xxx.py有什么区别! 自问自答: ...

  2. JAVA容器-自问自答学HashMap

    前言 这次我和大家一起学习HashMap,HashMap我们在工作中经常会使用,而且面试中也很频繁会问到,因为它里面蕴含着很多知识点,可以很好的考察个人基础.但一个这么重要的东西,我为什么没有在一开始 ...

  3. 分享蔡澜老师的自问自答

    蔡澜老师的个人网站上有个「访问自己」的板块,里面记录了很多蔡澜老师的「自问自答」,问题和回答都很有趣,从中挑选了一部分.喜欢这种洒脱率真的生活态度. 附上网址 http://blog.sina.com ...

  4. Golang 数组的一些自问自答

    基于Go-1.17.一些研究Go数组的自问自答,可以考虑作为面试题 image-20211227100817481 所有代码基于Go-1.17.一些研究Go数组的自问自答,可以考虑作为面试题. 问题: ...

  5. Maven 自问自答

    Maven 自问自答 Maven 自问自答 maven有什么用 POM 是一个什么东西 解读pom Build Lifecycle maven 三条指令运行web项目 maven常用指令 maven结 ...

  6. 干货!JAVA容器-自问自答学HashMap

    前言 这次我和大家一起学习HashMap,HashMap我们在工作中经常会使用,而且面试中也很频繁会问到,因为它里面蕴含着很多知识点,可以很好的考察个人基础.但一个这么重要的东西,我为什么没有在一开始 ...

  7. vue 源码自问自答-响应式原理

    vue 源码自问自答-响应式原理 最近看了 Vue 源码和源码分析类的文章,感觉明白了很多,但是仔细想想却说不出个所以然. 所以打算把自己掌握的知识,试着组织成自己的语言表达出来 不打算平铺直叙的写清 ...

  8. 自问自答:在VB中如何实现像C++一样printf的功能

    问: 每个整型都转换成5位的字符串,不足的在前面补0.比如:1转换成"00001",10转换成"00010".怎么实现? 答: format(1,"0 ...

  9. Java 疑问自问自答

    1.为什么把关闭资源放finally中? 答:保证即使前面发生一些异常情况也会最终正常执行finally中的代码,用于保证资源释放. 来源:https://bbs.csdn.net/topics/36 ...

最新文章

  1. Cmake,source_group
  2. 新建angular-cli项目
  3. Kudu安装(官网推荐的步骤)(installing build Kudu from source)
  4. nacos如何做配置中心?自带自动刷新配置功能?这一篇文章让你明明白白!
  5. hdu2457:DNA repair
  6. HTML表格和列表笔记练习!DOCTYPE html html lang=en head meta charset=UTF-8 title关于表格的一些练...
  7. 工作流牛人 Jan Mendling
  8. centos7.4 kubeadm安装Kubernetes 1.14.1 集群
  9. html中body呈现属性,HTML body 标签
  10. 蛮牛精选七款Unity插件
  11. D4 数据分析实例:分析movielens电影数据+pandas核心数据结构
  12. A1,A2,A3,A4,A5,A6,A7,A8纸张大小图解
  13. Android的SharedPreferences和SQLite
  14. java支付宝app支付代码
  15. GitChat·Python | 零基础小白如何入门 Python 编程
  16. Python开发【十一章】:RabbitMQ队列
  17. 看看一位清华计算机专业的学生怎么看LINUX与WINDOWS的
  18. C 语言 某人在国外留学,不熟悉当地的天气预报中的华氏温度值,请编程按每隔10°输出0°到300°之间的华氏温度的对照表,方便他对照查找
  19. WiFi基本概念(十三)射频(一)(EVM)
  20. mysql 类型_MySQL 数据类型有哪些?

热门文章

  1. 江苏赛区|2021年数学建模国赛江苏赛区获奖名单
  2. 【线上讲座】如果转型为AI人工智能?
  3. 云和恩墨多个标杆案例入选《2021年信创产业发展报告》,将持续推动数据库产业进步...
  4. 微信小程序微信授权登录,使用getPhoneNumber()部分手机无法获取动态令牌code(Taro)
  5. 输入某辆小轿车三次的 耗油量(升)和行驶里程(公里),计算平均油耗(升/百公里)。
  6. 触控笔有必要买吗?苹果平板触控笔排行榜
  7. 全球响应,维谛技术(Vertiv)助力EPC企业出海“加速度”
  8. floyd-warshall算法浅理解
  9. 大陆首款车量AI芯片 开启国产替代新纪元
  10. 爬虫实例:唐诗宋词爬虫