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 ...
随机推荐
- SpringBoot整合Prometheus
SpringBoot整合Prometheus 一.需求 二.实现步骤 1.引入jar包 2.application.prometheus文件配置 3.查看指标数据 4.接入到 prometheus 中 ...
- WiFi天线对PCB布局布线和结构的要求详解 - 全文
随着市场竞争的加剧,硬件设备正以集成化的方向发展.天线也由外置进化内置再进化到嵌入式,我们先来介绍这类应用的天线种类: ⑴ On Board板载式:采用PCB蚀刻一体成型,性能受限,极低成本,应用于蓝 ...
- Spark面试题整理(三)
1.为什么要进行序列化序列化? 可以减少数据的体积,减少存储空间,高效存储和传输数据,不好的是使用的时候要反序列化,非常消耗CPU. 2.Yarn中的container是由谁负责销毁的,在Hadoop ...
- VirtualBox Share Folder
转载:https://www.cnblogs.com/Dennis-mi/articles/5896586.html 使用virtualbox最方便的host-guest交换文件方案莫过于共享文件夹功 ...
- hdu 1227 Fast Food(DP)
题意: X轴上有N个餐馆.位置分别是D[1]...D[N]. 有K个食物储存点.每一个食物储存点必须和某个餐厅是同一个位置. 计算SUM(Di-(离第i个餐厅最近的储存点位置))的最小值. 1 < ...
- hdu 2086 A1 = ? (公式推导)
有如下方程:Ai = (Ai-1 + Ai+1)/2 - Ci (i = 1, 2, 3, .... n).若给出A0, An+1, 和 C1, C2, .....Cn.请编程计算A1 = ? Inp ...
- hdu 5095 Linearization of the kernel functions in SVM(模拟,分类清楚就行)
题意: INPUT: The input of the first line is an integer T, which is the number of test data (T<120). ...
- cm0 逆向分析
目录 cm0 逆向分析 前言 Strings工具复习 String工具使用说明 Strings工具解cm0题 cm0 逆向分析 前言 Emmmmm,我假装你看到这里已经学过了我的<恶意代码分析实 ...
- swagger3.0(springboot)消除basic-error-controller
1.新建springboot项目,可以通过https://start.spring.io/快速生成springboot项目. 2.引入jar依赖: <dependency> <gro ...
- yum Multilib version problems
这两天在更新CentOS7系统时,出现了Multilib version problems错误,执行命令: # yum update 出现了的错误信息: .... ---> Package li ...