FreeRTOS 计数信号量

一个二值信号量被用于让任务和中断进行同步。整个执行流程可以描
述为:

1. 中断产生。
2. 中断服务例程启动,给出信号量以使延迟处理任务解除阻塞。
3. 当中断服务例程退出时,延迟处理任务得到执行。延迟处理任务做的第一件事便是
获取信号量。
4. 延迟处理任务完成中断事件处理后,试图再次获取信号量——如果此时信号量无效,
任务将切入阻塞待等待事件发生。
在中断以相对较慢的频率发生的情况下,上面描述的流程是足够而完美的。如果在
延迟处理任务完成上一个中断事件的处理之前,新的中断事件又发生了,等效于将新的
事件锁存在二值信号量中,使得延迟处理任务在处理完上一个事件之后,立即就可以处
理新的事件。也就是说,延迟处理任务在两次事件处理之间,不会有进入阻塞态的机会,
因为信号量中锁存有一个事件,所以当 xSempaphoreTake()调用时,信号量立即有效。
这种情形将在图 图 30 中进行展现。

在图 图 30 中可以看到,一个二值信号量最多只可以锁存一个中断事件。在锁存的事
件还未被处理之前,如果还有中断事件发生,那么后续发生的中断事件将会丢失。如果
用计数信号量代替二值信号量,那么,这种丢中断的情形将可以避免。
就如同我们可以把二值信号量看作是只有一个数据单元的队列一样,计数信号量可
以看作是深度大于 1 的队列。任务其实对队列中存储的具体数据并不感兴趣——其只关
心队列是空还是非空。
计数信号量每次被给出(Given),其队列中的另一个空间将会被使用。队列中的有
效数据单元个数就是信号量的”计数(Count)”值

计数信号量有以下两种典型用法:

1.事件计数
在这种用法中,每次事件发生时,中断服务例程都会“给出(Give)”信号量——信号
量在每次被给出时其计数值加 1。延迟处理任务每处理一个任务都会”获取(Take)”一次
信号量——信号量在每次被获取时其计数值减 1。信号量的计数值其实就是已发生事件
的数目与已处理事件的数目之间的差值。这种机制可以参考 图 31。
用于事件计数的计数信号量,在被创建时其计数值被初始化为 0。
2.资源管理
在这种用法中,信号量的计数值用于表示可用资源的数目。一个任务要获取资源的
控制权,其必须先获得信号量——使信号量的计数值减 1。当计数值减至 0,则表示没
有可用资源。当任务利用资源完成工作后,将给出(归还)信号量——使信号量的计数值
加 1。
用于资源管理的信号量,在创建时其计数值被初始化为可用资源总数。第四章涵盖
了使用信号量来管理资源。

xSemaphoreCreateCounting() API 函数
FreeRTOS 中所有种类的信号量句柄都由声明为 xSemaphoreHandle 类型的变量
保存。
信号量在使用前必须先被创建。使用 xSemaphoreCreateCounting() API 函数来创
建一个计数信号量。

xSemaphoreHandle xSemaphoreCreateCounting( unsigned portBASE_TYPE uxMaxCount,
unsigned portBASE_TYPE uxInitialCount );

uxMaxCount 最大计数值。如果把计数信号量类比于队列的话,uxMaxCount 值
就是队列的最大深度。
当此信号量用于对事件计数或锁存事件的话,uxMaxCount 就是可
锁存事件的最大数目。
当此信号量用于对一组资源的访问进行管理的话,uxMaxCount 应
当设置为所有可用资源的总数。
uxInitialCount 信号量的初始计数值。
当此信号量用于事件计数的话,uxInitialCount 应当设置为 0——因
为当信号量被创建时,还没有事件发生。
当 此 信 号 量 用 于 资 源 管 理 的 话 , uxInitialCount 应 当 等 于
uxMaxCount——因为当信号量被创建时,所有的资源都是可用的。
返回值 如果返回 NULL 值,表示堆上内存空间不足,所以 FreeRTOS 无法
为信号量结构分配内存导致信号量创建失败。第五章有提供更多的
内存管理方面的信息。
如果返回非 NULL 值,则表示信号量创建成功。此值应当被保存起
来作为这个的信号量的句柄。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【图像分割 2023】BRAU-Net++

【图像分割 2023】BRAU-Net 论文题目:BRAU-Net: U-Shaped Hybrid CNN-Transformer Network for Medical Image Segmentation 中文题目: 论文链接:[2401.00722] BRAU-Net: U-Shaped Hybrid CNN-Transformer Network for Medical Image Segment…

IDEA 推荐插件

grep-console 输出日志换颜色 MybatisLogFormat 直接复制mybatis的日志成完整的SQL SequenceDiagram 生成时序图

武器级工具包 Immunity Canvas 7.26安装使用体验

介绍: Immunity Canvas工具包有集成化、自动化、简单化的特点,大幅降低了攻击门槛。该工具是Immunity公司的一款商业级漏洞利用和渗透测试工具,包含了480多个以上的漏洞利用,该工具工具本来并不开源,但是在2021年Immu…

Pytorch学习04_Transforms的使用

Structure的使用 在Pycharm的左下角可以点开structure,查看一些模块内的函数定义,没有的话,去到设置里搜索“keymap”,搜索”sturcture“,可以找到对应的快捷键 查看图片 from PIL import Image from torchvision import transfo…

【AIGC】大语言模型

大型语言模型,也叫大语言模型、大模型(Large Language Model,LLM;Large Language Models,LLMs) 什么是大型语言模型 大型语言模型(LLM)是指具有数千亿(甚至更多&#xf…

springboot集成elk实现日志采集可视化

一、安装ELK 安装ELK组件请参考我这篇博客:windows下安装ELK(踩坑记录)_windows上安装elk教程-CSDN博客 这里不再重复赘述。 二、编写logstash配置 ELK组件均安装好并成功启动,进入到logstash组件下的config文件夹,创建logstash.conf配置…

Linux第一个小程序-进度条

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一、回车和换行 二、行缓冲区概念 三、倒计时 四、进度条代码 版本一: ​编辑 版本二: 总结 前言 世上有两种耀眼的光芒,一…

Vue2学习第二天

Vue2 学习第二天 1. 数据绑定 Vue 中有 2 种数据绑定的方式: 单向绑定(v-bind):数据只能从 data 流向页面。双向绑定(v-model):数据不仅能从 data 流向页面,还可以从页面流向 data。 备注: 双向绑定一般都应用在表单…

Leecode之面试题消失的数字

一.题目及剖析 https://leetcode.cn/problems/missing-number-lcci/description/ 方法有很多,这里将两种时间复杂度为O(N)的方法 二.思路引入 第一种方法 先将0-n的总和求出来,在求出数组的总和,在做差就能得到消失的数字,不过要注意的是数据有可能溢出,这个方法很简单就不再…

Flink理论—容错之状态后端(State Backends)

Flink理论—容错之状态后端(State Backends) Flink 使用流重放和 检查点的组合来实现容错。检查点标记每个输入流中的特定点以及每个运算符的相应状态。通过恢复运算符的状态并从检查点点重放记录,可以从检查点恢复流数据流,同时保持一致性 容错机制不…

题解43-48

124. 二叉树中的最大路径和 - 力扣(LeetCode) 二叉树中的 路径 被定义为一条节点序列,序列中每对相邻节点之间都存在一条边。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点,且不一定经过根节点。 路径和…

巨抽象的前端vue3

根据实践证明&#xff0c;越是简单的问题&#xff0c;越容易造成大bug 一个自定义组件的路径就废了我老半天了 各种查询&#xff0c;各种百度&#xff0c;各种问&#xff0c;结果规规矩矩去导入组件路径&#xff0c;成了&#xff01; 错误代码&#xff1a; <script setu…