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 ...
随机推荐
- activiti流程图上获取各节点的信息获取
背景: 由于项目的需要,当用户在查看流程图时,当点击某个流程图片上的节点时,需要提示一些信息,这就需要获取各个节点的信息,此处获取id和name的值. 注意:这个并 ...
- Noip模拟79 2021.10.17(题目名字一样)
T1 F 缩点缩成个$DAG$,然后根据每个点的度数计算期望值 1 #include<cstdio> 2 #include<cstring> 3 #include<vec ...
- 注意 .NET string.GetHashCode() 用法
需求案例:需要把字符串存入数据库,并且要求数据库中不能有重复的字符串,由此就引出了将字符串hash成特定的hash值,依靠查询hash值是否重复来判断字符串是否重复.这样做的好处在于查询重复字符串的代 ...
- cf13C Sequence(DP)
题意: N个数.a1...aN. 对于每个数而言,每一步只能加一或减一. 问最少总共需要多少步使得新序列是非递减序列. N (1 ≤ N ≤ 5000) 思路: *一个还不知道怎么证明的结论(待证): ...
- ARM 链接配置.lds文件学习<转>
本文由Jacky原创,来自http://blog.chinaunix.net/u1/58780/showart.php?id=462971 对于.lds文件,它定义了整个程序编译之后的连接过程,决定了 ...
- ubuntu install redis
ubuntu install redis apt-get update apt-get install redis-server redis-server --daemonize yes
- Go语言核心36讲(Go语言实战与应用三)--学习笔记
25 | 更多的测试手法 在本篇文章,我会继续为你讲解更多更高级的测试方法.这会涉及testing包中更多的 API.go test命令支持的,更多标记更加复杂的测试结果,以及测试覆盖度分析等等. 前 ...
- 18-Spring Cloud Alibaba Nacos
简介 为什么叫Nacos 前四个字母分别为Naming和Configuration的前两个字母,最后的s为Service Nacos是什么 一个更易于构建云原生应用的动态服务发现.配置管理和服务管理平 ...
- 印象最深的一个bug:sessionStorage缓存在移动端失效
无bug,不程序:作为程序员的我,不是修bug就是在写bug的路上. 移动端sessionStorage缓存失效是我"印象最深的一个bug"之一,为啥呢,因为这个问题导致我加班到很 ...
- logstash插件配置-codec插件说明json和multiline
编码插件(Codec) Codec 是 logstash 从 1.3.0 版开始新引入的概念(Codec 来自 Coder/decoder 两个单词的首字母缩写). 在此之前,logstash 只支持 ...