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

Stm32 如何从高优先级ISR中唤醒FreeRtos任务?,stm32,freertos,isr,Stm32,Freertos,Isr,使用: Stm32F10x、F2xx、F4xx FreeRtos 8.1.1 gcc-arm-none-eabi-4_8-2014q2 我有一个必须以高中断优先级运行的ISR,因此禁止在此ISR中调用FreeRTOSAPI(请参阅和) 在某些情况下,这些ISR会检测到一些情况,在这些情况下,休眠的FreeRtos任务应至少以可能的延迟被唤醒 通常情况下(如果ISR因为足够低的优先级而被允许调用FreeRTOSAPI),我会使用队列或信号量来解决这个问题 但如何通过高优先级ISR实现这一点 我

使用:

  • Stm32F10x、F2xx、F4xx
  • FreeRtos 8.1.1
  • gcc-arm-none-eabi-4_8-2014q2
我有一个必须以高中断优先级运行的ISR,因此禁止在此ISR中调用FreeRTOSAPI(请参阅和)

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

通常情况下(如果ISR因为足够低的优先级而被允许调用FreeRTOSAPI),我会使用队列或信号量来解决这个问题

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

我目前的interims方法如下(简要概述):

但这种方法有缺点:

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

有什么建议可以更好地解决这个问题,特别是在减少延迟的情况下?

我有一个想法,虽然没有经过测试,但它似乎应该可以工作

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

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


当高优先级ISR完成时(以及任何其他待定的ISR),将调用低优先级ISR。这样就可以调用FreeRTOS API并在不再延迟的情况下启动任务。

解决方案是使用FreeRTOS


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

有没有关于如何触发内部中断的想法/链接?好的,在st库中找到
EXTI_generateswinterrup()
。不幸的是,它需要浪费一条EXTI线路和一个irq通道。但我会试试看。是另一种不使用EXTI的方法,但由于使用了FreeRtos跟踪宏,对我的项目来说有点太粗糙了。现在,我将基于EXTI的解决方案与FreeRtos信号量结合使用。FreeRtos任务通知(由FreeRtos 8.2引入)是信号量的一个很好的替代方案。但请注意,也不允许从具有高中断优先级的ISR调用该api。
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)
    }
}