首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >FreeRTOS:为什么要在isrHandler中调用taskYIELD_FROM_ISR()方法

FreeRTOS:为什么要在isrHandler中调用taskYIELD_FROM_ISR()方法
EN

Stack Overflow用户
提问于 2019-10-30 17:58:13
回答 2查看 5.7K关注 0票数 8

我试图理解为什么用户必须调用taskYIELD_FROM_ISR()方法,以及为什么xStreamBufferSendFromISR方法中的RTOS不自动调用它。

我的问题涉及手册第369页。

代码语言:javascript
复制
/* 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);
}

我对场景的理解

先决条件

  • 有两个任务
    • Task1 (高优先级)和Task2 (低优先级)

  • Task1处于阻塞状态,等待streamBuffer输入。
  • Task2处于运行状态,并被vAnInterruptServiceRoutine中断。

ISR中的

  • ISR方法调用xStreamBufferSendFromISR()
  • 此调用意味着,Task1的阻塞状态将变为就绪状态。

Case A如果ISR方法现在返回,则调度程序将不会被调用,Task2将在时间切片周期结束之前运行,然后调度程序切换到较高的优先Task1。

Case B如果ISR方法最终调用taskYIELD_FROM_ISR(xHigherPriorityTaskWoken);,则将调用调度程序,在返回ISR后,Task1将运行而不是Task2。

问题

  1. 对吗,Task2将被执行,直到一个时间段结束,或者任务切换是否有另一个tigger?
  2. 为什么RTOS在调用taskYIELD_FROM_ISR()时不自动调用xStreamBufferSendFromISR()方法
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-11-07 05:53:23

  1. 是的,在不调用taskYIELD_FROM_ISR的情况下,调度程序会在下一个预定的滴答中向Task1提供上下文。这可以用Segger SystemView进行验证。uartPrintTask在信号量上阻塞,然后从缓冲区打印数据。注意,在uartPrintTask“就绪”和“运行”之间有很长的延迟。这种延迟是可变的--尽管它的持续时间永远不会超过1mS (示例中的滴答率)

现在,在ISR末尾添加了与taskYIELD_FROM_ISR相同的示例。在ISR之后始终执行uartPrintTask

  1. automatically FreeRTOS不能从ISR调用任何东西。你可以完全控制所有的干扰。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()函数。

票数 10
EN

Stack Overflow用户

发布于 2019-10-31 09:40:05

  • 1)我想是的
  • 2)我对此不太确定。我认为这样做是为了保持中断速度快和保持上下文切换开销低。因此,根据需要的响应时间,触发上下文开关与否取决于您的选择。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58631246

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档