下载 FreeRTOS
 

出色的 RTOS & 嵌入式软件

内核
最新资讯
简化任何设备的身份验证云连接。
利用 CoAP 设计节能型云连接 IoT 解决方案。
11.0.0 版 FreeRTOS 内核简介:
FreeRTOS 路线图和代码贡献流程。
使用 FreeRTOS 实现 OPC-UA over TSN。

xTaskNotifyFromISR / xTaskNotifyIndexedFromISR
[RTOS 任务通知 API]


task.h

 BaseType_t xTaskNotifyFromISR( TaskHandle_t xTaskToNotify,
                                uint32_t ulValue,
                                eNotifyAction eAction,
                                BaseType_t *pxHigherPriorityTaskWoken );

BaseType_t xTaskNotifyIndexedFromISR( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction, BaseType_t *pxHigherPriorityTaskWoken );

可从中断服务程序 (ISR) 中使用的 xTaskNotify() 和 xTaskNotifyIndexed() 版本。请参阅 xTaskNotify() API 函数的文档页面,了解有关其操作的描述和必要的配置参数,以及向后兼容性信息。

参数:
xTaskToNotify   正在通知的 RTOS 任务的句柄。 这是目标任务。

要获取任务句柄, xTaskCreate() 创建任务并使用 pxCreatedTask 参数,或使用返回值创建任务 xTaskCreateStatic() 并存储该值,或在 调用 xTaskGetHandle() 中使用任务的名称。

当前执行的 RTOS 任务的句柄通过以下方式 由 xTaskGetCurrentTaskHandle() API 函数返回。

uxIndexToNotify   目标任务通知值数组中的索引, 通知值将发送给该索引。

uxIndexToNotify 必须小于 configTASK_NOTIFICATION_ARRAY_ENTRIES。

xTaskNotifyFromISR() 中没有此参数,总是向索引 0 发送通知。

ulValue   用于更新目标任务的通知值。 请参阅下面 eAction 参数的说明。
eAction   一种枚举类型,可以采用 下表中记录的值之一来执行相关操作。
pxHigherPriorityTaskWoken   *pxHigherPriorityTaskWoken 必须初始化为 0。

如果发送通知导致某个任务解除阻塞, 且被解除阻塞的任务的优先级高于当前运行的任务, xTaskNotifyFromISR() 会将 *pxHigherPriorityTaskWoken 设置为 pdTRUE。

如果 xTaskNotifyFromISR() 将此值设置为 pdTRUE, 则应在中断退出之前请求上下文切换 。 请参阅以下示例。

pxHigherPriorityTaskWoken 为可选参数,且可 设置为 NULL。

eAction Setting 已执行的操作
eNoAction 目标任务接收事件,但其 通知值未更新。 在这种情况下,不使用 ulValue。

eSetBits 目标任务的通知值 使用 ulValue 按位或运算。 例如, 如果 ulValue 设置为 0x01,则将在 目标任务的通知值中设置位 0。 同样,如果 ulValue 为 0x04,则将在 目标任务的通知值中设置位 2。 通过这种方式,RTOS 任务通知机制 可以用作 事件组的轻量级替代方案。

eIncrement 目标任务的通知值将 按 1 递增,使调用 xTaskNotifyFromISR() 相当于调用 vTaskNotifyGiveFromISR()。 在这种情况下,不使用 ulValue。
eSetValueWithOverwrite 目标任务的通知值 无条件设置为 ulValue。 因此, RTOS 任务通知机制可用作 xQueueOverwrite() 的轻量级替代方案。
eSetValueWithoutOrwrite 如果目标任务没有 挂起的通知,则其通知值 将设置为 ulValue。

如果目标任务已经有 挂起的通知,则不会更新其通知值, 因为这样做会覆盖 之前使用的值。 在这种情况下,调用 xTaskNotify() 会失败。

通过这种方式,RTOS 任务通知机制 在长度为 1 的队列上用作 xQueueSend() 在长度为 的轻量级替代方案。

返回:
除了 eAction 被设置为 eSetValueWithoutOverwrite 且目标任务的通知值 因目标任务已有挂起的通知而无法更新之外, 在所有情况下均返回 pdPASS。


用法示例:

[更多示例请参考主 RTOS 任务通知页面]

此示例演示了如何结合使用 xTaskNotifyFromISR() 和 eSetBits 操作。 请参阅 xTaskNotify() API 文档页面, 查看有关如何使用 eNoAction、eSetValueWithOverwrite 和 eSetValueWithoutOverwrite 行为的示例。



/* The interrupt handler does not perform any processing itself. Instead it
it unblocks a high priority task in which the events that generated the
interrupt are processed. If the priority of the task is high enough then the
interrupt will return directly to the task (so it will interrupt one task but
return to a different task), so the processing will occur contiguously in time -
just as if all the processing had been done in the interrupt handler itself.
The status of the interrupting peripheral is sent to the task using an RTOS task
notification. */

void vANInterruptHandler( void )
{
BaseType_t xHigherPriorityTaskWoken;
uint32_t ulStatusRegister;

/* Read the interrupt status register which has a bit for each interrupt
source (for example, maybe an Rx bit, a Tx bit, a buffer overrun bit, etc. */

ulStatusRegister = ulReadPeripheralInterruptStatus();

/* Clear the interrupts. */
vClearPeripheralInterruptStatus( ulStatusRegister );

/* xHigherPriorityTaskWoken must be initialised to pdFALSE. If calling
xTaskNotifyFromISR() unblocks the handling task, and the priority of
the handling task is higher than the priority of the currently running task,
then xHigherPriorityTaskWoken will automatically get set to pdTRUE. */

xHigherPriorityTaskWoken = pdFALSE;

/* Unblock the handling task so the task can perform any processing necessitated
by the interrupt. xHandlingTask is the task's handle, which was obtained
when the task was created. The handling task's 0th notification value
is bitwise ORed with the interrupt status - ensuring bits that are already
set are not overwritten. */

xTaskNotifyIndexedFromISR( xHandlingTask,
0,
ulStatusRegister,
eSetBits,
&xHigherPriorityTaskWoken );

/* Force a context switch if xHigherPriorityTaskWoken is now set to pdTRUE.
The macro used to do this is dependent on the port and may be called
portEND_SWITCHING_ISR. */

portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
/* ----------------------------------------------------------- */

/* A task that blocks waiting to be notified that the peripheral needs servicing,
processing all the events pending in the peripheral each time it is notified to
do so. */

void vHandlingTask( void *pvParameters )
{
uint32_t ulInterruptStatus;

for( ;; )
{
/* Block indefinitely (without a timeout, so no need to check the function's
return value) to wait for a notification. NOTE! Real applications
should not block indefinitely, but instead time out occasionally in order
to handle error conditions that may prevent the interrupt from sending
any more notifications. */

xTaskNotifyWaitIndexed( 0, /* Wait for 0th Notificaition */
0x00, /* Don't clear any bits on entry. */
ULONG_MAX, /* Clear all bits on exit. */
&ulInterruptStatus, /* Receives the notification value. */
portMAX_DELAY ); /* Block indefinitely. */

/* Process any bits set in the received notification value. This assumes
the peripheral sets bit 1 for an Rx interrupt, bit 2 for a Tx interrupt,
and bit 3 for a buffer overrun interrupt. */

if( ( ulInterruptStatus & 0x01 ) != 0x00 )
{
prvProcessRxInterrupt();
}

if( ( ulInterruptStatus & 0x02 ) != 0x00 )
{
prvProcessTxInterrupt();
}

if( ( ulInterruptStatus & 0x04 ) != 0x00 )
{
prvClearBufferOverrun();
}
}
}






Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.