FreeRTOS之任务通知代替消息队列实验

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)。

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值