FreeRTOS【16】直达任务通知使用

1.开发背景

        直达任务通知,FreeRTOS 的线程任务提供的接口,可以用作线程唤醒,或者是传递数据,因为是基于线程本身的操作,是轻量级,速度响应更快,适合小内存芯片使用。

        事实上本人使用得比较少,常用的项目内存都比较多,对响应时间也没有特别苛刻,需要快速响应的最好还是硬实时中断。直达任务通知实际上操作的都是一个 32bit 的数据,操作的类型有5 种,如下。

/* Actions that can be performed when vTaskNotify() is called. */
typedef enum
{
	eNoAction = 0,				/* Notify the task without updating its notify value. */
	eSetBits,					/* Set bits in the task's notification value. */
	eIncrement,					/* Increment the task's notification value. */
	eSetValueWithOverwrite,		/* Set the task's notification value to a specific value even if the previous value has not yet been read by the task. */
	eSetValueWithoutOverwrite	/* Set the task's notification value if the previous value has been read by the task. */
} eNotifyAction;

2.开发需求

设计实验:

        创建 2 个线程,一个线程等待唤醒,另一个线程则是通过不同的方式定时唤醒

3.开发环境

        window10 + MDK + STM32F429 + FreeRTOS10.3.1

4.实现步骤

4.1 实现编码

xTaskNotifyWait 接收需要注意的参数是

ulBitsToClearOnEntry        写入 0xFFFFFFFF 在调用前清除所有位

ulBitsToClearOnExit          写入 0xFFFFFFFF 在成功触发后清除所有位

#include "appTest.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "mspDwt.h"
#include "mspGpio.h"
#include "mspExti.h"

#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "stream_buffer.h"
#include "event_groups.h"

#include "appLog.h"

typedef struct
{
    /* 任务线程 */
    TaskHandle_t task1;     // 线程
    TaskHandle_t task2;     // 线程
    
}Ctrl_t;

/* 文件指针 */
static Ctrl_t s_ctrl = {0};
static Ctrl_t *p = &s_ctrl;
static void Task1(void *pvParameters);
static void Task2(void *pvParameters);

/* 接收线程 */
static void Task1(void *pvParameters)
{
    vTaskDelay(100);
    
    /* 唤醒 */
    vTaskDelay(100);
    xTaskNotifyGive(p->task2);
    Log_Debug("%s xTaskNotifyGive\r\n", __func__);
    
    /* 唤醒 */
    vTaskDelay(100);
    xTaskNotify(p->task2, 0, eNoAction);
    Log_Debug("%s xTaskNotify eNoAction\r\n", __func__);
    
    /* 传递数据 */
    vTaskDelay(100);
    unsigned int value = 0x12345678;
    xTaskNotify(p->task2, value, eSetValueWithoutOverwrite);
    Log_Debug("%s xTaskNotify eSetValueWithoutOverwrite\r\n", __func__);
    xTaskNotify(p->task2, value << 4, eSetValueWithOverwrite);
    Log_Debug("%s xTaskNotify eSetValueWithOverwrite\r\n", __func__);
    
    /* 数据自增 */
    vTaskDelay(100);
    xTaskNotify(p->task2, 0, eIncrement);
    Log_Debug("%s xTaskNotify eIncrement\r\n", __func__);
    
    /* 修改部分位 */
    vTaskDelay(100);
    xTaskNotify(p->task2, 0xAB00, eSetBits);
    Log_Debug("%s xTaskNotify eSetBits\r\n", __func__);
    
    for ( ; ; )
    {
        vTaskDelay(1000);
    }
}

/* 发送线程 */
static void Task2(void *pvParameters)
{
    vTaskDelay(100);
    
    /* 等待唤醒 */
    ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
    Log_Debug("%s ulTaskNotifyTake OK\r\n", __func__);
    
    /* 等待唤醒 */
    ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
    Log_Debug("%s ulTaskNotifyTake OK\r\n", __func__);
    
    for ( ; ; )
    {
        /* 等待接收数据 */
        unsigned int value = 0;
        xTaskNotifyWait(0xFFFFFFFF, 0xFFFFFFFF, &value, portMAX_DELAY);
        Log_Debug("%s xTaskNotifyWait OK, value = 0x%.8X\r\n", __func__, value);
        vTaskDelay(10);
    }
}

/* 测试初始化 */
void aTest_Init(void)
{
    /* 创建动态任务 */
    xTaskCreate(Task1, "Task1", 500, NULL, 5, &p->task1);
    xTaskCreate(Task2, "Task2", 500, NULL, 5, &p->task2);
}

/* Key2 PC13   Key0 PH3 Key1 PH2 */
void Exti13_TriggerInterrupt(void)
{
    mspExti_Close(13);
    if (mspGpio_GetInput("PC13") == 0)
    {
        
    }
}

4.2 结果显示

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值