(九)任务通知

一、概念

(1)FreeRTOS从V8.2.0版本开始提供任务通知
(2)每个任务都有一个32位的通知值
(3)发送任务通知的几种情况
3.1 发送通知给任务,如果有通知未读,不覆盖通知值
3.2 发送通知给任务,直接覆盖通知值
3.3 发送通知给任务,设置通知值的一个或多个位,可以当做事件组来使用
3.4 发送通知给任务,递增通知值,可以当做计数信号量来使用
(4)只能有一个任务接收通知消息
(5)只有等待通知的任务可以被阻塞
(6)无需创建,属于任务控制块中的变量,创建任务时即创建完成
(7)中断/任务均能发送通知
(8)只有任务可以等待通知,而不允许中断中等待通知
(9)相较于传统方式性能快
(10)使用时需要使能configUSE_TASK_NOTIFICATIONS宏定义

二、使用函数

(1)xTaskNotifyGive发送通知,没有通知值(信号量类型)
(2)xTaskNotify发送通知,带通知值
(3)xTaskNotifyAndQuery发送通知,带通知值,并返回原通知值
(4)ulTaskNotifyTake等待通知(信号量类型)
(5)xTaskNotifyWait等待通知
(6)vTaskNotifyGiveFromISR中断版本的xTaskNotifyGive
(7)xTaskNotifyAndQueryFromISR中断版本的xTaskNotifyAndQuery
(8)xTaskNotifyFromISR中断版本的ulTaskNotifyTake
(9)xTaskNotifyStateClear清除所有未读消息

三、代码示例

(1)任务通知代替消息队列

#include "FreeRTOS.h"
#include "task.h"
#include "led.h"
#include "limits.h"

static void task1(void* param);
static void task2(void* param);

static TaskHandle_t task1Handler;
static TaskHandle_t task2Handler;

int main()
{
    led_init();
    
    portENTER_CRITICAL();   //进入临界区
    
    BaseType_t xReturn;
    
    /******创建任务1*******/
    xReturn = xTaskCreate(task1,
                          "task1",
                          128,
                          NULL,
                          2,
                          &task1Handler);
    if(xReturn==pdTRUE){}
    
    /******创建任务2*******/
    xReturn = xTaskCreate(task2,
                          "task2",
                          128,
                          NULL,
                          2,
                          &task2Handler);
    if(xReturn==pdTRUE){}
                          
    portEXIT_CRITICAL();    //退出临界区
    
    vTaskStartScheduler();  //开启任务调度器
    
    while(1){  
    }
}

//发送消息
void task1(void* param)
{
    BaseType_t xReturn = pdPASS;
    uint32_t value1 = 1;
    uint32_t value2 = 2;
    
    while(1){
        xReturn = xTaskNotify(task2Handler,             //向哪个任务发送通知
                              value1,                   //发送的值
                              eSetValueWithOverwrite);  //写入值方式
        if(xReturn==pdTRUE){
            vTaskDelay(1000);
        }
            
        xReturn = xTaskNotify(task2Handler,             //向哪个任务发送通知
                              value2,                   //发送的值
                              eSetValueWithOverwrite);  //写入值方式
        if(xReturn==pdTRUE){
            vTaskDelay(1000);
        }
    }
}

//接收消息
void task2(void* param)
{
    BaseType_t xReturn;
    uint32_t recv;
    
    while(1){
        xReturn = xTaskNotifyWait(0x0,                  //进入时要清除的位
                             ULONG_MAX,             //退出时要清除的位,清除所有位
                             &recv,                  //接收的值
                             portMAX_DELAY);        //等待超时时间
    
        if(recv == 1 && xReturn==pdTRUE){
            open();
        }else if(recv == 2 && xReturn==pdTRUE){
            close();
        }
    }
}

(2)任务通知替换二值信号量

#include "FreeRTOS.h"
#include "task.h"
#include "led.h"
#include "limits.h"

static void task1(void* param);
static void task2(void* param);

static TaskHandle_t task1Handler;
static TaskHandle_t task2Handler;

int main()
{
    led_init();
    
    portENTER_CRITICAL();   //进入临界区
    
    BaseType_t xReturn;
    
    /******创建任务1*******/
    xReturn = xTaskCreate(task1,
                          "task1",
                          128,
                          NULL,
                          2,
                          &task1Handler);
    if(xReturn==pdTRUE){}
    
    /******创建任务2*******/
    xReturn = xTaskCreate(task2,
                          "task2",
                          128,
                          NULL,
                          2,
                          &task2Handler);
    if(xReturn==pdTRUE){}
                          
    portEXIT_CRITICAL();    //退出临界区
    
    vTaskStartScheduler();  //开启任务调度器
    
    while(1){  
    }
}

//发送消息
void task1(void* param)
{
    while(1){
        xTaskNotifyGive(task2Handler);
        vTaskDelay(500);
    }
}

//接收消息
void task2(void* param)
{
    static int ledcnt=0;
    
    while(1){
        ulTaskNotifyTake(pdTRUE,portMAX_DELAY);
        ledcnt=!ledcnt;
        if(ledcnt==1){
            open();
        }else if(ledcnt==0){
            close();
        }
    }
}

(3)任务通知代替计数信号量

#include "FreeRTOS.h"
#include "task.h"
#include "led.h"
#include "limits.h"

static void task1(void* param);
static void task2(void* param);

static TaskHandle_t task1Handler;
static TaskHandle_t task2Handler;

int main()
{
    led_init();
    
    portENTER_CRITICAL();   //进入临界区
    
    BaseType_t xReturn;
    
    /******创建任务1*******/
    xReturn = xTaskCreate(task1,
                          "task1",
                          128,
                          NULL,
                          2,
                          &task1Handler);
    if(xReturn==pdTRUE){}
    
    /******创建任务2*******/
    xReturn = xTaskCreate(task2,
                          "task2",
                          128,
                          NULL,
                          2,
                          &task2Handler);
    if(xReturn==pdTRUE){}
                          
    portEXIT_CRITICAL();    //退出临界区
    
    vTaskStartScheduler();  //开启任务调度器
    
    while(1){  
    }
}

//发送消息
void task1(void* param)
{
    while(1){
        xTaskNotifyGive(task2Handler);
        vTaskDelay(500);
    }
}

//接收消息
void task2(void* param)
{
    static int ledcnt=0;
    uint32_t retu=0;
    
    while(1){
        retu = ulTaskNotifyTake(pdFALSE,0);
        if(retu==1) ledcnt=!ledcnt;
        if(ledcnt==1){
            open();
        }else if(ledcnt==0){
            close();
        }
    }
}

(4)任务通知替代事件组

#include "FreeRTOS.h"
#include "task.h"
#include "led.h"
#include "limits.h"

static void task1(void* param);
static void task2(void* param);

static TaskHandle_t task1Handler;
static TaskHandle_t task2Handler;

#define EVENT1 (0x01<<1)
#define EVENT2 (0x01<<2)

int main()
{
    led_init();
    
    portENTER_CRITICAL();   //进入临界区
    
    BaseType_t xReturn;
    
    /******创建任务1*******/
    xReturn = xTaskCreate(task1,
                          "task1",
                          128,
                          NULL,
                          2,
                          &task1Handler);
    if(xReturn==pdTRUE){}
    
    /******创建任务2*******/
    xReturn = xTaskCreate(task2,
                          "task2",
                          128,
                          NULL,
                          2,
                          &task2Handler);
    if(xReturn==pdTRUE){}
                          
    portEXIT_CRITICAL();    //退出临界区
    
    vTaskStartScheduler();  //开启任务调度器
    
    while(1){  
    }
}

//发送消息
void task1(void* param)
{
    while(1){
        xTaskNotify(task2Handler,
                    EVENT1,
                    eSetBits);//设置任务通知对应位
        vTaskDelay(500);
        
        xTaskNotify(task2Handler,
                    EVENT2,
                    eSetBits);//设置任务通知对应位
        vTaskDelay(1000);
    }
}

//接收消息
void task2(void* param)
{    
    uint32_t recv;
    while(1){
        xTaskNotifyWait(0x0,
                        ULONG_MAX,
                        &recv,
                        portMAX_DELAY);
        if(recv == EVENT1){//事件或
            open();
        }else if(recv == EVENT2){
            close();
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/482399.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

体育竞赛成绩管理系统设计与实现|jsp+ Mysql+Java+ B/S结构(可运行源码+数据库+设计文档)

本项目包含可运行源码数据库LW&#xff0c;文末可获取本项目的所有资料。 推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 2024年56套包含java&#xff0c;…

什么是皮尔逊、斯佩尔曼和肯德尔相关性系数

代码实现&#xff1a; import numpy as np from scipy.stats import pearsonr, spearmanr,kendalltau #什么是皮尔逊、斯佩尔曼和肯德尔相关性系数 # 生成示例数据 x np.array([1, 2, 3, 4, 5]) y np.array([5, 6, 7, 8, 7])# 计算皮尔逊相关系数 pearson_coef, pearson_p …

计算机考研|几所性价比巨高的院校!必看

✅厦门大学 (985)&#xff1a;不歧视双非&#xff0c;全靠实力&#xff0c;校园环境还贼美 ✅重庆大学 (985)&#xff1a;信息公开透明&#xff0c;复试抽签 ✅吉林大学 (985)&#xff1a;不歧视双非&#xff0c;但信息公布比较慢&#xff0c;因为想把复复试的人都录取上 ✅…

仿牛客网开发笔记

用到Spring的 一些 核心技术 1 Spring Framework Spring Core IOC 、AOP > 管理对象的一种思想 IOC > 面向对象的管理思想 AOP > 面向切面的管理思想Spring Data Access 》访问数据库的功能 Transaction、Spring MyBatis Transaction 》管理事务Spring MyB…

Centos上安装Harbor并使用

harbor的安装与使用 Harbor介绍安装前的准备工作为Harbor自签发证书安装Harbor安装docker开启包转发功能和修改内核参数安装harbor扩展 Harbor 图像化界面使用说明测试使用harbor私有镜像仓库从harbor仓库下载镜像 Harbor介绍 容器应用的开发和运行离不开可靠的 镜像管理&…

探索超净实验室:高纯电子级PFA洗瓶特氟龙材质清洗瓶的特性

PFA洗瓶&#xff0c;实验中常用的清洗工具之一&#xff0c;是一个带有弯曲管状喷嘴的柔性瓶子&#xff0c;因此可以用手挤压瓶身以产生压力&#xff0c;迫使瓶内液体通过塑料管以单滴或窄流的形式流到需要清洁的表面。 ​ 由于需要多次挤压&#xff0c;瓶体要有良好的回弹性和…

动态规划——斐波那契问题(Java)

目录 什么是动态规划&#xff1f; 练习 练习1&#xff1a;斐波那契数 练习2&#xff1a;三步问题 练习3&#xff1a;使用最小花费爬楼梯 练习4&#xff1a;解码方法 什么是动态规划&#xff1f; 动态规划&#xff08;Dynamic Programming&#xff0c;DP&#xff09;&…

关于VS项目无法找到源文件或者,代码更改项目却不更改的问题

Studio\workShop\......\obj\Debug\net6.0\GraduationProjectEX.Shared.AssemblyInfo.cs”。 像上面这个&#xff0c;说无法找到源文件&#xff0c;然后我去目录找&#xff0c;果然是没有的&#xff0c;我的是依赖方面的错误&#xff0c;莫名其妙&#xff0c;因为我更改了项目…

超快的 AI 实时语音转文字,比 OpenAI 的 Whisper 快4倍 -- 开源项目 Faster Whisper

faster-whisper 这个项目是基于 OpenAI whisper 的模型&#xff0c;在上面的一个重写。 使用的是 CTranslate2 的这样的一个库&#xff0c;CTranslate2 是用于 Transformer 模型的一个快速推理引擎。 在相同精度的情况下&#xff0c;faster-whisper 的速度比 OpenAI whisper …

鸿蒙Harmony应用开发—ArkTS-if/else:条件渲染

ArkTS提供了渲染控制的能力。条件渲染可根据应用的不同状态&#xff0c;使用if、else和else if渲染对应状态下的UI内容。 说明&#xff1a; 从API version 9开始&#xff0c;该接口支持在ArkTS卡片中使用。 使用规则 支持if、else和else if语句。 if、else if后跟随的条件语句…

心脏滴血漏洞详解(CVE-2014-0160)

参考链接&#xff1a;心脏滴血漏洞利用&#xff08;CVE-2014-0160&#xff09;_cve-2014-0160漏洞禁用443端口-CSDN博客 目录 OpenSSL简介 漏洞原理 影响版本 漏洞复现 漏洞利用 修复方案 OpenSSL简介 OpenSSL是一个开放源代码的软件库包&#xff0c;提供了一组加密和认…

【leetcode热题】 位1的个数

编写一个函数&#xff0c;输入是一个无符号整数&#xff08;以二进制串的形式&#xff09;&#xff0c;返回其二进制表达式中数字位数为 1 的个数&#xff08;也被称为汉明重量&#xff09;。 提示&#xff1a; 请注意&#xff0c;在某些语言&#xff08;如 Java&#xff09;中…

【算法】回溯与深搜

方法论 1.构建决策树 2.设计代码&#xff1a;全局变量、dfs函数 3.剪枝&#xff0c;回溯 全排列 给定一个不含重复数字的整数数组 nums &#xff0c;返回其 所有可能的全排列 。可以 按任意顺序 返回答案。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff…

探索超融合服务器:是否助力企业飞跃数字化挑战?

在数字化不断深化的今天&#xff0c;企业面临着前所未有的转型压力和机遇。IT基础设施作为支撑企业运营的重要基石&#xff0c;其性能、效率及可管理性都直接关系到企业的竞争力。超融合服务器作为一种创新的IT架构&#xff0c;被许多业内专家视为应对现代业务挑战的有效手段。…

移动硬盘变NTFS无法访问:原因分析与数据恢复全攻略

一、遭遇困境&#xff1a;移动硬盘变NTFS打不开 在日常的数据存储与传输中&#xff0c;移动硬盘无疑是我们的得力助手。然而&#xff0c;当移动硬盘突然显示NTFS格式且无法打开时&#xff0c;这无疑给我们带来了巨大的困扰。面对这种突发情况&#xff0c;许多用户会感到焦虑和…

⾃定义类型:结构体

目录 1. 结构体类型的声明 1.1 结构体回顾 1.1.1 结构的声明 1.1.2 结构体变量的创建和初始化 1.2 结构的特殊声明 1.3 结构的⾃引⽤ 2. 结构体内存对⻬ 2.1 对⻬规则 2.2 为什么存在内存对⻬? 2.3 修改默认对⻬数 3. 结构体传参 4. 结构体实现位段 4.1 什么是位段…

二进制王国(蓝桥杯备赛)【sort/cmp的灵活应用】

二进制王国 题目链接 https://www.lanqiao.cn/problems/17035/learning/?contest_id177 题目描述 思路 这里就要灵活理解字典序排列&#xff0c;虽然string内置可以直接比较字符串字典序&#xff0c;但是在拼接时比较特殊&#xff0c;比如 11的字典序小于110&#xff0c;但…

故障诊断模型 | 基于图卷积网络的轴承故障诊断

文章目录 文章概述模型描述模型描述参考资料文章概述 故障诊断模型 | 基于图卷积网络的轴承故障诊断 模型描述 针对基于图卷积网络(GCN)的故障诊断方法大多默认节点间的权重相同、导致诊断精度较低与鲁棒性较差的问题,提出了一种基于欧式距离和余弦距离的 GCN 故障诊断方法…

HCIP实验02

实验步骤 1、R1和R2使用ppp链路之连&#xff0c;R2和R3把2条ppp链路捆绑为ppp直连 [R2]int Mp-group 0/0/0 [R2]int Serial 3/0/1 [R2-Serial3/0/1]ppp mp Mp-group 0/0/0 [R2-Serial3/0/1]int Serial 4/0/0 [R2-Serial4/0/0]ppp mp Mp-group 0/0/0 [R3]int Mp-group 0/0/…

代码随想录算法训练营 DAY 17 | 110.平衡二叉树 257.二叉树的所有路径 404.左叶子之和

110.平衡二叉树 平衡二叉树的定义&#xff1a;任何节点的左右子树高度差绝对值不超过1 空树也是AVL! 确定遍历顺序&#xff1a; 求高度用后序&#xff0c;求深度用前序。&#xff08;取决于需不需要从下往上返回结果&#xff09; 先判断它是不是平衡二叉树 如果是就返回 如…
最新文章