如何从高优先级ISR中唤醒FreeRtos任务?

时间:2014-10-08 19:27:27

标签: stm32 freertos isr

使用:

  • Stm32F10x,F2xx,F4xx
  • FreeRtos 8.1.1
  • GCC-臂-NONE-EABI-4_8-2014q2

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

在某些情况下,这些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 tick。
  • 需要轮询旗帜(浪费cpu周期)。

有任何建议可以更好地解决这个问题,特别是延迟时间更短吗?

1 个答案:

答案 0 :(得分:2)

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

我假设您的ISR是一个高优先级,因为它需要极低的延迟来做一些不受其他中断影响的事情(即,在一个确切的时间进行测量),并且任务应该快速完成,但不是&# 39; t非常重要(即传输或显示该值)。

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

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