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

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

3天内不再提示

减少RTOS中的任务切换

星星科技指导员 来源:嵌入式计算设计 作者:Micro Digital 2022-06-29 09:28 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

任务切换是多任务处理的全部内容。然而,由于以下原因,太多可能会破坏:

它增加了 RTOS 开销

它增加了功耗

它降低了响应能力,尤其是低优先级任务

它增加了调试的复杂性

它可能会导致错误

它可以抑制未来的扩张

因为一个好的 RTOS 在低端 50 MHz Cortex-M3 上每秒可以实现大约 50,000 次任务切换,所以第一个问题对于大多数系统来说可能并不重要。然而,对于电池供电的设备,即使是很小的效率改进也很重要。设备用户可能会注意到低优先级人机界面任务的响应速度降低。不必要的任务切换会混淆已经很复杂的调试过程,因此如果没有其他原因的话,也是不可取的。

第五个原因尤为重要。如果您没有意识到可能会发生任务切换,那么事情可能不会总是按照预期的顺序发生。这可能会导致难以找到的零星错误。最后,随着新功能的添加,空闲时间可能会变得很宝贵,尤其是在处理器性能刚开始的时候。有充分的理由减少过多的任务切换。让我们看几个。

优先提升

一种流行的方法是在选择运行时自动提高任务的优先级。这在以下示例中显示:

void sys_init(void) {

TCB_PTR t2a; // task a of priority 2

t2a = smx_TaskCreate(t2a_main, PRI_2, 500, SMX_FL_NONE, “t2a”);

smx_TaskHook(t2a, t2a_entry, t2a_exit);

smx_TaskStart(t2a);

}

void t2a_entry(void) {

smx_TaskBump(self, 3);

}

void t2a_exit(void) {

smx_TaskBump(self, 2);

}

void t2a_main(void) {

while (1) {

// perform t2a function at priority 3

}

}

在此示例中,t2a_enter() 由调度程序透明地调用,在 t2a 恢复之前,并且 t2a_exit() 在 t2a 暂停之后类似地调用。t2a_enter() 将 t2a 移动到就绪队列级别 3 的前面并将其优先级提高到 3。t2a_exit() 将 t2a 移动到就绪队列级别 2 的末尾并将其优先级降低到 2。因此,t2a 不能被 a 抢占运行时的优先级 3 任务。但是具有更高优先级的任务可以抢占 t2a。在这种情况下,t2a 将回到优先级 2,从而允许任何等待优先级 3 的任务接下来运行。

这种方法很有吸引力,因为一旦 t2a 开始运行,就应该允许它结束。但是,您可能想知道为什么不将 t2a 列为优先级 3 的任务。优先级提升的优点是所有优先级为 3 的任务将在 t2a 允许开始之前运行。然后它成为其中之一。这在三种情况下是有意义的:

t2a 是一个简短的任务

t2a 是一个重型切换器

t2a 是超级用户

如果 t2a 是一项很长的任务,那么将其提升到优先级 3 并不是一个好主意,因为它会影响真正的优先级 3 任务的响应能力。所以,t2a 应该很短。

重型切换器的一个例子是浮点任务,与定点任务相比,它必须保存和恢复额外的 32 个寄存器。另一个例子是通过缓存从慢速内存执行的任务。然后,由于新任务使用不同的代码和变量,重度切换表现为缓存未命中和重新加载。即使在缓存环境中,提升的任务也应该很短。

如果 t2a 以比其他任务更高的功率级别运行(例如,它在运行时打开外围设备),则显然将其运行时间最小化是有益的,假设节能很重要。这是优先级提升的一个很好的用途。

除了优先级反转之外,优先级提升的另一个缺点是它增加了使用它的任务的切换开销。对于上面的示例,任务切换从每秒 50,000 次下降到 26,000 次,这不是问题。

任务锁定

任务锁定是防止不必要的任务切换的另一种方法。以下示例说明了这一点:

TCB_PTR t2a, t3a; // tasks

SCB_PTR sa; // semaphore

void t3a-main(void) {

smx_SemTest(sa);

// do something

}

void t2a-main(void) {

smx_SemSignal(sa);

}

这个例子除了说明隐藏的任务切换之外没有任何用处。由于 t3a 具有更高的优先级,它首先运行,然后等待信号量,sa。然后 t2a 运行并向 sa 发出信号。t2a 并没有像预期的那样停止,而是立即被 t3a 抢占,它做某事,然后停止。然后,t2a 再次运行,除了停止之外什么都不做。您现在可以看到这是一个浪费的任务切换。可以而且应该通过以下方式加以预防:

void t2a-main(void) {

smx_TaskLock();

smx_SemSignal(sa);

}

现在,在 t2a 停止并释放其锁定之前,t3a 无法抢占。请注意,这实际上是调度程序锁定,但我更喜欢称它为任务锁定,因为这更能描述它的作用。

更少的优先级

如果你发现你的系统做了太多的任务切换,最好简单地减少优先级的数量。为此,您显然需要一个允许任务共享优先级的 RTOS。假设您有这样的 RTOS,下一步是重新考虑相关的任务优先级。

当一项任务一直在等待时,它的紧迫性就会增加。降低优先级意味着可能已经抢占它的任务,从而使其等待更长时间,现在将在它之后运行。较低的优先级实际上可以实现更流畅的操作,以及减少不必要的任务切换。

试图过度控制活动而不是让它们自然发生是一种常见的冲动。不太有力的控制可能更能适应不可预见的情况,因此可能会产生更坚固的解决方案。值得一试。

循环调度

在降低优先级的过程中,引入相同优先级的任务的循环调度可能会有所帮助。这可以按如下方式完成:

void t2a_main(void) {

while (smx_TestSem(sa)) {

// do function a

smx_TaskBump(self, NO_PRI_CHG);

}

}

void t2b_main(void) {

while (smx_TestSem(sb)) {

// do function b

smx_TaskBump(self, NO_PRI_CHG);

}

}

当每个任务完成一些工作时,它会将自己撞到就绪队列级别 2 的末尾,以便其他任务可以运行,如果它有工作的话。如果两个任务都没有工作,则两者都将在各自的信号量上挂起,并且可以运行优先级较低的任务。当然,更高优先级的任务可以随时抢占 t2a 和 t2b。在这个例子中,这两个任务可能大部分时间都在等待工作。但是当他们的工作量增加时,他们会交替工作,从而公平地关注所有客户。

不可抢占的任务

通常一次性任务(没有像普通任务那样的内部循环)非常短,使它们不可抢占是有意义的,如下所示:

TCB_PTR t2a;

t2a = smx_TaskCreate(t2a_main, PRI_2, 0, SMX_FL_LOCK, “t2a”);

smx_TaskStart(t2a);

void t2a_main(void) {

// do something simple and stop

}

因为 t2a 是在创建时设置了它的 start-locked 标志,所以它在开始运行时将被锁定,因此在它停止或自行解锁之前是不可抢占的。这类任务非常适合更改关键控制结构之类的事情,因此您不希望它们被抢占。如果这样的任务要等待某个东西,它就会失去它的锁,从而变成可抢占的。

在许多情况下,优先级提升对于提高系统性能很有用。然而,更简单的方法,如任务锁定、降低优先级、循环调度和使用非抢占式任务在某些情况下也很有效。

审核编辑:郭婷

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

    关注

    31

    文章

    5589

    浏览量

    129072
  • RTOS
    +关注

    关注

    25

    文章

    862

    浏览量

    122613
  • 电池
    +关注

    关注

    85

    文章

    11360

    浏览量

    141309
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    RTOS Crash 问题全维度分析与解决指南

    rt_sem_release后Crash(实际误调用rt_sem_take); 原理 :RTOS中断上下文不允许调用阻塞API(无任务切换上下文); 解决 : 中断仅调用“中断安全版
    发表于 12-08 03:56

    FreeRTOS 空闲任务

    几乎所有的小型 RTOS 中都会有一个空闲任务,空闲任务属于系统任务,是必须要执行的,用户程序不能将其关闭。不光小型系统中有空闲任务,大型的
    发表于 12-04 07:35

    学习RTOS的意义?

    RTOS实现多任务管理。 嵌入式操作系统有众多的软件组件,可以极大的加速项目进度,避免重复造车轮。 2.技能需要 掌握操作系统,和基于RTOS的编程,实现更好的职业规划,对个人发展是必不可少的。 在招聘网
    发表于 11-27 08:16

    RTOS 必学概念:任务、信号量、队列一次搞懂

    如果你刚接触RTOS(实时操作系统),很可能会有这样的困惑:“RTOS和裸机程序到底有什么区别?”“任务是线程吗?为什么要分任务?”“信号量和互斥锁有什么区别,不都是同步手段吗?”“队
    的头像 发表于 11-17 10:53 194次阅读
    <b class='flag-5'>RTOS</b> 必学概念:<b class='flag-5'>任务</b>、信号量、队列一次搞懂

    嵌入式rtos哪一个更加值得去学习?

    嵌入式圈里聊 RTOS,总有人揪着任务调度的那点差异争得面红耳赤,可实际上这东西做透了大家都大差不差 —— 优先级调度、时间片轮转,核心逻辑翻来覆去就那些,真到项目里谁也没比谁快出多少,哪怕是所谓
    的头像 发表于 11-05 10:48 554次阅读
    嵌入式<b class='flag-5'>rtos</b><b class='flag-5'>中</b>哪一个更加值得去学习?

    py32f030移植thread nano开启读保护,任务切换失败的原因?

    读option,并打印;同时在切换任务之前,打印切换任务指针,都是一样的。不知道问题出在哪
    发表于 09-16 06:39

    什么是RTOS的优先级反转

    当一个高优先级任务正在等待一个资源,但一个低优先级任务正在持有它,一个中等优先级任务继续在中间运行时,就会发生优先级反转——阻止低优先级任务释放它。
    的头像 发表于 09-09 14:50 776次阅读

    py32f030 移植thread nano 开启读保护,任务切换失败怎么解决?

    读option,并打印;同时在切换任务之前,打印切换任务指针,都是一样的。不知道问题出在哪
    发表于 08-29 07:10

    请问编译纯rtos到底是选择Linux+rtos的sdk编译only rtos还是直接使用rtos sdk?

    编译纯rtos到底是选择Linux+rtos的sdk编译only rtos还是直接使用rtos sdk?
    发表于 07-11 07:22

    【RA4L1-SENSOR】05 按键实现RTOS任务切换

    与计数功能的切换,为之后的多任务切换做个铺垫。 2. 软件部分 将上次的实验工程复制一份,重命名为05_Button_Switch_Task 2.1 绑定按键IO &&
    发表于 06-16 22:38

    RTOS如何在FX3工作?

    大家好, 我正在使用 FX3 进行一个项目。 我想知道 RTOS 调度是如何工作的。 我知道调用“CyU3PKernelEntry();”后 RTOS 就会开始工作。 如果我只注册一个应用程序线程。 我的线程什么时候执行? 是否有其他系统/fx3 线程与我的线程共享系
    发表于 05-06 13:20

    详解RTOS的Hook函数

    Hook函数是RTOS的一个关键特性,通过该函数,用户可以增强对任务管理的控制,定义系统行为。
    的头像 发表于 03-24 16:14 840次阅读

    RTOS的本地存储指针使用

    本地存储指针是RTOS的一个重要特性,增强了任务管理和数据处理能力。在RTOS上下文中,本地存储是指存储在本地的特定任务或对象的数据。通常
    的头像 发表于 02-28 16:33 1172次阅读
    <b class='flag-5'>RTOS</b><b class='flag-5'>中</b>的本地存储指针使用

    RTOS的错误检查机制

    在嵌入式应用,有可能发生各种各样的错误,系统必须能够检测到这些错误并作出适当的响应。RTOS通常内置了一些错误检查功能,用于检测错误并向应用提供响应错误的方法。
    的头像 发表于 01-03 14:44 1022次阅读

    使用任务通知提高RTOS应用的效率

    在实时嵌入式系统,性能和资源效率是决定设计成败的关键因素。传统的实时操作系统(RTOS)提供了如队列、信号量和事件组机制,实现任务之间的同步和通信。FreeRTOS/SAFERTOS还提供一种方法可以使这些过程更快、更轻量化,
    的头像 发表于 12-27 14:54 1073次阅读