FreeRTOS学习--53讲 任务通知

news2025/1/12 9:54:49

任务通知定义

        a.任务通知像个用于通知的任务,由一个32位无符号整数和8位的通知状态组成,通过任务通知函数改写其他任务的32位无符号整数数据。

        b.改写方式如下(1.可以让这个整数加1: 模拟信号量 2. 设置该整数的指定的某些位:模拟事件组 3.直接选择覆盖或者不覆盖写入: 模拟消息队列)

        c.发送通知 可用于任务和中断服务函数中,接收通知 只能用于任务中

任务通知中,任务的三种状态

 a.未等待通知状态:就是任务的初始状态

b.等待通知状态:当任务在没有通知的时候接收通知时(也就是任务没有接收到通知的时候调用了接收通知的函数,则此时必定接收不到通知,把该任务标记为等待通知状态(去等别的任务发给我通知),任务进入阻塞态),这样做的用处是什么呢? 答:当另外一个任务发通知给该任务时,此时发现任务处于等待通知的状态,然后就可以即可把该任务唤醒。

c.等待接收通知状态:当有其他任务向任务发送通知,但任务还未接收这一通知的这段期间内(当其他任务给该任务发了通知,但是该任务还没有接收,则将该任务标记为等待接收通知状态),这样做的用处就是当该任务调用了接收通知的函数,发现自身的状态为等待接收通知状态,则不用进入阻塞,直接接收通知值。
 

发送任务通知的核心函数

发送通知函数:

xTaskNotify(xTaskToNotify,ulValue,eAction)                发送通知,带有通知值

参数:目标任务句柄,通知值,通知方式

xTaskNotifyAndQuery(xTaskToNotify,ulValue,eAction,pulPreviousNotifyValue)

  发送通知,带有通知值并且保留接收任务的原通知值

参数:目标任务句柄,通知值,通知方式,给原通知值保存的变量

xTaskNotifyGive(xTaskToNotify)                                发送通知,不带通知值

参数:目标句柄

接收任务通知函数

ulTaskNotifyTake()该函数就是专门服务与模拟二值信号量/计数型信号量的
ulTaskNotifyTake(xClearCountOnExit,xTicksToWait)
参数:
   参数1 在成功接收通知后,将通知值清零或减1(分别对应二值信号量,计数型信号量)
   参数2 阻塞等待任务通知值的最大时间
函数返回值 0:接收失败,非 0: 接收成功,返回任务通知的通知值(当前计数值)

xTaskNotifyWait()该函数一般用来模拟队列或者事件组的接收
xTaskNotifyWait( ulBitsToClearOnEntry,      等待前指定清零的任务通知通知值比特位(0则不清零)
                            ulBitsToClearOnExit,          成功等待后指定清零的任务通知通知值比特位
                            pulNotificationValue,           等待超时后任务通知的通知值
                            xTicksToWait)                      阻塞等待任务通知值的最大时间
返回值:pdTRUE 等待任务通知成功,pdFALSE 等待任务通知失败

任务通知模拟信号实验

//freertos_demo.c

#include "freertos_demo.h"
#include "./SYSTEM/usart/usart.h"
#include "./BSP/LED/led.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/KEY/key.h"
#include "./SYSTEM/delay/delay.h"
#include "./MALLOC/malloc.h"
/*FreeRTOS******************************************************************************/
#include "FreeRTOS.h"
#include "task.h"

/************************************************************************************/
/*FreeRTOS配置*/

/* START_TASK 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define START_TASK_PRIO      1
#define START_TASK_STACK_SIZE 128
TaskHandle_t  start_task_handler;
void start_task(void * pvParameters);

/* TASK1 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
  */
  
#define TASK1_PRIO      2
#define TASK1_STACK_SIZE 128
TaskHandle_t  task1_handler;
 void task1(void* pv);
 
 /* TASK2 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
  */
  
#define TASK2_PRIO      3
#define TASK2_STACK_SIZE 128
TaskHandle_t  task2_handler;
 void task2(void* pv);
/***************************************************************************************/


/**
 * @brief       FreeRTOS例程入口函数
 * @param       无
 * @retval      无
 */
void freertos_demo(void)
{    
    xTaskCreate((TaskFunction_t    )    start_task,         //创建开始任务
                (char*             )    "start_task", 
                (unsigned portSHORT)    START_TASK_STACK_SIZE, 
                (void *            )    NULL, 
                (portBASE_TYPE     )    START_TASK_PRIO, 
                (TaskHandle_t*     )    &start_task_handler );
    vTaskStartScheduler();
}

void start_task(void* pvPara)
{
    taskENTER_CRITICAL();         //进入临界区
    
    xTaskCreate((TaskFunction_t    )    task1,              //创建任务一
                (char*             )    "task1", 
                (unsigned portSHORT)    TASK1_STACK_SIZE, 
                (void *            )    NULL, 
                (portBASE_TYPE     )    TASK1_PRIO, 
                (TaskHandle_t*     )    &task1_handler );
                
    xTaskCreate((TaskFunction_t    )    task2,              //创建任务二
                (char*             )    "task2", 
                (unsigned portSHORT)    TASK2_STACK_SIZE, 
                (void *            )    NULL, 
                (portBASE_TYPE     )    TASK2_PRIO, 
                (TaskHandle_t*     )    &task2_handler );
                
    vTaskDelete(NULL);              //删除start_task任务
    taskEXIT_CRITICAL();            //退出临界区
}


//任务一 发送任务通知值
void task1(void* pv)
{
    uint8_t key = 0;
    printf("连接成功!\r\n");
    while(1)
    {
        key = key_scan(0);              
        if(key == KEY0_PRES)
        {
            printf("任务通知模拟二值信号量释放!!!\r\n");
            xTaskNotifyGive(task2_handler);     //发送通知值给任务二
        }
        vTaskDelay(500);
    }
}

//任务二 接收任务通知值
void task2(void* pv)
{
    uint32_t rev = 0;
    while(1)
    {
        rev = ulTaskNotifyTake(pdTRUE,portMAX_DELAY);//接收任务通知值,参数1是将通知值清零,参数2是阻塞时间;接收成功解除阻塞
        if(rev != 0)
        {
            printf("接收任务通知成功,模拟获取二值信号量!!\r\n");
        }
        
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++ 类和对象 (上)

类的引入: 由于C语言是面向过程的编程语言,我们在完成一件事的时候通常习惯将一件事拆分成一个一个小过程来实现,而到了C就习惯将一件事分成不同的模块,交给不同的对象来处理,每一个对象中承载着数据类型和函数。 &am…

网格布局(大练习)

最近对网格布局研究了一下,写了一个简单的demo。可以参考参考~ 网格基础布局:github地址 挤占网格布局:github地址 基础网站格局:github地址 复杂网站格局(方式一):github地址 复杂网站格局&am…

MySQL的高级SQL语句

目录 1.mysql高阶查询 select:显示表格中一个或数个字段的所有数据记录 distinct:不显示重复的数据记录 where:有条件查询 AND OR :且 或 in:显示已知值的数据记录 between:显示两个值范围内的数据记…

深入ArkUI:深入实战组件text和text input

文章目录 Text组件介绍Text组件的属性方法Text:文本显示组件4.3TextInput组件实战案例:图片宽度控制页面本文总结要点回顾在今天的课程中,我们将深入学习ArkUI提供的基础组件,着重探讨text和text input两个组件。 Text组件介绍 Text组件是一个用于显示文本的组件,其主要作…

SoniTranslate

示例效果 官方在线运行地址:https://huggingface.co/spaces/r3gm/SoniTranslate_translate_audio_of_a_video_content 环境配置 git clone --recurse-submodules https://github.com/R3gm/SoniTranslate.gitconda create -n soni python3.8conda activate sonipip…

解决Github无法上传>100M文件——只需两行代码

文章目录 合作推广,分享一个人工智能学习网站。计划系统性学习的同学可以了解下,点击助力博主脱贫( •̀ ω •́ )✧ 废话不多说,如果在githubpush文件太大时,会报错:this exceeds GitHub’s file size limit of 100.…

MySQL8.0聚合函数+over()函数

1、数据表内容为: CREATE TABLE chapter11 (shopname VARCHAR(255) NULL,sales VARCHAR(255) NULL,sale_date VARCHAR(255) NULL ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_0900_ai_ci;INSERT INTO chapter11 (shopname, sales, sale_date) VALUES(A…

基于YOLOv8的遥感SAR舰船小目标识别

💡💡💡本文摘要:基于YOLOv8的遥感SAR舰船小目标,阐述了整个数据制作和训练可视化过程 1.YOLOv8介绍 Ultralytics YOLOv8是Ultralytics公司开发的YOLO目标检测和图像分割模型的最新版本。YOLOv8是一种尖端的、最先进的…

1.2.0 IGP高级特性之FRR

理论部分参考文档:Segment Routing TI-LFA FRR保护技术 - 华为 一、快速重路由技术 FRR(Fast Reroute)快速重路由 实现备份链路的快速切换,也可以与BFD联动实现对故障的快速感知。 随着网络的不断发展,VoIP和在线视频等业务对实时性的要求越…

堪比Postman!这款IDEA插件真好用!

Postman是大家最常用的API调试工具,那么有没有一种方法可以不用手动写入接口到Postman,即可进行接口调试操作?今天给大家推荐一款IDEA插件:Apipost Helper,写完代码就可以调试接口并一键生成接口文档!而且还…

Arduino驱动VL6180X光学测距传感器(OLED显示)

Arduino驱动VL6180X光学测距传感器(OLED显示) 简介原理模块参数接线图代码结果 简介 VL6108X三合一光电模块,芯片内集成了IR VSEL(vertical-cavity surface-emitting laser)红外垂直腔面发射激光器光源、接近传感器、环境光传感器&#xff0…

《网络是怎样连接的》1.2、1.3、1.4节图表(自用)

图2.1:浏览器调用socket库中的解析器,向DNS服务器询问域名的ip地址 (图中的gethostbyname是解析器的名称;协议栈是操作系统的网络控制软件,也称协议驱动、TCP/IP驱动) 图2.2 DNS服务器根据客户端查询信息查…

解析Web自动化测试工具能做什么?

随着互联网的蓬勃发展,Web应用程序在我们生活和工作中扮演着愈发重要的角色。为确保这些Web应用程序的质量、稳定性和安全性,Web自动化测试工具应运而生。本文将介绍Web自动化测试工具的多重功能,以及它们如何在软件开发生命周期中发挥关键作…

分享一套超有价值的JAVA开源MES系统

商业开源的一套超有价值的JAVA制造执行MES系统源码 亲测 带本地部署搭建教程 教你如何在本地运行运行起来。 开发环境:jdk11tomcatmysql8springbootmaven 需要源码,私信我获取。 一、系统概述: MES制造执行系统,其定位于制造执…

OKCC语音机器人的人机耦合来啦

目前市场上语音机器人的外呼形式基本就分为三种,一种纯AI外呼,第二种也是目前主流的AI外呼转人工。那么第三种也可能是未来的一种趋势,人机耦合,或者也叫人机协同。 那么什么是人机耦合呢? 人机耦合是为真人坐席创造相…

springCould中的OpenFeign-从小白开始【6】

目录 1.简单介绍❤️❤️❤️ 2.能干嘛❤️❤️❤️ 3.简单入门 ❤️❤️❤️ 4.超时控制 ❤️❤️❤️ 5.日志打印❤️❤️❤️ 1.简单介绍❤️❤️❤️ OpenFeign是一个用于微服务架构中的声明式、模板化的HTTP客户端库。它简化了编写服务间通信的代码,使得开…

nrm的保姆级使用教程

📢 鸿蒙专栏:想学鸿蒙的,冲 📢 C语言专栏:想学C语言的,冲 📢 VUE专栏:想学VUE的,冲这里 📢 CSS专栏:想学CSS的,冲这里 &#x1f4…

Linux开发工具——gdb篇

Linux下调试工具——gdb 文章目录 makefile自动化构建工具 gdb背景 gdb的使用 常用命令 总结 前言: 编写代码我们使用vim,编译代码我们使用gcc/g,但是我们,不能保证代码没问题,所以调试是必不可少的。与gcc/vim一样&…

Oracle 拼接字符串

语法 使用||拼接如果内容中有单引号,则可在该单引号前面再加一个单引号进行转义 例子 比如有一个业务是根据需要生成多条插入语句 select insert into des_account_des_role(des_account_id, roles_id) values( || id || , || (select id from des_role where wo…

统一入口,全面提升工作效率,WorkPlus超级APP引领数字化办公新潮流

在数字化办公的时代,企业往往面临着多个应用管理的挑战。员工需要在众多应用之间切换,记忆不同的登录凭证,这不仅分散了注意力,还降低了工作效率。为了应对这一问题,企业需要一站式的解决方案,通过整合繁杂…