FreeRTOS(三)

news2025/1/9 14:22:16

第二部分 事件组

一、事件组的简介

1、事件

事件是一种实现任务间通信的机制,主要用于实现多任务间的同步,但事件通信只能是事件类型的通信,无数据传输。其实事件组的本质就是一个整数(16/32位)。可以是一个事件发生唤醒一个任务,或者多个事件唤醒一个或多个任务。

2、与队列/信号量的区别:

①信号量/队列当事件发生时只去唤醒一个任务,而事件组可唤醒多个任务,起到一个广播的作用。 ②信号量/队列是一个消耗性资源,即数据读走了就减少,而事件组可以选择清除事件也可以选择保留事件。 ③事件组只能是起到一个同步的作用,并不能传递数据。 ④事件组可以实现多个任务之间的同步,队列/信号量则只能是两个任务之间的同步。

3、事件组

1)整数的位数: 如果宏configUSE_16_BIT_TICKs = 0,那么这个整数是32位的,其中⽤低24位来表示事件组,代表24 个事件,剩余8位用于管理事件。 如果宏configUSE_16_BIT_TICKs = 1,那么这个整数是16位的,其中⽤低8位来表示事件组,代表8个事 件。

2)每⼀位事件的含义由我们自己定义。

3)这些位,值为1表示事件发生了,值为0表示事件没发⽣。

4)⼀个或多个任务、ISR都可以写这些位。

5)⼀个或多个任务可以等待某⼀位、某几个位。

特点

①与信号量不同设置,事件组不会阻塞,多个任务设置同一时间等于设置一次。

②支持事件超时等待机制,等待该事物类型的任务会进行阻塞态

③逻辑与:任务所期望的事件全部发生,任务才能被唤醒

逻辑或:任务所期望的事件只要有任意一个事件发生,任务即可被唤醒。

全局变量的区别

1.全局变量使用在操作系统中存在被多个任务同时读写的风险,则事件组它会直接禁止任务调度来规避风险。 2.使用全局变量需要自己去实现阻塞机制(成本太高)。 3.使用事件组能更方便的实现多任务之间的同步。

二、API函数

接口函数函数功能
xEventGroupCreate()动态创建事件组
xEventGroupSetBits()事件组置位函数
xEventGroupWaitBits()等待事件函数
EventGroupHandle_t()事件组结构体
EventGroupHandle_t
xEventGroupCreate

分三步:①为事件组结构体分配内存

②初始化事件组

③初始化等待链表

xEventGroupSetBits()

xEventGroupWaitBits

 

 

第三部分 软件定时器

一、简介

1、硬、软定时器

硬件定时器:由外部晶振提供时钟,定时精准,精度可以达到微秒级。不仅具有定时功能,还可以输出PWM,输入捕获等高级功能,当时间到达会触发一次中断。

软件定时器:基于一个守护任务,可以被其他中断或优先级比它高的任务打断,且软件定时器的精度是基于系统时钟SysTick的,一般达不到微秒级别。只能用来定时,每当时间到达会执行回调函数。

2、为何使用软件定时器

硬件定时器数量有限,而且使用定时的高级功能一般不会用来定时,但是实际上需要很多定时器来采集数据,上传数据等,所以我们就有了软件定时器,只要内存足够可以创建无数个软件定时器(一个软件定时器只需要一个定时器结构体的内存,还需要两条定时器链表,一个队列)。

软件定时器适合于对定时器精度要求不高的周期性任务

二、API函数

接口函数函数功能
tmrTimerControl定时器结构体
xTimerCreate()创建定时器
xTimerStart()启动定时器
xTimerStop()停止定时器
xTimerDelete()删除定时器
1、tmrTimerControl

(定时器结构体)

(1)定时器周期

单次定时:像闹钟一样只执行一次,时间一到事情做完定时器就停止运行;

周期定时:比如每隔20s触发一次,这就是周期执行。

(2)回调函数

每个定时器都由用户指定一个回调函数(功能由用户自己实现),每当定时器超时,守护任务则会去调用该定时器的回调函数

typedef void (* TimerCallbackFunction_t)( TimerHandle_t xTimer );

(3)定时器的状态

定时器活跃:定时器并不是一被创建就开始定时,与硬件定时器一样需要一个启动的命令(当前任务通过消息队列发送给守护任务),则定时器才会被挂入定时器链表,则处于活跃态,假设一个定时器是单次定时,在一次定时之后,则定时器会被移出定时器链表,所以判断一个定时器是否在活跃态,就是判断定时器是否在定时器链表中(如果在说明该定时器在参与定时)。

(4)软件定时器的守护任务

通过一个prvTimerTask任务来管理软件定时器,这个任务也叫“守护任务”。在启动调度器时自动创建的,以满足用户定时的需要。

需要在config文件中将configUSE_TIMERS设置为1时,在启用调度器时自动创建守护任务。

(5)定时器命令队列

任务和守护任务之间通过消息队列,守护任务创建完成后将会进入阻塞状态,等待用户程序发起定时器启动命令。其阻塞时间为定时器定时时间。

2、xTimerCreate()

第一次创建定时器需要初始化两条定时器链表(一条正常,一条超时),并创建一个消息队列,以上三者是软件定时器运行起来的基本配置。

守护任务:如果将宏configUSE_TIMERS配置为1则默认使用定时器,回创建一个定时器的守护任务。

3、xTimerStart()
定时器命令ID:

ID号-2~-1:直接调用用户指定的函数在守护任务执行前

ID号0~5:定时器的启动、复位、停止、更改周期、删除命令

ID号6~9:中断版的定时器的启动、复位、停止、更改周期命令

作用:将定时器信息打包发送给定时器信息队列等待守护任务读取信息并处理。

4、xTimerStop()

不难发现他的内部函数还是那个,只是执行命令不同。

5、xTimerDelete()

三、运行机制

(1)创建定时器--创建定时器控制块

用户程序调用定时器创建函数,给出定时时间

SysTick定时器常被用来作为软件定时器的时钟源,1s节拍1000次,1次就是1ms

(2)插入列表

根据定时时间长短:以升序方式插入链表中。

有两个链表:一个是创建时插入表,另一个是溢出时插入表。

xTimeNow:这个是SYSTIC的计数值。

XTicksToWait:xTimeNow+定时时间。

(3)启动定时器

当⽤户任务发送定时器启动命令后,定时器的守护任务函数将会执⾏。在任务函数中定义了⼀个全

局变量并初始化为0,⽤来保存上次定时器时间到的SYSTICK的值。

然后,⽐较全局变量和当前xTimeNow的值,如果xTimeNow<上次SYSTICK,则表明SYSTICK溢

出,那么将会把第⼀张链表上的定时器移到第⼆张链表中。

如果系统节拍计数器没有溢出,⽐较xTimeNow 和 xTickToWait的值,当xTimeNow >=

xTickToWait时,说明定时器时间到,调⽤回调函数。

如果xTimeNow <xTickToWait,定时器任务阻塞,阻塞时间为:xTickToWait - xTimeNow时。

以上是目前我对FreeRTOS的理解,后续如果对这块有更深理解会继续更新,如果有错误的地方可以交流。

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

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

相关文章

[医学分割大模型系列] (3) SAM-Med3D 分割大模型详解

[医学分割大模型系列] -3- SAM-Med3D 分割大模型解析 1. 特点2. 背景3. 训练数据集3.1 数据集收集3.2 数据清洗3.3 模型微调数据集 4. 模型结构4.1 3D Image Encoder4.2 3D Prompt Encoder4.3 3D mask Decoder4.4 模型权重 5. 评估5.1 评估数据集5.2 Quantitative Evaluation5.…

C#_事件_多线程(基础)

文章目录 事件通过事件使用委托 多线程(基础)进程:线程: 多线程线程生命周期主线程Thread 类中的属性和方法创建线程管理线程销毁线程 昨天习题答案 事件 事件&#xff08;Event&#xff09;本质上来讲是一种特殊的多播委托&#xff0c;只能从声明它的类中进行调用,基本上说是…

【python从入门到精通】-- 第二战:注释和有关量的解释

&#x1f308; 个人主页&#xff1a;白子寰 &#x1f525; 分类专栏&#xff1a;python从入门到精通&#xff0c;魔法指针&#xff0c;进阶C&#xff0c;C语言&#xff0c;C语言题集&#xff0c;C语言实现游戏&#x1f448; 希望得到您的订阅和支持~ &#x1f4a1; 坚持创作博文…

体育赛事直播源码是什么?四种适用场景及盈利模式

体育直播系统源码是指已经编写好的程序代码&#xff0c;用于搭建体育赛事直播软件平台。由于源码已经开发&#xff0c;并且源码可以被复制并多次使用&#xff0c;不需要从头开始开发&#xff0c;只需根据需求进行适当的修改和定制&#xff0c;因此可以大大加快上线速度&#xf…

应用层协议 - HTTP

文章目录 目录 文章目录 前言 1 . 应用层概要 2. WWW 2.1 互联网的蓬勃发展 2.2 WWW基本概念 2.3 URI 3 . HTTP 3.1 工作过程 3.2 HTTP协议格式 3.3 HTTP请求 3.3.1 URL基本格式 3.3.2 认识方法 get方法 post方法 其他方法 3.3.2 认识请求报头 3.3.3 认识请…

36.网络游戏逆向分析与漏洞攻防-游戏网络通信数据解析-数据解码器的实现

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 如果看不懂、不知道现在做的什么&#xff0c;那就跟着做完看效果 内容参考于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;35.登录成功数据…

2024年【安全员-C证】考试及安全员-C证考试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 安全员-C证考试根据新安全员-C证考试大纲要求&#xff0c;安全生产模拟考试一点通将安全员-C证模拟考试试题进行汇编&#xff0c;组成一套安全员-C证全真模拟考试试题&#xff0c;学员可通过安全员-C证考试题全真模拟…

Git基础(25):Cherry Pick合并指定commit id的提交

文章目录 前言指定commit id合并使用TortoiseGit执行cherry-pick命令 前言 开发中&#xff0c;我们会存在多个分支开发的情况&#xff0c;比如dev&#xff0c;test, prod分支&#xff0c;dev分支在开发新功能&#xff0c;prod作为生产分支已发布。如果某个时候&#xff0c;我们…

AGI争论燃爆!奥特曼、马斯克、杨立坤、Hinton一众大佬关于“AGI何时降临?”的讨论

随着Sora、Claude 3的亮相以及GPT-5的预告&#xff0c;一个激动人心的话题不断被提起&#xff1a;如果存在一种智能能够超越人类&#xff0c;那么世界将会变成什么样子&#xff1f; 更引人注目的问题是&#xff0c;我们究竟能在何时迎来这样的“超级AI”&#xff1f; GPT-3.5…

Hudi部署

目录 前言 Hudi的介绍 一、Hudi是什么&#xff1f; 二、Hudi的特点功能和优势 三、Hudi的使用场景 Hudi的搭建部署 一、准备 二、搭建 1&#xff09;搭建JAVA环境和Hadoop环境 2&#xff09;部署zookeeper 3&#xff09;部署Spark on yarn 4&#xff09;部署maven环…

Avalonia11.0.2+.Net6.0支持多语言,国际化

Avalonia11.0.2+.Net6.0支持多语言,国际化 操作系统项目结构最终效果具体实现安装Prism.Avalonia准备多语言文件语言资源加载类界面标记扩展类界面中使用国际化VM具体实现VM里面使用多语言方法操作系统 项目结构 最

【前端Vue】Vue3+Pinia小兔鲜电商项目第3篇:静态结构搭建和分类实现,1. 整体结构创建【附代码文档】

Vue3ElementPlusPinia开发小兔鲜电商项目完整教程&#xff08;附代码资料&#xff09;主要内容讲述&#xff1a;认识Vue3&#xff0c;使用create-vue搭建Vue3项目1. Vue3组合式API体验,2. Vue3更多的优势,1. 认识create-vue,2. 使用create-vue创建项目,1. setup选项的写法和执行…

007 日期类型相关工具类

推荐一篇文章 http://t.csdnimg.cn/72F7Jhttp://t.csdnimg.cn/72F7J

【TB作品】430单片机,单片机串口多功能通信,Proteus仿真

文章目录 题目功能仿真图程序介绍代码、仿真、原理图、PCB 题目 60、单片机串口多功能通信 基本要求: 设计一串口通信程序,波特率38400,通过RS232与PC机通信。 自动循环发送数据串(设计在程序中) 接收并存储和显示该数据串 在发送端定义10个ASCII码键0-9 按键发送单字节,PC机接…

uboot - pinctrl - FPGA回片前测试阶段 - 设置GPIO引脚复用失败

问题描述 pinctrl设置引脚复用失败&#xff0c;没有调用到controller中的set_groups_function函数。 问题定位 pinctrl如何注册dm节点如何进行设备树中各个设备节点下的复用配置为什么没调用到控制器实现的set_groups_function函数 &gpio0 {status "okay";p…

数据结构进阶篇 之 【二叉树】详细概念讲解(带你认识何为二叉树及其性质)

有朋自远方来&#xff0c;必先苦其心志&#xff0c;劳其筋骨&#xff0c;饿其体肤&#xff0c;空乏其身&#xff0c;鞭数十&#xff0c;驱之别院 一、二叉树 1、二叉树的概念 1.1 二叉树中组分构成名词概念 1.2 二叉树的结构概念 1.3 特殊的二叉树 2、二叉树的存储结构 …

c语言--实用调试技巧

1什么是bug 2调试是什么&#xff0c;有多重要&#xff1f; 3debug与release 4windows环境调试简绍 5一些调试的实例 6如何写出好的代码&#xff08;便于调试&#xff09; 7编程常见错误 1什么是bug 导致计算机出现问题就叫bug 2调试是什么&#xff0c;有多重要&#x…

4.线性数据结构——1.vector弥补数组的缺陷及其底层逻辑

数组的缺陷 数组在定义时大小固定&#xff0c;不能改变如果要定义在main内部&#xff0c;数组大小不能超过一百万&#xff08;6个0&#xff09;&#xff0c;超过需要定义为全局变量 定义在main内部&#xff0c;数组创建在内存的栈中&#xff0c;作为局部变量&#xff0c;但栈的…

基于stm32与TJC3224T124_011串口屏的PID调参器(附完整工程)

电赛在即&#xff0c;每次比赛调PID都是一件比较繁琐的事。每次都要在程序中改完再烧录到板子上&#xff0c;特别耗时。正好最近发现实验室的一块串口屏比较好玩。 于是就做了这个调PID的东西。它可以通过串口直接修改PID的值&#xff0c;从而达到快速调PID的目的。下面我将完整…

c++初阶------c++代码模块

作者前言 &#x1f382; ✨✨✨✨✨✨&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f382; ​&#x1f382; 作者介绍&#xff1a; &#x1f382;&#x1f382; &#x1f382; &#x1f389;&#x1f389;&#x1f389…