如何解决如何处理 RTOS 中的任务抢占极端情况
假设一个 RTOS 中有两个任务:TASKL(低优先级)和 TASKH(高优先级)。 RTOS 遵循基于优先级的抢占调度。 TASKL 执行三个操作: a) 使用易失性变量读取传感器值。 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;
但这在处理普通“传感器”时几乎没有意义。
,作为一个有趣的小问题,如果未限定为 volatile
的对象以编译器不期望的方式被修改,gcc 有时会表现得非常奇怪。使用选项 -mcpu=cortex-m0 -O2
for
unsigned short test(unsigned short *p)
{
unsigned short temp = *p;
return temp - (temp >> 15);
}
如果 *p
的值在该函数执行期间在 0xFFFF 和 0 之间变化,则将返回 0xFFFF,反之亦然,即使该函数只读取一次 *p
,如果 {{ 1}} 被读取为 0xFFFF,如果它*p
被读取为零,则为零。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。