Hi , i have a question about the Freertos task scheduling.
There are 2 task which priority is same and it is single core , as we know the kernel will prepare a time slice for every task .
And i am so wonder that is that possible when the task A had not finish its job and timeout happen ?
does the kernel will switch the context and make task B running? or keep the state until Task A finish its job ?
if task A and Task B were always operated the same queue ,which i mean that they will call the same API to push the data into the same queue.(and this API is without mutex operation)
is that possible sometimes when Task A push the data1 into queue location1 in half way ,and kernel time slice is timeout,and kernel switch context to Task B,
and then Task B doing the same push action (push data2 into queue location1) 。。。。
FreeRTOS will use a critical section to make the copying of the data into the queue an atomic operation, so you won’t have a problem. The copying of the queue data is quick enough, FreeRTOS chooses to use a Critical Section (which disable interrupt for a short while) instead of a Mutex, and trying to use a mutex wouldn’t work to allow ISRs to push data onto queues, which is an important use of them.
Yes, this will happen if you have set configUSE_TIME_SLICING to 1 so the scheduler will switch between equal priority tasks on each tick interrupt, and in your case task B will start running.
Hi Rohitmdn & Richard :
thank you for your reply first.
But i have not got the point !
As you said it is possible that switching action will be happen in this case (two same priority task). how does Freertos make sure copy data action will not be interrupt?
Looking at the code you shared, it seems like you are using a custom queue implementation instead of FreeRTOS queues. If that’s the case, your description is correct—a context switch can occur between the execution of the pushMsgQueue function.
FreeRTOS ensures data copying is not interrupted by temporarily disabling interrupts when performing critical operations. The xQueueSend() API, for example, internally uses taskENTER_CRITICAL() and taskEXIT_CRITICAL() to protect critical sections.
I recommend using FreeRTOS queues instead of a custom implementation. FreeRTOS provides robust queue management APIs such as xQueueCreate() and xQueueSend() to handle data safely and efficiently. You can refer to the Queue Management documentation for a complete list of available queue-related APIs.
As you shared, If you still need to ensure that a specific data operation is not preempted, you can explicitly disable and re-enable interrupts around it:
This approach ensures that no context switch occurs while push_data_action() executes.
FreeRTOS, in its queue functions, does basically that, the actual operations that manipulate the data are inside a critical section, so the operation can’t be interrupts.
If your “push_data_action” uses a FreeRTOS queue, then it will deal with the issue. If you are manipulating data objects yourself, then you need to deal with it.
You could use a critical section around the manipulation, and if the data might be also manipulated inside an ISR, that tends to be the way to do it. (Just be careful about making the critical section too long). If you don’t need to worry about an ISR, then longer periods can be done either by suspending the scheduler, or using a Mutex. The Mutex will cost a little bit of memory, but is the finest grained operation.
If this your custom queue implementation or are your trying to show what FreeRTOS queues might be doing? If later, as explained by @rohitmdn and @richard-damon, FreeRTOS adds critical sections to ensure that the data corruptions cannot happen.