1、 介绍任务通知结构体和常用函数。
①任务通知的状态
#define taskNOT_WAITING_NOTIFICATION ( ( uint8_t ) 0 )//任务没有等待通知
#define taskWAITING_NOTIFICATION ( ( uint8_t ) 1 )//任务在等待通知
#define taskNOTIFICATION_RECEIVED ( ( uint8_t ) 2 )//任务接收到通知
②任务通知的操作
typedef enum
{
eNoAction = 0, /* 通知任务而不更新其通知值。(在stream_buffer时会用到) */
eSetBits, /* 在任务的通知值中设置位。(任务通知代替通知) */
eIncrement, /* 增加任务的通知值。 (任务通知代替信号量)*/
eSetValueWithOverwrite, /* 覆盖写(任务通知代替消息队列) */
eSetValueWithoutOverwrite /* 不覆盖写(任务通知代替消息队列) */
} eNotifyAction;
③发送消息函数xTaskNotify。xTaskNotify是个宏定义,调用xTaskGenericNotify。
#define xTaskNotify( xTaskToNotify, ulValue, eAction ) \
xTaskGenericNotify( ( xTaskToNotify ), ( ulValue ), ( eAction ), NULL )
/*
**参数1:任务控制块
**参数2:数据
**参数3:作为消息队列,只能eSetValueWithOverwrite和eSetValueWithoutOverwrite,如果使用eSetValueWithOverwrite将发送永远不会失败。
**参数4:更新以前通知值到参数4
*/
BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify,
uint32_t ulValue,
eNotifyAction eAction,
uint32_t *pulPreviousNotificationValue )
④接收消息函数xTaskNotifyWait
/*
**参数1:进入时清除的位
**参数2:退出时清除的位
**参数3:通知值
**参数4:等待时间
*/
BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry,
uint32_t ulBitsToClearOnExit,
uint32_t *pulNotificationValue,
TickType_t xTicksToWait )
2、 创建任务
void m_create_task_notify1(void)
{
BaseType_t xReturn = pdPASS;
xReturn = xTaskCreate((TaskFunction_t )Receive1_Task,
(const char* )"Receive1_Task",
(uint16_t )512,
(void* )NULL,
(UBaseType_t )2,
(TaskHandle_t* )&Receive1_Task_Handle);
if(pdPASS == xReturn)
LOG_BLE("Receive1_Task create ok\n");
xReturn = xTaskCreate((TaskFunction_t )Receive2_Task,
(const char* )"Receive2_Task",
(uint16_t )512,
(void* )NULL,
(UBaseType_t )3,
(TaskHandle_t* )&Receive2_Task_Handle);
if(pdPASS == xReturn)
LOG_BLE("Receive2_Task create ok\n");
xReturn = xTaskCreate((TaskFunction_t )Send_Task,
(const char* )"Send_Task",
(uint16_t )512,
(void* )NULL,
(UBaseType_t )4,
(TaskHandle_t* )&Send_Task_Handle);
if(pdPASS == xReturn)
LOG_BLE("Send_Task create ok\n");
}
3、 编写内存的测试任务入口函数
#include "limits.h"
//任务通知代替消息队列
#ifndef TAG_BLE
#define LOG_BLE(...)
#endif
static TaskHandle_t Receive1_Task_Handle = NULL;
static TaskHandle_t Receive2_Task_Handle = NULL;
static TaskHandle_t Send_Task_Handle = NULL;
#define USE_CHAR 1 /* 测试字符串的时候配置为1 测试变量配置为0*/
static void Receive1_Task(void* parameter)
{
BaseType_t xReturn = pdTRUE;
#if USE_CHAR
char *r_char;
#else
uint32_t r_num;
#endif
while (1)
{
xReturn=xTaskNotifyWait(0x0,
ULONG_MAX,
#if USE_CHAR
(uint32_t *)&r_char,
#else
&r_num,
#endif
portMAX_DELAY);
if( pdTRUE == xReturn )
#if USE_CHAR
LOG_BLE("Receive1_Task string:%s \n",r_char);
#else
LOG_BLE("Receive1_Task value:%d \n",r_num);
#endif
TOGGLE_LED13();
}
}
static void Receive2_Task(void* parameter)
{
BaseType_t xReturn = pdTRUE;
#if USE_CHAR
char *r_char;
#else
uint32_t r_num;
#endif
while (1)
{
xReturn=xTaskNotifyWait(0x0,
ULONG_MAX,
#if USE_CHAR
(uint32_t *)&r_char,
#else
&r_num,
#endif
portMAX_DELAY);
if( pdTRUE == xReturn )
#if USE_CHAR
LOG_BLE("Receive2_Task string:%s \n",r_char);
#else
LOG_BLE("Receive2_Task value:%d \n",r_num);
#endif
TOGGLE_LED14();
}
}
static void Send_Task(void* parameter)
{
BaseType_t xReturn = pdPASS;
#if USE_CHAR
char test_str1[] = "this is a mail test 1";
char test_str2[] = "this is a mail test 2";
#else
uint32_t send1 = 1;
uint32_t send2 = 2;
#endif
uint8_t button1_sta=0;
uint8_t button2_sta=0;
while (1)
{
if( READ_BUTTON1_P11() == BUTTON_PUSH )
{
if ( 0 == button1_sta)
{
button1_sta = 1;
//xTaskGenericNotify( ( xTaskToNotify ), ( ulValue ), ( eAction ), NULL )
xReturn = xTaskNotify( Receive1_Task_Handle,
#if USE_CHAR
(uint32_t)&test_str1,
#else
send1,
#endif
eSetValueWithOverwrite );
if( xReturn == pdPASS )
LOG_BLE("Receive1_Task_Handle task notify send ok\n");
}
} else
{
button1_sta = 0;
}
if( READ_BUTTON2_P12() == BUTTON_PUSH )
{
if (0 == button2_sta)
{
button2_sta = 1;
xReturn = xTaskNotify( Receive2_Task_Handle,
#if USE_CHAR
(uint32_t)&test_str2,
#else
send2,
#endif
eSetValueWithOverwrite );
if( xReturn == pdPASS )
LOG_BLE("Receive2_Task_Handle task notify send ok\n");
}
} else
{
button2_sta = 0;
}
vTaskDelay(20);
}
}
实验说明和现象
当USE_CHAR为1时,任务通知传输的是指针地址。
当USE_CHAR为0时,任务通知传输的是变量(变量最大为uin32_t)。