当前位置: 首页 > article >正文

FreeRTOS中任务通知的使用

目录

  • 0x01 任务通知介绍
  • 0x02 示例代码

0x01 任务通知介绍

简单举个例子:

例如任务一用于获取数据,任务二用于处理数据。

但这其中存在一个先后关系:必须等到任务一获取完了数据,任务二才能开始工作,你会如何选择何种实现方式呢?

未引入操作系统时,轮询系统会按照代码顺序执行,触发中断时,你可以通过设置一个获取原始数据的函数完成的全局变量作为标志位是否为1来判断是否完成,如果完成则开始执行数据处理任务,否则就等下一轮。
在这里插入图片描述

引入了操作系统后,可以通过二进制信号量的方式进行PV原子操作,这样一来便可以确保 任务一完成后,任务二才能执行

用两份伪代码的方式来描述一下:

任务1-获取数据:
	······
	······
while(数据没获取完)
	获取数据;

V(muttex)//数据获取完了,释放信号量
	······
	······
任务2-处理数据:
	······
	······
while(P(muttex))//获取不到信号量会被阻塞
	静静等待;

处理数据//得到信号量了跳出循环,可以开始工作
	······
	······

很通俗易懂,是一个比较简单的生产消费者模型。

这个和轮询系统的区别就是,引入操作系统可以提高系统的实时性。在轮询系统中,MCU需要不断的去检查标志位的值是否满足条件,这会导致浪费一些资源在这个步骤上。而通过PV操作来获取信号量消耗的资源较少,并且此时任务还是处在被挂起的状态,相比起来是不怎么耗费资源的。相比使用全局变量标志位的方式而言,使用二进制信号量所耗费的资源往往可以接受,并且在获取到信号量的瞬间任务便可以开始工作,而在轮询系统中还需要等到其他代码执行完轮到函数2了,才可以开始执行。

0x02 示例代码

下面使用示例代码说明,使用FreeRTOS的软件定时器来为其发送任务通知,促使LED闪烁。

在收到任务通知时,LED会闪烁一下随后继续等待任务通知马,方可继续闪烁,否则将被阻塞进程。
main.c

#include "tasks.h"  
#include "stdio.h"  

// 等待任务通知的任务
void vHandlerTask( void *pvParameters )
{
	while(1)
	{
		if(ulTaskNotifyTake(pdTRUE, xMaxExpectedBlockTime));//未收到任务通知会被阻塞
			LED_Blink;
	}
}

// 软件定时器回调函数  
void vTimerCallback(TimerHandle_t xTimer) 
{  
    if (xHandlerTaskHandle != NULL) {  
    	// 发送任务通知到vHandlerTask  
        xTaskNotifyGive(xHandlerTaskHandle);  
    }  
}  
  
// 设置并启动软件定时器  
void vStartTimer(void) 
{  
    const TickType_t xTimerPeriod = pdMS_TO_TICKS(1000); // 定时器周期为1000ms(1秒)  
  
    // 创建定时器  
    TimerHandle_t xTimer = xTimerCreate("Timer",  
                                        xTimerPeriod,  
                                        pdTRUE,  
                                        (void *) 0,  
                                        vTimerCallback);  
}  

http://www.kler.cn/a/287272.html

相关文章:

  • vue集成高德地图API实现坐标拾取功能
  • 双向耦合粒子追踪稳态求解器找到未定义的值?
  • LINUX编译LibreOffice
  • docker 基础语法学习,K8s基础语法学习,零基础学习
  • 如何在linux系统上完成定时开机和更新github端口的任务
  • vue项目配置多语言
  • 两句话解决ChatGPT 502 Bad Gateway问题
  • 前后端分离项目遇到的跨域问题解决方案(后端为主)
  • uniapp按钮点击过快导致请求数据混乱
  • 【学习笔记】卫星通信NTN 3GPP标准化进展分析(五)- 3GPP Release19 研究计划
  • 一图打尽C++内存分区(分段)
  • 内核开发具有哪些特点?大致流程是怎样的?
  • <C++> 红黑树
  • golang make 函数的三个参数分别有什么作用
  • 峟思大坝安全监测系统:科技筑牢工程稳定的基石
  • TCP ISO/OSI模型
  • 开启ROS 2中的geometry坐标模拟展示
  • SQLi-LABS靶场56-60通过攻略
  • [Python]之深拷贝与浅拷贝
  • Flask之Hello world 详解
  • 【补-办公室】拟批语的区别
  • 重构贪心算法(二)
  • 12大常用自动化测试工具,请记得转发收藏!
  • Leetcode 3277. Maximum XOR Score Subarray Queries
  • PostgreSQL LIMIT 子句的使用与优化
  • Jenkins版本升级