我试图理解为什么用户必须调用taskYIELD_FROM_ISR()方法,以及为什么xStreamBufferSendFromISR方法中的RTOS不自动调用它。
我的问题涉及手册第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);
}我对场景的理解
先决条件
vAnInterruptServiceRoutine中断。ISR中的
xStreamBufferSendFromISR()Case A如果ISR方法现在返回,则调度程序将不会被调用,Task2将在时间切片周期结束之前运行,然后调度程序切换到较高的优先Task1。
Case B如果ISR方法最终调用taskYIELD_FROM_ISR(xHigherPriorityTaskWoken);,则将调用调度程序,在返回ISR后,Task1将运行而不是Task2。
问题
taskYIELD_FROM_ISR()时不自动调用xStreamBufferSendFromISR()方法发布于 2019-11-07 05:53:23
taskYIELD_FROM_ISR的情况下,调度程序会在下一个预定的滴答中向Task1提供上下文。这可以用Segger SystemView进行验证。uartPrintTask在信号量上阻塞,然后从缓冲区打印数据。注意,在uartPrintTask“就绪”和“运行”之间有很长的延迟。这种延迟是可变的--尽管它的持续时间永远不会超过1mS (示例中的滴答率)
现在,在ISR末尾添加了与taskYIELD_FROM_ISR相同的示例。在ISR之后始终执行uartPrintTask。

taskYIELD_FROM_ISR应该放在ISR实现的末尾(但是您可能在ISR中的任何地方都调用了xStreamBufferSendFromISR )。FreeRTOS的优点之一(在我看来)是,它没有劫持任何东西,并提供了大量的灵活性。您可以在RTOS下完全执行中断-- FreeRTOS不需要知道任何关于它们的信息。不自动调用taskYIELD_FROM_ISR是这种灵活性的另一个例子(在我看来)。
来自SafeRTOS手册
在中断服务例程中调用xQueueSendFromISR()或xQueueReceiveFromISR()可能会导致任务离开阻塞状态,如果解除阻塞任务的优先级高于中断任务,则需要进行上下文切换。当xQueueSend()或xQueueReceive()导致比调用任务优先级更高的任务退出阻塞状态时,上下文切换将透明地执行(在API函数中)。这种行为在任务中是可取的,而不是从中断服务例程中得到的。因此,xQueueSendFromISR()和xQueueReceiveFromISR(),而不是自己执行上下文切换,而是返回一个指示是否需要上下文切换的值。如果需要上下文切换,应用程序编写器可以在最合适的时间(通常在中断处理程序的末尾)使用taskYIELD_FROM_ISR()来执行上下文切换。有关更多信息,请参见第69页的“xQueueSendFromISR()”和第71页的“xQueueReceiveFromISR()”,它们分别描述了xQueueSendFromISR()和xQueueReceiveFromISR()函数。
发布于 2019-10-31 09:40:05
https://stackoverflow.com/questions/58631246
复制相似问题