Joe
Joe

Reputation: 3160

How to wake up a FreeRtos task from a high priority ISR?

Using:

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:

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

Upvotes: 4

Views: 5149

Answers (2)

deddebme
deddebme

Reputation: 465

The solution is to use FreeRTOS Task notification.

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

Upvotes: 0

mbmcavoy
mbmcavoy

Reputation: 2686

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.

Upvotes: 2

Related Questions