CMSIS-RTOS 信号量Semaphores
信号量Semaphores
和信号类似,信号量也是一种同步多个线程的方式,简单来讲,信号量就是装有一些令牌的容器。当一个线程在执行过程中,就可能遇到一个系统调用来获取信号量令牌,如果这个信号量包含多个令牌,线程就会继续执行,同时信号量令牌的数量就会减一。如果此时信号量中没有令牌,线程就会被置于等待状态,直到出现一个可用的令牌。在线程执行的任何位置,它都可以给信号量增加一个令牌。
信号量用来帮助访问程序资源,在一个线程允许访问一个信号量之前,它必须拥有一个令牌。如果没有令牌可用,它就必须等待,当线程使用完资源时,它就必须释放令牌。
上图揭示了两个线程如何使信号量同步。首先,必须创建一个信号量,并初始化令牌数目,在上图中,信号量初始化令牌数目为1。当两个线程运行到某一点时就试图从信号量中请求一个令牌,图中第一个线程到达这个点,成功获取一个令牌,然后继续执行,第二个线程也试图获取一个令牌,但是当前信号量为空,所以它暂停执行,并进入等待状态,直到信号量中有令牌可用。
与此同时,执行中的线程可以释放令牌给信号量,一旦释放完成,等待中的线程就会获取令牌,并离开等待状态进入准备状态。紧接着调度器就会把它调度到运行状态去执行剩下的代码。
因为信号量保含较多的系统调用,所以想一次性全部理解有些难度,在本节,我们将首先看看如何给系统添加信号量,然后了解一下常用的信号量应用。
在使用信号量之前,你必须先声明一个信号量容器:
osSemaphoreId sem1;
osSemaphoreDef(sem1);
- 1
- 2
然后在线程里给信号量容器初始化一些令牌:
sem1 = osSemaphoreCreate(osSemaphore(sem1), SIX_TOKENS);
- 1
有一点比较重要,就是在线程运行的过程中令牌既可以被创建也可以被销毁,举个例子,你可以初始化一个信号量,拥有0个令牌,然后用一个线程给这个信号量创建一些令牌,再使用另一个线程移除它们,这样一来,你就可以设计线程,既可以充当生产者的线程,也可以充当消费者的线程。
一旦信号量被创建,令牌就可能被获取,并以类似事件标志的方式发送给信号量,os_sem_wait调用来阻塞线程,直到有信号量令牌可用,类似os_event_wait,当然,在这个调用中同样拥有超时机制,超时初始值是0xFFFF。
osStatus osSemaphoreWait(osSemaphoreId semaphore_id, uint32_t millisec);
- 1
一旦线程完成对信号量资源的使用,它就可以给信号量容器发送一个令牌:
osStatus osSemaphoreRelease(osSemaphoreId semaphore_id);
- 1
练习:信号量的信号传输
在这个练习中,我们将看到如何配置一个信号量,并使用它在两个任务间发送信号。
打开Pack Installer,选择”Ex 9 Semaphore Signaling”,然后复制到你的指定路径。
首先创建一个信号量sem1,然后给它初始化0个令牌:
osSemaphoreId sem1;
osSemaphoreDef(sem1);
int main(void){
sem1 = osSemaphoreCreate(osSemaphore(sem1), 0);
- 1
- 2
- 3
- 4
第一个线程等待一个令牌被发送到信号量容器:
void led_Thread1(void const *argument){
for(;;){
osSemaphoreWait(sem1, osWaitForever);
LED_On(1);
osDelay(500);
LED_Off(1);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
与此同时,第二个线程周期性的给信号量发送令牌:
void led_Thread2(void const *argument){
for(;;){
LED_On(2);
osSemaphoreRelease(sem1);
osDelay(500);
LED_Off(2);
osDelay(500);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
编译工程并启动仿真环境。
在led_Thread2任务设置断点:
运行代码,运行到断点,观察线程状态:
现在led_thread1被阻塞,等待从信号量获取一个令牌,线程1的优先级比线程2高,所以一旦令牌放入信号量,线程1就会立即进入准备状态,抢占低优先级线程,并随后启动运行。当运行到osSemaphoreWait()调用后,它又再次阻塞。
现在单步运行(F10),观察线程及信号量的行为。
CMSIS-RTOS 信号量Semaphores的更多相关文章
- CMSIS RTOS -- embOS segger
#ifndef __CMSIS_OS_H__ #define __CMSIS_OS_H__ #include <stdint.h> #include <stddef.h> #i ...
- CMSIS-RTOS 信号量
信号量Semaphores 和信号类似,信号量也是一种同步多个线程的方式,简单来讲,信号量就是装有一些令牌的容器.当一个线程在执行过程中,就可能遇到一个系统调用来获取信号量令牌,如果这个信号量包含多个 ...
- C++互斥器:Semaphores
类似于Mutex,但信号量Semaphores不仅仅是锁和解锁那么简单,更高级的是,可以被锁住最多n次. 其中这个n是信号量被产生时指定的n.该值常常被用来代表“可以锁定住一份资源”的线程个数. 可以 ...
- RTOS之CMSIS-RTOS
CMSIS-RTOS 是实时操作系统的通用 API.它提供了标准化的编程接口,它只是封装了RTX/embos,以后还可能封装freeRTOS,uc/os等等第三方OS,CMSIS RTOS是ARM现在 ...
- ARM官方《CMSIS-RTOS教程》之线程Threads
创建线程Creating Threads 一旦RTOS开始运行,就会有很多系统调用来管理和控制活跃的线程.默认情况下,main()函数自动被创建为第一个可运行的线程.在第一个例子里我们使用main() ...
- CMSIS_RTOS_Tutorial自译中文版
一.序言 本资料是Trevor Martin编写的<The Designers Guide to the Cortex-M Processor Family>的摘要,并得到Elsevier ...
- STM32F429i-DISCO FreeRTOS keil STM32CubeMX
目标: 在STM32F429 Disco开发板上用FreeRTOS双线程点亮双闪led. 准备: 0. STM32F429i-DISCO 1. keil ARMMDK 5.13 2. STM32Cub ...
- Linux Communication Mechanism Summarize
目录 . Linux通信机制分类简介 . 控制机制 0x1: 竞态条件 0x2: 临界区 . Inter-Process Communication (IPC) mechanisms: 进程间通信机制 ...
- linux概念之IPC
一切皆文件,文件类型为普通,目录,管道,socket,链接,块设备,字符设备cd /proc/2305/fd/ 该进程打开了6个文件描述符,三个为字符设备即012,三个为socket即345,sock ...
随机推荐
- 使用Mybatis的TypeHandler加解密数据
使用Mybatis的TypeHandler加解密数据 一.背景 二.解决方案 三.需求 四.实现思路 1.编写一个实体类,凡是此实体类的数据都表示需要加解密的 2.编写一个加解密的`TypeHandl ...
- 使用registry搭建docker私服仓库
使用registry搭建docker私服仓库 一.拉取 registry镜像 二.根据镜像启动一个容器 1.创建一个数据卷 2.启动容器 三.随机访问一个私服的接口,看是否可以返回数据 四.推送一个镜 ...
- SpringCloud 2020.0.4 系列之服务降级的其他用法与熔断
1. 概述 老话说的好:控制好自己的情绪,才能控制好自己的人生.冲动是魔鬼,冷静才最重要. 言归正传,之前聊了在 Feign 调用时,如何给整个 Feign接口类 增加降级策略. 今天我们来聊一下 H ...
- 疯狂Java基础Day2
巩固Java流程控制的学习... 一.用户交互Scanner 通过Scanner类获取用户的输入 import java.util.Scanner; public class Demo1 { publ ...
- A*,IDA*—高档次的暴搜
A*通过评价函数来判断当前状态是否可以到达最终状态(即可行性剪枝),来减少不必要的搜索. 例题--P2324 [SCOI2005]骑士精神 我们通过当前不在指定位置上的棋子个数为评价函数,\(used ...
- MyBatis源码分析(二):MyBatis整体架构及原理
一.Mybatis整体架构导图 二.Mybatis的核心组成 SqlSessionFactoryBuilder(构造器): 根据配置信息(XML)生成SqlSessionFactory工厂接口,构造器 ...
- 极速上手 VUE 3—v-model 的使用变化
本篇文章主要介绍 v-model 在 Vue2 和 Vue3 中使用变化. 一.Vue2 中 v-model 的使用 v-model 是语法糖,本质还是父子组件间的通信.父子组件通信时有两种方式: 父 ...
- 并发编程从零开始(十四)-Executors工具类
并发编程从零开始(十四)-Executors工具类 12 Executors工具类 concurrent包提供了Executors工具类,利用它可以创建各种不同类型的线程池 12.1 四种对比 单线程 ...
- 远程设备管理opendx平台搭建-server,agent以及front实际搭建
本系列文章讲述的是一个系列的第二部分,最终可以搭建一整套设备远程管理平台,与stf不同的是,opendx搭建较为简单,而且由于底层是appium来支持的,所以,较容易支持ios,也容易支持更高版本的安 ...
- vscode + vim 全键盘操作高效搭配方案
基础知识 vscode-vim vscode-vim是一款vim模拟器,它将vim的大部分功能都集成在了vscode中,你可以将它理解为一个嵌套在vscode中的vim. 由于该vim是被模拟的的非真 ...