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,一经查实,立即删除!

相关文章

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

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

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

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

人工智能|深度学习——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即可

DHCP动态主机配置协议

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

微信小程序的自定义组件

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

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

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

Android 异常开机半屏重启代码分析

Android 的稳定性是 Android 性能的一个重要指标&#xff0c;它也是 App 质量构建体系中最基本和最关键的一环&#xff1b;如果应用经常崩溃&#xff0c;或者关键功能不可用&#xff0c;那显然会对我们的留存产生重大影响所以为了保障应用的稳定性&#xff0c;我们首先应该树立…

Zynq UltraScale+ RFSoC 配置存储器器件

Zynq UltraScale RFSoC 配置存储器器件 下表所示闪存器件支持通过 Vivado 软件对 Zynq UltraScale RFSoC 器件执行擦除、空白检查、编程和验证等配置操 作。 本附录中的表格所列赛灵思系列非易失性存储器将不断保持更新 &#xff0c; 并支持通过 Vivado 软件对其中所列…

【C语言】6.C语言VS实用调试技巧(2)

文章目录 6.调试举例17.调试举例28.调试举例3&#xff1a;数组9.编程常⻅错误归类9.1 编译型错误9.2 链接型错误9.3 运⾏时错误 – 6.调试举例1 求 1!2!3!4!…10! 的和。 int main() {int n 0;int i 0;int ret 1;int sum 0;for (n 1; n < 3; n) {for (i 1; i < …

knife4j案例

1.导入 <dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId> </dependency>2.在配置类中加入 knife4j 相关配置并设置静态资源映射&#xff08;否则接口文档页面无法访问&#xff…

就这?轻轻松松在RK356X Android11适配ML307R Cat.1模组

开源鸿蒙硬件方案领跑者 触觉智能 Industio 本文基于IDO-SXB3568主板&#xff0c;介绍Android11平台上适配中移物联ML307R Cat.1 4G模组的方法。该方法适用于触觉所有RK356X的主板。 IDO-SXB3568是触觉智能推出的RK3568行业主板&#xff0c;预计6月上旬正式上架售卖。该行业主…

鸿蒙OS开发:【一次开发,多端部署】(应用UX设计原则)

应用UX设计原则 设计原则 当为多种不同的设备开发应用时&#xff0c;有如下设计原则&#xff1a; 差异性 充分了解所要支持的设备&#xff0c;包括屏幕尺寸、交互方式、使用场景、用户人群等&#xff0c;对设备的特性进行针对性的设计。 一致性 除了要考虑每个设备的特性…

54.指针

目录 一.什么是指针&#xff1f; 二&#xff0e;定义一个指针变量 三&#xff0e;指针变量类型 四&#xff0e;取地址运算符& 五.取值运算符* 六.视频教程 一.什么是指针&#xff1f; 口语中的指针一般指指针变量&#xff0c;指针变量存放的是一个地址。普通变量存放…

电脑缺失api-ms-win-crt-runtime-l1-1-0.dll文件的几种修复方法

当您在使用电脑过程中遇到程序启动失败&#xff0c;提示缺少“api-ms-win-crt-runtime-l1-1-0.dll”文件时&#xff0c;不必过于焦虑&#xff0c;此问题通常与Windows系统的Visual C Redistributable组件未正确安装或损坏有关。小编将介绍5种修复电脑缺失api-ms-win-crt-runtim…

计算机毕业设计 | vue+springboot电影票售卖 影院售票商城 电影管理系统(附源码+论文)

1&#xff0c;项目背景 目的&#xff1a;本课题主要目标是设计并能够实现一个基于web网页的电影院购票选座系统&#xff0c;整个网站项目使用了B/S架构&#xff0c;基于vue和SpringBoot框架下开发&#xff1b;管理员通过后台管理系统实现管理影院信息&#xff0c;电影信息&…