RT-thread 内核深度剖析
文章平均质量分 63
通过学习RT-thread 内核,不断提高自己的编程能力。
机器灵魂注入师
一名在不断精进的嵌入式软件开发工程师,很庆幸能从事自己喜欢的工作。
愿你要永远抱有一颗好奇之心。
愿你出走半生,归来仍是少年。
展开
-
【RT-Thread内核详解系列】基于优先级的全抢占式调度算法的实现
The unexamined life is not worth living.未经审视的人生是不值得过的。– 苏格拉底一、原理概述RT-Thread 是一款嵌入式实时操作系统(RTOS),同时也是一款优秀的物联网操作系统,相对于裸机的轮询调度算法,它使用的线程(任务)调度算法是基于优先级的全抢占式多线程调度算法,该算法大大增强了系统的实时响应,大大扩展了系统的应用场景。该调度算法在每次调度任务时,总会选择优先级最高的就绪任务执行,保证优先级高的任务得到最及时的响应。下面,我们来详细讲解该调.原创 2022-01-09 00:29:03 · 2993 阅读 · 0 评论 -
验证:为RT-Thread内核增加一种新的查找字节最低非0位的算法
人生最苦痛的是梦醒了无路可走。做梦的人是幸福的;倘没有看出可走的路,最要紧的是不要去惊醒他。– 鲁迅 《娜拉走后怎么样》概述该篇文章来源于:《验证:为RT-Thread内核增加一种新的查找字节最低非0位的算法》在 RT-Thread 的内核代码中,有一种查找最低非零位的算法,主要采用查表的方法,通过时间换空间的方式,为系统寻找线程的最高优先级提供了一种高效的方法。通过查看内核代码里面的 kservice.c 文件,我们可以看到如下源代码:const rt_uint8_t __lowest_.原创 2021-11-07 17:47:06 · 288 阅读 · 0 评论 -
RT-Thread 内核默认的“查找字节最低非0位的算法”的汇编分析
RT-Thread 默认的查找字节最低非0位的算法如下:const rt_uint8_t __lowest_bit_bitmap[] ={ /* 00 */ 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 10 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 20 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,原创 2021-10-28 23:59:49 · 218 阅读 · 0 评论 -
以rtthread内核代码为例,内联函数关键字 inline 前为啥需要添加 static 的关键字?
“我努力奔跑,只为追上曾经被寄予厚望的自己。”金州勇士队队员 - 肖恩·利文斯顿本文以 RT-Thread 操作系统为例:我们可以在 RT-Thread 的内核代码的 kservice.c 中有关于 inline 的宏定义(省略中间无关的代码):#ifdef __CC_ARM /* ARM Compiler */ #define rt_inline static __inline#elif define.原创 2021-09-29 00:31:05 · 660 阅读 · 0 评论 -
RT-Thread 的自动初始化机制
金鳞岂是池中物,一遇风云便化龙。 九霄龙吟惊天变,风云际会浅水游。出处《风云》,泥菩萨给雄霸算卦的批文。一、前言介绍RT-Thread 的自动初始化机制使用了自定义 RTI 符号段,将需要在启动时进行初始化的函数指针放到了该段中,形成一张初始化函数表,在系统启动过程中会遍历该表,并调用表中的函数,达到自动初始化的目的。初始化函数主动通过这些宏接口进行申明,如 INIT_BOARD_EXPORT(rt_hw_usart_init),链接器会自动收集所有被申明的初始化函数,放到 RTI 符号段中,该.原创 2021-09-27 22:46:22 · 1475 阅读 · 0 评论 -
RT-Thread Finsh输出版本信息时,如何得到编译时的时间?
“一是禾下乘凉梦,梦想试验田里的超级杂稻长得有高粱那么高、稻穗有扫把那么长、谷粒有花生米那么大,我坐在禾下悠闲地纳凉;另一个是杂交稻覆盖全球梦。”---- 杂交水稻之父、共和国勋章获得者袁隆平谈及自己的两个梦想在 RT-Thread 启动时,串口会打印如下提示信息:别的内容都是固定的,就是 build 后的 Jun 13 2021,记录的是编译时的时间,这个时间是如何得到的呢?查看源码:/** * This function will show the version of rt-thre.原创 2021-06-13 16:06:26 · 440 阅读 · 0 评论 -
关于 RT-Thread 内核调度算法中 __rt_ffs函数为什么要检测 value值是否为0的疑问
产生一个好的想法,最佳方法就是先产生许许多多的想法。The best way to have a good idea is to have a lot of ideas.– 鲍林(Linus Pauling),诺贝尔化学奖得主疑问:RT-Thread 的内核调度算法中使用的查找当前最高优先级的线程的代码实现是这样的:int __rt_ffs(int value){ if (value == 0) return 0; if (value & 0xff) .原创 2021-06-13 15:17:44 · 503 阅读 · 0 评论 -
RT-Thread 的线程调度器是如何查找到优先级最高的任务的?
一命二运三风水,四积阴德五读书,六名七相八敬神,九交贵人十养生。---- 民间出品冯唐解读成功十要素:一命二运三风水,四积阴德五读书六名七相八敬神 打开 RT-Thread 内核中的 scheduler.c,我们可以看到如下的代码:rt_list_t rt_thread_priority_table[RT_THREAD_PRIORITY_MAX];#if RT_THREAD_PRIORITY_MAX > 32/* Maximum priority level, 256 */rt_u.原创 2021-06-12 14:06:00 · 880 阅读 · 0 评论 -
关于rt_hw_stack_init()函数的参数选择(char *)thread->stack_addr + thread->stack_size - sizeof(rt_ubase_t)的理解
RT-thread的线程初始化函数内部有一个线程栈初始化函数,如下图所示其由宏定义ARCH_CPU_STACK_GROWS_UPWARD(栈的生长方式)来决定其传入的参数。看#else部分,函数的第二个参数有- sizeof(rt_ubase_t)的操作。再来看rt_hw_stack_init()的实现,红箭头标识的地方有+ sizeof(rt_uint32_t);的操作,对于32位的芯片来说,这个一加一减,其实是相同的值。那么问题来了,为什么传入的时候,进行了 -4的操作,而函数的内部实现里原创 2021-03-17 20:37:19 · 925 阅读 · 6 评论 -
RT-thread -- 线程递归持有信号量会发生主动挂起(最终形成死锁)的原因解释
RT-thread 官方文档中有这样一句话:在信号量中,因为已经不存在实例,线程递归持有会发生主动挂起(最终形成死锁)出自《rtthread-programming-manual.pdf》P73这句话的意思是如果一个线程不断获取信号量(没有释放的过程),当信号量的值为0后,线程就会停下,之后就无法运行了,相当于被锁住了。当然这里有个前提,别的线程无法释放这个信号量。还是举个例子:假设信号量初始值为1,也就是二值信号量先说正常的使用,我们可以用来保护临界区数据void thread1_entr原创 2020-12-16 23:41:01 · 1173 阅读 · 0 评论 -
RT-Thread 的一些疑问和理解
2020-9-17眼看他起朱楼,眼看他宴宾客,眼看他楼塌了。– 孔尚任《桃花扇》线程控制块是线程切换的核心,通过线程创建 rt_thread_create/线程初始化rt_thread_init函数将线程栈与线程入口函数绑定在线程控制块。线程切换主要靠的是线程栈,切换时将当时线程运行的数据保存在线程栈,线程恢复时将线程栈的内容再恢复到线程栈中。线程栈的内容如下,值得注意的是,运行过程中,R15存储的不一定是入口地址(由于入口函数运行到一半,此时切换的话,线程栈对应到pc寄存器的位置保存的是此时程.原创 2020-09-17 20:47:48 · 831 阅读 · 0 评论 -
RT-Thread使用笔记 -- 临界区的保护
(一)、临界区的保护简单来说,临界区的设立就是为了保护在临界区内的代码不会被外界打断,顺序完整的执行下去,这样做的目的是保证一些共享的资源在执行临界区代码的中途被临界区外的代码改变,造成数据紊乱,功能错误。RT-Thread设置临界区的两种方式(主要指的是API的调用)及其区别 :(1)调用这组API, 实现的是禁止任务调度,不会关闭别的中断。如非必须,尽量使用这组,对系统别的部分影响相对较...原创 2020-03-09 20:16:28 · 2535 阅读 · 1 评论