I try to understand why the user has to call the taskYIELD_FROM_ISR()
method and why it isn't automatically called by the RTOS within the xStreamBufferSendFromISR
method.
My question refers to the FreeRTOS_Manual p. 369.
/* A stream buffer that has already been created. */
StreamBufferHandle_t xStreamBuffer;
void vAnInterruptServiceRoutine( void ) {
size_t xBytesSent;
char *pcStringToSend = "String to send";
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
/* Attempt to send the string to the stream buffer. */
xBytesSent = xStreamBufferSendFromISR(xStreamBuffer,(void *) pcStringToSend,strlen( pcStringToSend),&xHigherPriorityTaskWoken);
if(xBytesSent != strlen(pcStringToSend)){
/* There was not enough free space in the stream buffer for the entire string to be written, ut xBytesSent bytes were written. */
}
/*
If xHigherPriorityTaskWoken was set to pdTRUE inside xStreamBufferSendFromISR() then a
task that has a priority above the priority of the currently executing task was unblocked
and a context switch should be performed to ensure the ISR returns to the unblocked task.
In most FreeRTOS ports this is done by simply passing xHigherPriorityTaskWoken into
taskYIELD_FROM_ISR(), which will test the variables value, and perform the context switch
if necessary. Check the documentation for the port in use for port specific instructions.
*/
taskYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
My understanding of the scenario
Preconditions
- There are two tasks
- Task1 (high priority) and Task2 (low priority)
- Task1 is in Blocked-State waiting for a streamBuffer input
- Task2 is in Running-State and is interrupted from
vAnInterruptServiceRoutine
Within the ISR
- The ISR method calls
xStreamBufferSendFromISR()
- This call means, that the Blocked-State of Task1 changes into the Ready-State
Case A If the ISR method is returning now, the scheduler will not be called and Task2 is running until the time slice period is over and then the scheduler switches to the high prior Task1.
Case B
If the ISR method calls taskYIELD_FROM_ISR(xHigherPriorityTaskWoken);
at last, the scheduler will be called and after returning the ISR, Task1 will be running instead of Task2.
Questions
- Is it right, that Task2 will be executed until a time slice period is over or is there another tigger for the task switch?
- Why is the
taskYIELD_FROM_ISR()
method not called automatically by the RTOS when callingxStreamBufferSendFromISR()
?
taskYIELD_FROM_ISR()
as well as using the "FromISR" APIs in ISRs puts a big burden on the programmer. It also leads to duplication of APIs ("regular" and "FromISR()" APIs). But most unfortunately, this design aspect of FreeRTOS opens up a wide range of possible errors where the wrong API type is used. For example, callback functions are often invoked from the ISR context. Moreover, the flagxHigherPriorityTaskWoken
needs to be somehow propagated up the call stack. – Packhorse