Hi, I have a requirement to perform an operation within 200us of receiving an interrupt. The ISR when triggered will post an event and once the event is delivered to the waiting task ,It works normal when only has one task(taskA) in the system.
When add the other task(taskB,this one is Lower priority,but takes about 5ms deal with some things), there is a delay in this event received by about 0.1~5 microseconds (random).
The TaskA has higher priority than the TaskA, why the TaskA can’t preempt the TaskB?
I am using this on STM32G473(Cortex M4) and have already used portYIELDFROM ISR() after xEventGroupSetBitsFromISR() in the ISR.
What is osEventFlagsSet() doing? Is it a wrapper for a FreeRTOS event group? If so, that is a very inefficient way to unblock a task from an interrupt because event groups are not deterministic as you don’t know how many tasks setting an event bit will unblock. Because it’s not deterministic, FreeRTOS won’t perform the action in the task ISR itself, but instead defer the operation to the timer task. The configuration constants you show don’t include the timer task priority - but no matter what it is - the timer task will run before the task you are trying to unblock. Using a direct to task notification will be much faster.
It appears that the timer task priority is set lower than osPriorityNormal (24), so the timer task must wait for task A to finish Attitude_Calculation() – a 5ms operation. Only then can task B wake up, even though it has the highest priority of all.
As Richard suggests, using direct-to-task notification would resolve all of this, and your synchronization latency will end up even shorter than if you increase the priority of the timer task and stay with event groups.
As Richard explained task notifications are the fastest way to signal an event to a task providing lowest latency and jitter. Do you properly use them following the example in the API docs ?
Especially using the xHigherPriorityTaskWoken flag ?
Event groups can be used without FreeRTOS timers (configUSE_TIMERS). One example from the FreeRTOS+TCP library: when an API waits for the IP-task, the function xEventGroupWaitBits() is called. When the IP-task has an answer, it will call xEventGroupSetBits() to wake up to signal user task.
Only when “FromISR” event group functions are called, the FreeRTOS timers feature (configUSE_TIMERS) might be needed.
I increased SysTick to 10khz and the unwanted “sync to systick” (sympthom description, not description of found and understood error) reduced to 100us.
This is my config, can you see something missconfigured that explains the behaviour?
Given you have a similar scenario and use correctly pxHigherPriorityTaskWoken with vTaskNotifyGiveFromISR AND the notified task is waiting for a notification AND has the highest prio, it gets scheduled as soons as the ISR is left and no other ISR is running, of course.
If there is another task with the same prio currently running (owning the CPU) there can be a latency until the next systick when the scheduler selects the other (the previously notified) task with equal prio. That’s how the preemptive scheduler works (as documented).
Since you’ve enabled the TICK and IDLE_HOOK there might be something else int the respective hook functions causing the behaviour mentioned.
Thanks for insights. Its 8.3us on my device, if priority of taking task is highest.
If the taking task is not highest-rated priority, it is synced to systick. Can this be changed? I mean, CPU is ideling around while a notification is pending…
This can only happen if your application task has the same prio as the idle task i.e. the lowest possible prio. Then the scheduler schedules idle task and your application task in a round robin/time sliced scheme. This is not really the idea of the idle task which should be the absolute lowest prio task and hence only run if there is really nothing else to do.
So better start at lowest/idle prio +1 with your application task priorities.