0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

构建RTOS Kernel指南 (下)

恩智浦MCU加油站 来源:未知 2023-08-03 08:50 次阅读
单单具有任务切换功能自然不能称之为RTOS Kernel,一个任务往往具有多个重要的属性,优先级就是其中之一。一个任务的优先级决定了它的“尊贵”程度,越尊贵的任务越有优先占用CPU运行的权力。

1优先级查找

位图是指一组连续的标志位,是一种常见的优先级框架的实现方式每个比特位通常用来对应一个优先级,越低位的优先级越高,其状态标识该优先级是否有就绪状态的任务。下图32位为例,存在优先级为1、7、9、16……24、25、31的就绪态任务。每个优先级存在对应的任务链表,同一个优先级中采用“先就绪先执行”的原则。wKgaomToOvSAGFZOAABhpRbvchw921.png 图1 位图

那么,CPU的任务从“寻找优先级最高的任务”变成了“寻找位图中最低位的1”。如果按照上图中依次按位查找,速度是较慢的,系统的实时性可能会有一定程度的影响,下面介绍一种较为巧妙的方法——分组查表法。wKgaomToOvSAH72PAABeb4zoeNg734.png                           图2 分组查表法

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,
    /* 30 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* 40 */ 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* 50 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* 60 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* 70 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* 80 */ 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* 90 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* A0 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* B0 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* C0 */ 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* D0 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* E0 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* F0 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
};


int __rt_ffs(int value)
{
    if (value == 0) return 0;


    if (value & 0xff)
        return __lowest_bit_bitmap[value & 0xff] + 1;


    if (value & 0xff00)
        return __lowest_bit_bitmap[(value & 0xff00) >> 8] + 9;


    if (value & 0xff0000)
        return __lowest_bit_bitmap[(value & 0xff0000) >> 16] + 17;


    return __lowest_bit_bitmap[(value & 0xff000000) >> 24] + 25;

这种方法将32位共分成4组,每组8位,那么每组的8位二进制数0x00~0xFF对应数组bitmap的序号0-255,数组中的值的含义为其对应8位二进制数最低位“1”的序号。那么通过这样巧妙的分组查表方式,通过至多四次查找,便可得到位图的最低位“1”的位置。除此之外,还有更为巧妙的利用汇编指令CLZ和RBIT组合实现这个目的,其中CLZ可以统计出现“1”的最高位位置,RBIT是数据进行按位反转的指令。这样就可以先通过RBIT进行位反转,再通过CLZ获取反转后最高位“1”的位置,即原数据中最低位“1”的位置。

2临界区保护和线程同步

在RTOS中,时常会出现多个线程访问公用资源的情况,即都需要访问公用的程序片段,如若没有对应的处理机制,可能会对系统造成意想不到的混乱。常用的方法有调度器上锁和禁止中断,这两者相互依赖,例如在调度器上锁时需要禁止中断。除此之外,还可以采用互斥机制来进行临界区保护,如信号量和互斥量,这两者也用于线程的同步机制。

wKgaomToOvSAeGPZAAFTZeq5SKc148.png 图3 信号量类比

信号量可以类比停车位,当有空车位的时候,才能开进停车场,对于线程而言,假如某临界资源对应的信号量为0,是不能对其进行操作的。信号量应该有两个重要的属性:信号量值和等待队列,信号量的值表示对应可操作临界资源实例数,假如线程申请信号量是其值为0,那么该线程将被挂起在此信号量的等待队列。

wKgaomToOvWAeOfHAAIRH1bLrTQ225.png

图4 互斥量类比

互斥量的作用类似于二值信号量,它是一种特殊的信号量,只具有“上锁”和“解锁”两种状态,对应的临界资源具有极强的排他性。就像景区的豪华单间卫生间,每个人在使用的时候都不能被打扰。虽然功能类似,但是二值信号量和互斥量还是有区别的,后续会进行相应的介绍。 wKgaomToOvWAbdNTAACq08hq3PU866.png                    图5 事件集工作原理 除了信号量互斥量,还有一种有趣的同步机制-事件集,它通常可以用一个32位二进制数表示,每一位代表了一个事件,也可以说成一种触发条件,而事件集的作用便是可以用“逻辑或”和“逻辑与”自由组合出想要触发的条件,就好像“明天天气好”和“我心情愉悦”都发生,“我出去郊游”才会触发,又像“发表一篇论文”或“发明一项专利”任一发生,都触发“达成硕士毕业标准”。

3优先级反转问题

当隐入互斥量的机制后,读者可以思考一下,这会不会和优先级机制产生冲突?

一个是根据优先级制定的“国家法律”,一个是根据临界资源制定的“地方法律”,当遵守“地方法律“的时候会不会违背“国家法律”?这就是优先级反转问题。

wKgaomToOvWAZM4HAABeowHnLCY646.png                                      图6  优先级反转

如上图,假设我们有三个线程,它们的优先级Thread1 > Thread2 > Thread3,t0之前Thread3获取某资源的互斥量,互斥量值变locked状态,t0时刻Thread2线程就绪,由于优先级Thread2 > Thread3,Thread3让出CPU执行权给Thread2,但没有解开互斥量。到t1时刻,Thread1就绪,Thread2让出CPU,Thread1执行过程申请Thread3所占有的互斥量,由于互斥量为locked状态,在t2时刻Thread1被挂起等待,剩余两个就绪态的线程Thread2优先级高于Thread1,因此继续执行。

至此,我们发现,都处于就绪态的线程,低优先级的Thread2反而能比高优先级的Thread1优先执行,其原因是更低优先级的Thread3占有信号量并被抢占,造成了优先级反转。所以为了让“地方法律”更加适配“国家法律”,常用的做法是优先级继承即可以让Thread3短暂地提升到Thread1的优先级,得以抢占CPU快速执行完将互斥量解锁,从而让Thread1及时获取到互斥量得以执行。除此之外,还存在一些另外的处理方式,如优先级天花板等,有兴趣的读者可以自行查阅相关资料

二值信号量和互斥信号量非常类似,但还是有一些细微的差别。互斥信号量拥有优先级继承机制,而二值信号量没有。互斥量必须是同一个任务申请,同一个任务释放,其他任务释放无效,且同一个任务可以递归申请。然而对于二值信号量,一个任务申请成功后,可以由另一个任务释放,因此二值信号另更适合用于同步(任务与任务或任务与中断的同步),互斥信号量适合用于简单的互斥访问。

4线程间通信

线程间通信主要是通过消息队列和邮箱实现,消息队列一般采用先进先出的原则(FIFO),而邮箱可以理解成队列长度为1的特殊消息队列,但是消息队列中为待传输的数据按值拷贝的副本,所以支持各种类型的数据的传递,而邮箱中传输的通常为指向待交换数据的指针。

5总结

至此,一个RTOS的内核功能基本就实现了,下面对一个RTOS Kernel应具备的功能进行分条总结:

实时性:实时系统对任务的响应时间要求较高。具备严格的按优先级调度任务的机制,并且一般要支持抢占式调度

多任务调度:RTOS需要能够同时管理多个任务,并合理分配CPU时间片给每个任务。设计任务调度算法以确保相同优先级的任务能公平使用CPU,避免优先级反转问题,并提供优先级继承、优先级天花板等机制。

同步和通信:多任务系统中,任务之间需要进行同步和通信。设计合适的同步机制,如信号量、互斥锁、消息队列等,并确保在多个任务之间实现可靠的数据传输和共享。

但是,这些仅仅是内核的基本功能,一个成熟的RTOS还应该具有更多的扩展功能予以支撑。例如内存管理功能、外设驱动的支持、硬件依赖性和可移植性、调试和测试功能等等。罗马非一日而建,希望大家都能脚踏实地,乐于钻研,乐于进步,共勉!

END

更多恩智浦AI-IoT市场和产品信息,邀您同时关注“NXP客栈”微信公众号

wKgaomToOvWAacP0AABCdkRE230894.jpg      

NXP客栈


恩智浦致力于打造安全的连接和基础设施解决方案,为智慧生活保驾护航。

长按二维码,关注我们

恩智浦MCU加油站


这是由恩智浦官方运营的公众号,着重为您推荐恩智浦MCU的产品信息、开发技巧、教程文档、培训课程等内容。

wKgaomToOvWAT-uOAAATNlPH08Y563.jpg  

长按二维码,关注我们


原文标题:构建RTOS Kernel指南 (下)

文章出处:【微信公众号:恩智浦MCU加油站】欢迎添加关注!文章转载请注明出处。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • mcu
    mcu
    +关注

    关注

    146

    文章

    16852

    浏览量

    349798
  • 恩智浦
    +关注

    关注

    14

    文章

    5815

    浏览量

    106229

原文标题:构建RTOS Kernel指南 (下)

文章出处:【微信号:NXP_SMART_HARDWARE,微信公众号:恩智浦MCU加油站】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    深入解析Zephyr RTOS的技术细节

    Zephyr是一个针对资源受限设备优化的小型、可缩放、多体系架构实时操作系统(RTOS)。Zephyr由Linux基金会维护[1],是一个以构建业界最佳的RTOS为目标的开源合作项目。近年来
    的头像 发表于 10-22 16:47 192次阅读
    深入解析Zephyr <b class='flag-5'>RTOS</b>的技术细节

    freertos和rtos区别是什么

    FreeRTOS 和 RTOS(实时操作系统)是两个不同的概念,但它们之间有紧密的联系。FreeRTOS 是一个特定的开源实时操作系统,而 RTOS 是实时操作系统的一般概念。 概念定义 RTOS
    的头像 发表于 09-02 14:18 795次阅读

    RTOS的特性和类型

    实时操作系统(RTOS)是一种可运行实时计算应用程序的软件平台,用于处理具有明确时间约束的事件和数据。与通用操作系统(GPOS)不同,RTOS必须在有限的硬件资源上调度应用程序之间的处理和数据共享
    的头像 发表于 08-20 11:29 439次阅读

    RTOS开发最佳实践

    基于RTOS编写应用程序时,有一些要注意事项。在本节中,您将学习RTOS开发最佳实践,例如POSIX合规性、安全性和功能安全认证。
    的头像 发表于 08-20 11:24 363次阅读

    什么是实时操作系统(3)-在 RTOS 中可以期待什么?

    RTOS使用各种机制来管理任务、事件和内存,以确保嵌入式系统满足时间约束。在本节中,您将了解构建嵌入式应用程序时需要考虑的RTOS功能,例如确定性、空间和时间分离、调度、内存管理和进程间通信。
    的头像 发表于 07-23 12:00 942次阅读
    什么是实时操作系统(3)-在 <b class='flag-5'>RTOS</b> 中可以期待什么?

    RTOS-SDK如何关闭系统的提示信息?

    您好,我使用的1.3版本的RTOS-SDK,在STA状态,连接状态改变串口0会有提示信息产生,怎么样才能将其关闭呢?
    发表于 07-22 07:04

    是否可以扩展esp_iot_rtos_sdk以具有api功能来进行云更新?

    是否可以扩展esp_iot_rtos_sdk以具有 api 功能来进行云更新?SDK 编程指南(尽管我认为它不适用于 rtos sdk)表明存在
    发表于 07-15 08:19

    ESP8266_RTOS_SDK LWIP构建失败怎么解决?

    然后我克隆了 ESP8266_RTOS_SDK 的 release/v3.3 分支。这导致我的项目生成失败,并出现以下情况: 抄送构建/lwip/lwip/src/api/if_api.o 在
    发表于 07-09 08:01

    ESP8266_RTOS_SDK-v3.4的构建错误如何解决?

    我尝试将 SDK3.4 导入 Aithinker windows IDE 程序,然后构建它。不幸的是,我收到以下错误: LD /d/8266/ESP8266_RTOS
    发表于 07-08 07:59

    请问cyw20719或cyw20721是否支持RTOS

    请确认 cyw20719 或 cyw20721 是否支持 RTOS? 我们希望使用 RTOS 控制外设 SPI、I2C、PWM、ADC 等。 如果有,您有移植指南吗?
    发表于 05-20 06:39

    基于RTOS的应用进程中的典型线程

    RTOS中的关键因素是最小的中断延迟和最小的线程切换延迟。RTOS的价值在于它的响应速度或可预测性,而不是它在给定时间段内可以执行的工作量。
    发表于 03-05 09:32 489次阅读
    基于<b class='flag-5'>RTOS</b>的应用进程中的典型线程

    kernel到android核心启动过程

    总结一个图:kernel 到android核心启动过程 kernel镜像执行跳转到start_kernel开始执行,在rest_init会创建两个kernel 进程(线程),其分别是为
    的头像 发表于 12-04 16:59 848次阅读
    <b class='flag-5'>kernel</b>到android核心启动过程

    kernel的启动分为哪两个阶段

    设计。在运行过程中运行地址和加载地址一致(如果不明白的话建议先参考一《[kernel 启动流程] 前篇——vmlinux.lds分析》)。 (上一篇
    的头像 发表于 12-04 16:45 584次阅读

    kernel日志写入logd介绍

    kernel日志写入logd介绍 通过logcat命令获取kernel日志比较特殊,故作为一个例子进行梳理。 2.3.1 整体流程 2.3.2 命令打印kernel日志 通过logcat -b
    的头像 发表于 11-23 17:11 588次阅读
    <b class='flag-5'>kernel</b>日志写入logd介绍

    RTOS中的线程、进程和协程详解

    看到有小伙伴在讨论【RTOS任务属于线程还是进程】的话题,这里就来分析一OS中的线程、进程和协程的这几个概念,同时一起看看RTOS中的任务到底属于哪一种。
    的头像 发表于 11-09 12:36 1777次阅读
    <b class='flag-5'>RTOS</b>中的线程、进程和协程详解