...waiting to synchronise with some external event?
If it's the case, then it's better to use one FreeRTOS task synchronisation methods, such as task notification or binary semaphores.
Hardware interrupts (as well as PCINT interrupts) are handled outside the context of FreeRTOS operating system, however it's possible to use the FreeRTOS interrupt safe "FromISR" API functions from within the interrrupt, to synchronise or pass information from the interrupt into a FreeRTOS task.
no this function is just to turn on the LEDs by writing to the specific PORT registers, this is not the blocking function and not waiting to sync with any other event.
In FreeRTOS, it's possible to use external hardware interrupts to call a standard Interrupt Service Routine (ISR) function then get this to call a high priority interrupt handler task. This not only allows the interrupt handling to be prioritised, but also handled within the context of the operating system itself.
Below is an example, in this case a standard attachInterrupt() ISR that gets called every second, each time the microcontroller receives a pulse from the RTC. Note that interrupt doesn't do any data processing itself, it mearly sends a task notification to a high priority interrupt handling task. It also allows this higher priorty task to preempt the task that's currently running by using the portYIELD_FROM_ISR() macro. In this way, FreeRTOS can handle interrupts in a timely manner:
void rtcTickHandler()
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
vTaskNotifyGiveFromISR(xTimeHandle, &xHigherPriorityTaskWoken); // Notify the RTC handler task that an RTC interrupt has occured
if (xHigherPriorityTaskWoken == pdTRUE) // Check if a higher priority task is in the ready state
{
portYIELD_FROM_ISR(); // Yield to the higher priority task
}
}
The interrupt handling task then immediately scheduled to run after the ISR, the task notification unblocking and executing the interrupt processing code:
void xTaskRTCInterrupt(void *pvParameters)
{
// Intialise local variables here...
for(;;) // Loop forever
{
if (ulTaskNotifyTake(pdTRUE, portMAX_DELAY) == pdTRUE) // Wait indefinitely to receive an interrupt from the RTC
{
// Process the RTC interrupt here...
}
}
}
After executing the code, the task loops round and blocks waiting for the next task notification from the ISR. This allows the scheduler to switch back to whatever it was doing beforehand.