三、任务通知源码分析
任务通知的创建就不用说了,任务被创建时则就便有了任务通知,而且FreeRTOS默认任务通知是开启的。
1.xTaskNotify函数
这个函数其实也是个宏定义,实际上调用的是xTaskGenericNotify这个函数
#define xTaskNotify( xTaskToNotify, ulValue, eAction ) \
xTaskGenericNotify( ( xTaskToNotify ), ( tskDEFAULT\_INDEX\_TO\_NOTIFY ), ( ulValue ), ( eAction ), NULL )
具体的原码介绍,看中文注释
#if ( configUSE\_TASK\_NOTIFICATIONS == 1 )//配置任务通知相关宏
BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify,
UBaseType_t uxIndexToNotify,
uint32\_t ulValue,
eNotifyAction eAction,
uint32\_t \* pulPreviousNotificationValue )
{
TCB_t \* pxTCB; //指向哪个任务句柄
BaseType_t xReturn = pdPASS;//返回值,用于判断是否设置通知成功
uint8\_t ucOriginalNotifyState;//原始的任务状态
configASSERT( uxIndexToNotify < configTASK_NOTIFICATION_ARRAY_ENTRIES );
configASSERT( xTaskToNotify );
pxTCB = xTaskToNotify;//指向任务句柄
taskENTER\_CRITICAL();//进入临界区
{
if( pulPreviousNotificationValue != NULL )//判断原始通知值是否存在
{
\*pulPreviousNotificationValue = pxTCB->ulNotifiedValue[ uxIndexToNotify ];
//覆盖任务通知值
}
//ucOriginalNotifyState 获得任务的原始状态
ucOriginalNotifyState = pxTCB->ucNotifyState[ uxIndexToNotify ];
//任务的状态设置为接收通知状态
pxTCB->ucNotifyState[ uxIndexToNotify ] = taskNOTIFICATION_RECEIVED;
switch( eAction )
/\*eAction具有五个模式typedef enum
{
eNoAction = 0, /\* 通知任务而不更新其通知值
eSetBits, /\* 在任务的通知值中设置位。
eIncrement, /\* 增加任务的通知值。
eSetValueWithOverwrite, /\* 将任务的通知值设置为特定值,即使任务尚未读取以前的值。
eSetValueWithoutOverwrite /\* 如果任务已读取前一个值,则设置任务的通知值。
} eNotifyAction;
\*/
{
case eSetBits:
pxTCB->ulNotifiedValue[ uxI