4

使用:

  • Stm32F10x、F2xx、F4xx
  • FreeRtos 8.1.1
  • gcc-arm-none-eabi-4_8-2014q2

我有一个必须以高中断优先级运行的 ISR,因此禁止在此 ISR 中调用 FreeRtos Api(请参阅此处此处)。

在某些情况下,这些 ISR 会检测条件,在这些条件下,休眠的 FreeRtos 任务应该以至少可能的延迟唤醒。

通常(如果由于足够低的优先级而允许 ISR 调用 FreeRtos Api)我会使用队列或信号量来解决这个问题。

但是如何通过高优先级 ISR 实现这一点?

我目前的临时方法是这样的(简要概述):

volatile int flag = 0;

void XYZ_IRQHandler() {
    if (someCondition)
        flag = 1
}

void FreeRtosTaskFunction(void* parameters) {
    for (;;) {
        if (flag == 1)
            doSomething();
        vTaskDelay(1);  // sleep 10ms (tick frequency is 100Hz)
    }
}

但这种方法有以下缺点:

  • 延迟(从在 ISR 中设置标志直到任务唤醒)最多为 1 个 FreeRtos 滴答。
  • 需要轮询标志(浪费 cpu 周期)。

有什么建议可以更好地解决这个问题,尤其是延迟更少?

4

2 回答 2

2

我有一个想法,尽管未经测试似乎应该可行。

我假设您的 ISR 具有高优先级,因为它需要极低的延迟来执行不受其他中断影响的事情(即在准确的时间进行测量),并且任务应该很快完成,但并不完全关键(即传输或显示值)。

在您的高优先级 ISR 中,执行时序关键功能,然后触发低优先级内部中断。

当高优先级 ISR 完成(以及任何其他待处理)时,将调用低优先级 ISR。这可以调用 FreeRTOS API 并立即启动任务。

于 2014-10-08T22:49:13.253 回答
0

解决方案是使用 FreeRTOS任务通知

您的任务将挂起,然后在 ISR 事件后立即恢复/唤醒。

于 2017-08-11T14:16:57.270 回答