Free RTOS中Semaphore(二值信号量)的使用介绍

目录

概述

1 使用STM32Cube 配置信号量

1.1 引子

1.2 STM32Cube中配置FreeRTOS

1.3 STM32Cube生成Project

2 cmsis_os中信号量接口函数

2.1 函数:osSemaphoreNew

2.2 函数:osSemaphoreGetName

2.3 函数:osSemaphoreAcquire

2.4 函数:osSemaphoreRelease

2.5 函数:osSemaphoreGetCount

2.6 函数:osSemaphoreDelete

3 使用信号量方法

3.1 定义信号量的变量

3.1.1 数据结构: osSemaphoreAttr_t

3.1.2 数据结构:StaticSemaphore_t

3.1.3 数据结构:osSemaphoreId_t

3.2 一个Demo

3.2.1 定义信号量参数

3.2.2 创建信号量

3.2.3 Task中使用信号量

4 总结


概述

本文主要介绍Free RTOS中Semaphore的使用方法,包括使用STM32Cube中配置FreeRTOS,并且使能Semaphore,还介绍了Free RTOS中Semaphore中相关的函数。还通过一个简单的实例,来介绍Semaphore的使用方法。

1 使用STM32Cube 配置信号量

1.1 引子

笔者使用硬件平台为STM32H750,本文使用STM32CubeMX配置工程代码,并用该工具生成FreeRTOS的相关的Task和Semaphore相关的代码。关于嵌入式实时操作系统中的信号量的概念,笔者已经在其他文章中做了介绍,这里仅仅介绍如何使用FreeRTOS提供的接口,来实现功能。

1.2 STM32Cube中配置FreeRTOS

step-1: 使能FreeRTOS

step-2: 配置信号量参数,笔者配置了3个信号量

1)2个二值信号量

2)一个计数信号量

step-3:配置Task,用于测试信号量的功能,配置3个Task,每个task的优先级相互之间不同

1.3 STM32Cube生成Project

完成Semaphore和Task参数配置后,就可以点击GENERATE生成Project,完成GENERATE之后,打开工程,其项目文件结构如下:

1) 和FreeRTOS相关的代码已经被加载项目中

2) STM32Cube生成的和FreeRTOS相关的应用代码

2 cmsis_os中信号量接口函数

2.1 函数:osSemaphoreNew

函数功能: 创建并初始化一个信号量对象。

函数原型:

osSemaphoreId_t osSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr);

参数介绍:

参数名称描述
max_count可用令牌的最大数量
initial_count可用令牌的初始数量
attr

信号量属性;

默认值: NULL。

返回值:

供其他函数参考的信号量ID,如果发生错误则为NULL。

2.2 函数:osSemaphoreGetName

函数功能:获取信号量对象的名称

函数原型:

const char *osSemaphoreGetName (osSemaphoreId_t semaphore_id);

参数介绍:

参数名称描述
semaphore_id获取的信号量ID,这个ID是由osSemaphoreNew创建的

返回值:

状态码,表示函数的执行状态。

2.3 函数:osSemaphoreAcquire

函数功能: 获取信号量令牌,如果当前没有令牌,则超时放弃。

函数原型:

osStatus_t osSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout);

参数介绍:

参数名称描述
semaphore_id获取的信号量ID,这个ID是由osSemaphoreNew创建的
timeoutCMSIS_RTOS_TimeOutValue,如果没有超时,则为0。

返回值:

状态码,表示函数的执行状态

2.4 函数:osSemaphoreRelease

函数功能:释放一个信号量令牌,直到初始最大计数。

函数原型:

osStatus_t osSemaphoreRelease (osSemaphoreId_t semaphore_id);

参数介绍:

参数名称描述
semaphore_id获取的信号量ID,这个ID是由osSemaphoreNew创建的

返回值:

状态码,表示函数的执行状态

2.5 函数:osSemaphoreGetCount

功能介绍:获取当前信号量令牌计数。

函数原型:

uint32_t osSemaphoreGetCount (osSemaphoreId_t semaphore_id);

参数介绍:

参数名称描述
semaphore_id获取的信号量ID,这个ID是由osSemaphoreNew创建的

返回值:

可用令牌的数量。

2.6 函数:osSemaphoreDelete

功能介绍:删除信号量对象。

函数原型:

osStatus_t osSemaphoreDelete (osSemaphoreId_t semaphore_id);

参数介绍:

参数名称描述
semaphore_id获取的信号量ID,这个ID是由osSemaphoreNew创建的

返回值:

状态码,表示函数的执行状态

3 使用信号量方法

3.1 定义信号量的变量

3.1.1 数据结构: osSemaphoreAttr_t

数据结构参数说明

参数名称描述
name信号量的名称
attr_bits属性位
cb_mem控制块存储器
cb_size为控制块提供的内存大小
/// Attributes structure for semaphore.
typedef struct {const char                   *name;   ///< name of the semaphoreuint32_t                 attr_bits;   ///< attribute bitsvoid                      *cb_mem;    ///< memory for control blockuint32_t                   cb_size;   ///< size of provided memory for control block
} osSemaphoreAttr_t;

3.1.2 数据结构:StaticSemaphore_t

了解嵌入式实时操作系统中信号的相关知识,就知道每一个信号必须有一个controlBlock,其数据结构定义如下:

信号controlBlock数据结构定义如下:

3.1.3 数据结构:osSemaphoreId_t

在cmsis_os2.h 文件中定义了osSemaphoreId_t的数据类型为 void

3.2 一个Demo

3.2.1 定义信号量参数

代码第16行: 重新定义信号量控制块类型

代码第19行: 定义信号量ID

代码第21行: 定义信号量控制块

代码第23~27行:初始化信号参数簇

源代码

typedef StaticSemaphore_t osStaticSemaphoreDef_t;/* Definitions for myBinarySem01 */
osSemaphoreId_t myBinarySem01Handle;osStaticSemaphoreDef_t myBinarySem01ControlBlock;const osSemaphoreAttr_t myBinarySem01_attributes = {.name = "myBinarySem01",.cb_mem = &myBinarySem01ControlBlock,.cb_size = sizeof(myBinarySem01ControlBlock),
};/* Definitions for myBinarySem02 */
osSemaphoreId_t myBinarySem02Handle;
osStaticSemaphoreDef_t myBinarySem02ControlBlock;
const osSemaphoreAttr_t myBinarySem02_attributes = {.name = "myBinarySem02",.cb_mem = &myBinarySem02ControlBlock,.cb_size = sizeof(myBinarySem02ControlBlock),
};/* Definitions for myCountingSem01 */
osSemaphoreId_t myCountingSem01Handle;
osStaticSemaphoreDef_t myCountingSem01ControlBlock;
const osSemaphoreAttr_t myCountingSem01_attributes = {.name = "myCountingSem01",.cb_mem = &myCountingSem01ControlBlock,.cb_size = sizeof(myCountingSem01ControlBlock),
};

3.2.2 创建信号量

代码第50~53行:创建两个二值信号量

代码第56行:创建一个计数信号量

源代码:

void initTask( void )
{myBinarySem01Handle = osSemaphoreNew(1, 1, &myBinarySem01_attributes);/* creation of myBinarySem02 */myBinarySem02Handle = osSemaphoreNew(1, 1, &myBinarySem02_attributes);/* creation of myCountingSem01 */myCountingSem01Handle = osSemaphoreNew(2, 2, &myCountingSem01_attributes);	
}

3.2.3 Task中使用信号量

代码第79行: 申请信号量myBinarySem01Handle

代码第65行: 释放信号量myBinarySem01Handle

详细代码:

void mainTask(void *argument)
{  osStatus_t sem_osStatus;for(;;){	 sem_osStatus = osSemaphoreRelease(myBinarySem01Handle);if( sem_osStatus == osOK ){printf("myBinarySem01Handle: osSemaphoreRelease \r\n");	 }osDelay(30);}
}void monitorTask(void *argument)
{osStatus_t sem_osStatus;for(;;){sem_osStatus = osSemaphoreAcquire(myBinarySem01Handle, 100);if( sem_osStatus == osOK ){printf("myBinarySem01Handle: osSemaphoreAcquire  \r\n");}osDelay(10);}
}

4 总结

1)FreeRTOS的源代码cmsis_os2.h定义了所有的和信号量相关的接口函数

2)使用二值信号量时,需要定义和信号量相关的参数,包括信号量ID,控制块和参数族

3)通过osSemaphoreAcquire函数申请信号

4)通过osSemaphoreRelease释放信号量

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

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

相关文章

hashmap数据结构为什么是链表

HashMap 数据结构中&#xff0c;链表通常用于解决哈希冲突。当不同的键映射到相同的哈希桶时&#xff0c;就会发生哈希冲突。链表是一种简单而有效的解决方法。 在 JDK 8 之前的 HashMap 实现中&#xff0c;当发生哈希冲突时&#xff0c;冲突的元素会被存储在同一个哈希桶中&a…

设计模式:外观模式(Facade)

设计模式&#xff1a;外观模式&#xff08;Facade&#xff09; 设计模式&#xff1a;外观模式&#xff08;Facade&#xff09;模式动机模式定义模式结构时序图模式实现在单线程环境下的测试在多线程环境下的测试模式分析优缺点适用场景应用场景模式扩展参考 设计模式&#xff1…

C++STL(queue和list)

3.6 queue 容器 3.6.1 queue 基本概念 概念&#xff1a;Queue是一种先进先出(First In First Out,FIFO)的数据结构&#xff0c;它有两个出口 队列容器允许从一端新增元素&#xff0c;从另一端移除元素队列中只有队头和队尾才可以被外界使用&#xff0c;因此队列不允许有遍历…

【Open AI】GPT-4o深夜发布:视觉、听觉跨越式升级

北京时间5月14日1点整&#xff0c;OpenAI 召开了首场春季发布会&#xff0c;CTO Mira Murati 在台上和团队用短短不到30分钟的时间&#xff0c;揭开了最新旗舰模型 GPT-4o 的神秘面纱&#xff0c;以及基于 GPT-4o 的 ChatGPT&#xff0c;均为免费使用。 本文内容来自OpenAI网站…

大数据面试 --- 六

1、Flink中的三种时间&#xff0c;哪一个性能会比较好 在Flink中主要分成三种时间&#xff1a; 事件时间&#xff08;Event Time&#xff09;注入时间&#xff08;Process Time&#xff09;、摄入时间&#xff08;Ingestion Time&#xff09; 事件时间指的是事件产生的时间…

课时126:awk实践_进阶知识_内置函数1

1.2.5 内置函数1 学习目标 这一节&#xff0c;我们从 基础知识、简单实践、小结 三个方面来学习。 基础知识 简介 在awk内部预制了一些函数&#xff0c;借助于这些函数&#xff0c;我们可以实现相关场景的快速操作。这些内置函数的常见类型有&#xff1a;数值类内置函数int…

人工智能|深度学习——YOLOV8结构图

YoloV8相对于YoloV5的改进点&#xff1a; Replace the C3 module with the C2f module.Replace the first 6x6 Conv with 3x3 Conv in the Backbone.Delete two Convs (No.10 and No.14 in the YOLOv5 config).Replace the first 1x1 Conv with 3x3 Conv in the Bottleneck.Use…

【图神经网络——消息传递】

消息传递机制 画图先&#xff1a;导包&#xff1a;画图&#xff1a; 实现消息传递&#xff1a;例子一&#xff1a;例子二&#xff1a; 画图先&#xff1a; 导包&#xff1a; import networkx as nx import matplotlib.pyplot as plt import torch from torch_geometric.nn im…

Linux操作系统最著名的两大系列Red Hat和Debian

Linux操作系统可以根据其背后的项目或社区分为不同的系列&#xff0c;其中最著名的两大系列是Red Hat系列和Debian系列。 1.著名的两大系列是Red Hat和Debian Red Hat系列&#xff1a; Red Hat Enterprise Linux (RHEL)&#xff1a;这是Red Hat公司推出的企业级操作系统&#…

【LAMMPS学习】十、LAMMPS辅助工具(1)

10. 辅助工具 LAMMPS 被设计为用于执行分子动力学计算的计算内核。设置和分析模拟通常需要额外的预处理和后处理步骤。此类工具的列表可以在 LAMMPS 网页上的以下链接中找到&#xff1a; 前/后处理 外部 LAMMPS 软件包和工具 Pizza.py 工具包 Pizza.py 的最后一个链接是桑迪…

CTFshow misc

第一题1 打开图片直接就是flag 第二题0 放入010发现文件头有png 更换后缀 获得flag 第三题1 下载之后发现是bpg后缀 用在线工具转换为png获得flag 第四题 0 把六个文件后缀都改为png即可获得flag

Visual Studio Code 扩展程序Text Edits

需求 比如把Scarzombie_Monster全部转换为大写或者小写 安装 Text Edits 直接搜索安装即可 使用 假如要把Scarzombie_Monster全部转为大写&#xff0c;选中右键选中 To Upper Case或者直接快捷键shiftAltU即可

使用yolov8 训练coco 和自己的关键点识别数据集的参考

使用yolov8 训练关键点配置理解 1. coco-pose.yaml 修改关键参数kpt_shape: [17, 3]flip_idx: [0, 2, 1, 4, 3, 6, 5, 8, 7, 10, 9, 12, 11, 14, 13, 16, 15]2. yolov8n-pose.yaml 修改kpt_shape3. 编写 train文件4.一个封装的推理代码1. coco-pose.yaml 修改关键参数 kpt_sha…

DHCP动态主机配置协议

DHCP概述 DHCP是什么 DHCP&#xff1a;Dynamic Host Configuration Protocol&#xff1a;动态主机配置协议DHCP是一种集中对用户IP地址进行动态管理和配置的技术 DHCP作用&#xff1a; 作用&#xff1a;实现IP地址的动态分配和集中管理优势&#xff1a;避免手工配置IP地址&…

linux编译gdb

下载 我下载了8.3 Index of /gnu/gdb 编译 make cleanmake diskclean./configure \--without-x \--disable-werrormake make install

微信小程序的自定义组件

一、创建自定义组件 &#xff08;1&#xff09;定义&#xff1a; 把页面重复的代码部分封装成为一个自定义组件&#xff0c;以便在不同的页面中重复使用&#xff0c;有助于代码的维护。 &#xff08;2&#xff09;组成&#xff1a; 自定义组件的组成&#xff1a;json文件&a…

.gitignore文件使用指南

.gitignore文件使用指南 .gitignore 文件的作用 忽略不需要的文件&#xff1a;避免将不必要的文件&#xff08;如编译生成的文件、临时文件、日志文件等&#xff09;提交到代码仓库。保护敏感信息&#xff1a;防止本地配置文件&#xff08;如数据库配置文件、API 密钥等&…

阅读笔记——《代码整洁之道》ch2

引言 clean-code ch2阅读笔记 有意义的命名 名副其实 选择体现本意的名称能让人更容易理解和修改代码。 避免误导 怎么能知道该调用哪个函数呢? getActiveAccount(); getActiveAccounts(); getActiveAccountInfo();moneyAmount与money没区别,customerInfo与customer没区别。…

代码随想录-算法训练营day39【动态规划02:不同路径】

代码随想录-035期-算法训练营【博客笔记汇总表】-CSDN博客 第九章 动态规划part02● 62.不同路径 ● 63. 不同路径 II 今天开始逐渐有 dp的感觉了&#xff0c;题目不多&#xff0c;就两个 不同路径&#xff0c;可以好好研究一下详细布置 62.不同路径 本题大家掌握动态规划的方…

Elasticsearch 搜索引擎实现对文档内容进行快速检索(保姆级教程)

本文主要讲解ES如何从提取文档中提取内容&#xff08;word、pdf、txt、excel等文件类型&#xff09;&#xff0c;实现快速检索文档内容实现。 特别说明一下&#xff0c;为什么用7.10.0版本&#xff0c;因为在项目中除了精确匹配的要求&#xff0c;也会有模糊查询&#xff08;关…