首页 > 解决方案 > 如何在 RTOS 中处理任务抢占极端情况

问题描述

假设 RTOS 中有两个任务:TASKL(低优先级)和 TASKH(高优先级)。RTOS 遵循基于优先级的抢占调度。TASKL 执行三个操作: a) 使用 volatile 变量读取传感器值。b) 操作读取的值(比如乘以 10)。c) 向另一个组件发送值。现在假设一个场景,TASKL 执行了语句 a,然后被 TASKH 打断。同时,传感器值也被中断更新。当 TASKL 恢复时,它会从语句 b 恢复吗?如果是,那么它将更新传感器值还是旧传感器值?另外请让我知道我们怎样才能避免这种情况?

标签: embeddedrtosautosar

解决方案


这取决于实际的代码。您所写的内容如下:

//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,一个适当的互斥保护 RT​​OS 功能 ^^ 不过我不知道你的。

顺便说一句,回答您的一些问题:不,即使传感器中断已触发并更新了 sensor_volatile_val,语句“b”仍将使用它之前读取的“旧”值。

如果您出于某种原因不想使用“旧”传感器值。您可以在将其放入队列之前验证该值:

if( old_sensor_val != sensor_volatile_val) goto start;

但这在处理普通的“传感器”时几乎没有意义。


推荐阅读