embedded - 如何在 RTOS 中处理任务抢占极端情况
问题描述
假设 RTOS 中有两个任务:TASKL(低优先级)和 TASKH(高优先级)。RTOS 遵循基于优先级的抢占调度。TASKL 执行三个操作: a) 使用 volatile 变量读取传感器值。b) 操作读取的值(比如乘以 10)。c) 向另一个组件发送值。现在假设一个场景,TASKL 执行了语句 a,然后被 TASKH 打断。同时,传感器值也被中断更新。当 TASKL 恢复时,它会从语句 b 恢复吗?如果是,那么它将更新传感器值还是旧传感器值?另外请让我知道我们怎样才能避免这种情况?
解决方案
这取决于实际的代码。您所写的内容如下:
//a
int val = sensor_volatile_val;
//b
val *= 10;
//c
put_into_queue(val);
上面的代码不会受到调度错误的影响,(在大多数平台上)因为易失性读取很可能是原子的。这可以通过显式原子读取来改进(在大多数平台上):
int val = atomic_read32(sensor_volatile_val);
但是,重要的是sensor_volatile_val实际上被定义为 volatile。(看到它被中断更新了。)中断给出了潜在的竞争条件。不是调度。调度问题可能发生在语句“c”中。“向另一个组件发送价值”是相当模棱两可的。
我的“put_into_queue”是 ofc,一个适当的互斥保护 RTOS 功能 ^^ 不过我不知道你的。
顺便说一句,回答您的一些问题:不,即使传感器中断已触发并更新了 sensor_volatile_val,语句“b”仍将使用它之前读取的“旧”值。
如果您出于某种原因不想使用“旧”传感器值。您可以在将其放入队列之前验证该值:
if( old_sensor_val != sensor_volatile_val) goto start;
但这在处理普通的“传感器”时几乎没有意义。
推荐阅读
- node.js - 其他计算机可ping通时如何添加PM2启动脚本
- json - 将 EIA Json 转换为 DataFrame - Python 3.6
- xml - 在 NLog.config 中将 ${basedir} 更改为引用桌面
- c# - 如何为用于在 Xamarin 中创建 SQLITE 表的类设置 [NotNull, Default(value: 0)]
- google-api - 联系人 API 调用中 maxResults 的默认值是多少?
- http2 - 我可以使用 HTTP/2 Server Push 发送资源吗?
- html - Flex order 和 flex-direction 在 IE11 和 Edge 中不起作用
- c# - 将 XML 字符串反序列化为对象 C#
- android - 如何使用 SQLite 数据库中的数据设置 EditText
- three.js - 三个Js从多个场景中获取所有元素