4

Using:

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

I have an ISR which must run with high interrupt priority, so that's forbidden to call FreeRtos Api from within this ISR (see here and here).

In some cases these ISR detects conditions, for which a sleeping FreeRtos task should be waked up with at least possible latency.

Normally (if the ISR was allowed to call FreeRtos Api because of enough low priority) I would use a queue or semaphore to solve this.

But how to realize that with a high priority ISR?

My current interims approach is like this (briefly outlined):

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)
    }
}

But this approach has the disadvantages:

  • Latency (from setting the flag in ISR until task wakeup) to is up to 1 FreeRtos tick.
  • Need to poll the flag (waste of cpu cycles).

Any suggestions to solve this in a better way, especially with less latency?

Joe
  • 3,090
  • 6
  • 37
  • 55

2 Answers2

2

I have an idea, although not tested seems like it should work.

I am assuming that your ISR is a high priority because it needs an extremely low latency to do something unaffected by other interrupts (i.e., take a measurement at an exact time), and the task should be done quickly, but isn't quite as critical (i.e., transmit or display the value).

In your high-priority ISR, perform the timing-critical function, and then trigger a low-priority internal interrupt.

When the high-priority ISR is complete, (as well as any others pending), the low-priority ISR will be called. This can then call the FreeRTOS API and initiate the task with no further delay.

mbmcavoy
  • 2,628
  • 5
  • 23
  • 34
  • Any idea / link how to trigger a internal interrupt? – Joe Oct 08 '14 at 23:05
  • Ok, found `EXTI_GenerateSWInterrupt()` within the st-lib. Unfortulately, it needs to waste a EXTI Line and also an irq channel. But I'll give it a try. – Joe Oct 09 '14 at 05:06
  • [Here](https://sourceforge.net/p/freertos/discussion/382005/thread/140cde98/#694c) is another approach without the use of EXTI, but because of using a FreeRtos trace macro, it's a bit too hacky for my project. I'd now applied the EXTI based solution in combination with a FreeRtos semaphore. – Joe Oct 11 '14 at 18:33
0

The solution is to use FreeRTOS Task notification.

Your task will pend, then resume/awaken right away upon the ISR event.

deddebme
  • 445
  • 1
  • 5
  • 10
  • 3
    FreeRtos Task Notification (introduced with FreeRtos 8.2) is a nice alternative to a semaphore. But note that it's also not allowed to call that api from a ISR with high interrupt priority. – Joe Aug 14 '17 at 12:31