I need feedback if this RTOS structure can work. If not, what is the problem?
Two tasks same priority. Currently configUSE_TIME_SLICING is set to 1
Whenever an interrupt occurs, a flag is set.
Task 1 loops checking for interrupt flags. If flag is set, the appropriate function is called. A total of 9 interrupt flags are checked in this task.
If the flag specific to task 2 is set, task 1 calls xTaskNotifyGive(&Task2Handle);
Task 2 activates on a specific interrupt flag and stays blocked at other times.
for( ;; )
{
ulTaskNotifyTake( pdTRUE, portMAX_DELAY );
do some processing
xTaskNotifyGive(&Task1Handle);
}
That would work but has a few inefficiencies - notably having a task polling for interrupt flags. Is that all the task is doing? If so then why not have the notification sent directly from the interrupt to the task that needs to be unblocked? Secondly, depending on the prioritisation and real time requirements of your system, if you can combine processing multiple interrupts into a single task then that will prevent you from having to create a task stack for each interrupt type. That would mean the [deferred] interrupt processing that occurs in the ‘do some processing’ part of your code would only be able to do the processing for one interrupt type at a time, then when that was done, it could do the next, effectively serialising processing. Like I said - it might be that is not appropriate for you needs but thought I would mention all the same.
I am now trying vTaskNotifyGiveFromISR from the interrupt that will wake up task 2. Task 2 stays indefinitely blocked ulTaskNotifyTake( pdTRUE, portMAX_DELAY );
However this is not waking task 2. If I step into vTaskNotifyGiveFromISR it skips traceTASK_NOTIFY_GIVE_FROM_ISR(); the eOriginalNotifyState is not eWaitingNotification and it exits the API. What does this mean?
If both tasks are the same priority, then a higher priority task won’t be unblocked, and it would be expected that *pxHigherPriorityTaskWoken remains pdFALSE.
Interrupts that call API functions must be at or below the priority set by configMAX_SYSCALL_INTERRUPT_PRIORITY (some ports call this configMAX_API_CALL_INTERRUPT_PRIORITY) - how to configure that depends on the port you are using. configKERNEL_INTERRUPT_PRIORITY should always be the lowest interrupt priority there is. There are several pages that document this, including RTOS for ARM Cortex-M
Thank you for your reply. For equal priority tasks, is it possible to block a task until the notification is given from an ISR? Or is the scheduler responsible for the task switch?
If a task switch can only happen to a higher priority task, how does the task switch happen out of the higher priority task to the lower priority task?
I’m not sure I understand the question because I thought that was what were doing. If you block on the notification, and the ISR gives the notification, then it will unblock the task because the event the task was waiting on will have happened.
The higher priority task must enter either the Blocked or Suspended state (the Blocked state in 99.999% of use cases). This is fundamental knowledge you need in order to write an efficient functioning application so I highly recommend you take some time to read through the first few chapters of the pdf book - it won’t take long at all.