【问题标题】:What's the downside (if any) of using "FromISR" FreeRTOS calls in non-ISR contexts?在非 ISR 上下文中使用“FromISR”FreeRTOS 调用有什么缺点(如果有)?
【发布时间】:2019-12-03 02:45:34
【问题描述】:

为了使我正在编写的函数能够在 ISR 内部和外部使用,只使用 FreeRTOS API 调用的 ISR 安全版本是否安全?

// NOT ISR-safe
uint32_t messages_waiting(void)
{
    return uxQueueMessagesWaiting(queue);
}

// ISR-safe
// - maybe just use this function ALL THE TIME??--both inside and outside ISRs?
uint32_t messages_waiting(void)
{
    return uxQueueMessagesWaitingFromISR(queue);
}

FreeRTOS API 参考:https://www.freertos.org/a00018.html#ucQueueMessagesWaitingFromISR

以下是每个函数的 FreeRTOS 实现,来自 queue.c

UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue )
{
UBaseType_t uxReturn;

    configASSERT( xQueue );

    taskENTER_CRITICAL();
    {
        uxReturn = ( ( Queue_t * ) xQueue )->uxMessagesWaiting;
    }
    taskEXIT_CRITICAL();

    return uxReturn;
} /*lint !e818 Pointer cannot be declared const as xQueue is a typedef not pointer. */

UBaseType_t uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue )
{
UBaseType_t uxReturn;

    configASSERT( xQueue );

    uxReturn = ( ( Queue_t * ) xQueue )->uxMessagesWaiting;

    return uxReturn;
} /*lint !e818 Pointer cannot be declared const as xQueue is a typedef not pointer. */

跟进:我可以看到非 ISR-safe 版本添加了访问保护:

taskENTER_CRITICAL();
taskEXIT_CRITICAL();

也许我也可以添加这些 ISR 安全版本,如下所示? 现在,这个函数可以在 ISR 内部和外部使用吗?

uint32_t messages_waiting(void)
{
    UBaseType_t saved_interrupt_status = taskENTER_CRITICAL_FROM_ISR();
    uint32_t num_msgs_waiting = uxQueueMessagesWaitingFromISR(queue);
    taskEXIT_CRITICAL_FROM_ISR(saved_interrupt_status);

    return num_msgs_waiting;
}

taskENTER_CRITICAL_FROM_ISR()的参考和示例用法:https://www.freertos.org/taskENTER_CRITICAL_FROM_ISR_taskEXIT_CRITICAL_FROM_ISR.html

【问题讨论】:

    标签: queue freertos isr


    【解决方案1】:

    在这个特定的上下文中,从技术上讲,使用函数的fromISR 变体是安全的。不过我不推荐它,因为这可能随时更改,并且在您决定将 FreeRTOS 升级到较新版本后检测此错误将是一件痛苦的事情。

    它们为队列/互斥体/信号量上运行的函数提供单独的非 ISR 和 from-ISR 变体的原因是为了提供一致的 API,即使在技术上函数与本例中执行完全相同的事情的情况下也是如此。这样做是为了让您的应用程序在整个 FreeRTOS 升级过程中继续工作,即使底层实现可能会发生巨大变化。只要您正确使用 API,它应该会继续像以前一样运行。

    PS。作为其他阅读这篇文章的人的旁注——混合非 ISR 和来自 ISR 的函数变体通常是非常不安全的。例如,大多数非 ISR 函数执行关键部分进入/退出和 - 根据情况 - 任务抢占,而 from-ISR 变体不这样做。如果你把这两者混在一起,你就是在自找麻烦。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-19
      • 1970-01-01
      • 2011-09-23
      相关资源
      最近更新 更多