6.FreeRTOS学习笔记-信号量
基本概念
- 抽象的来讲,信号量是一个非负整数,所有获取它的任务都会将该整数减一(获取它当然是为了使用资源),当该整数值为零时,所有试图获取它的任务都将处于阻塞状态
二值信号量
二值信号量既可以用于临界资源访问也可以用于同步功能
互斥量有优先级继承机制,二值信号量则没有这个机制
二值信号量更偏向应用于同步功能(任务与任务间的同步或任务和中断间同步)
而互斥量更偏向应用于临界资源的访问
将二值信号量看作只有一个消息的队列因此这个队列只能为空或满
计数信号量
- 计数信号量肯定是用于计数的
- 信号量的计数值则表示还有多少个事件没被处理
- 计数型信号量允许多个任务对其进行操作,但限制了任务的数量
互斥信号量
- 互斥信号量其实是特殊的二值信号量,由于其特有的优先级继承机制从而使它更适用于简单互锁,也就是保护临界资源
- 信号量创建后可用信号量个数应该是满的
递归信号量
- 任务成功获取几次递归互斥量,就要返还几次,在此之前递归互斥量都处于无效状态,只有持有递归信号量的任务才能获取与释放
- 对于已经获取递归互斥量的任务可以重复获取该递归互斥量,该任务拥有递归信号量的所有权
信号量控制块
- 使用信号量需要包含头文件
#include <semphr.h>
- 信号量控制块结构体与消息队列结构体是一模一样的,只不过结构体中某些成员变量代表的含义不一样而已
typedef struct QueueDefinition
{int8_t *pcHead; int8_t *pcTail; int8_t *pcWriteTo; union {int8_t *pcReadFrom; UBaseType_t uxRecursiveCallCount;} u;List_t xTasksWaitingToSend; List_t xTasksWaitingToReceive; volatile UBaseType_t uxMessagesWaiting;/* 表示有效信号量个数
1. 如果信号量是二值信号量、互斥信号量,这个值是 1 则表示有可用信号量,如果是 0 则表示没有可用信号量。2. 如果是计数信号量,这个值表示可用的信号量个数,在创建计数信号量的时候会被初始化一个可用信号量个数 uxInitialCount,最大不允许超过创建信号量的初始值 uxMaxCount。
*/UBaseType_t uxLength; /*
最大的信号量可用个数,
1. 如果信号量是二值信号量、互斥信号量,uxLength 最大为 1,因为信号量要么是有效的,要么是无效的。
2. 如果是计数信号量,这个值表示最大的信号量个数,在创建计数信号量的时候将由用户指定这个值 uxMaxCount。*/UBaseType_t uxItemSize; /*果控制块结构体被用于信号量的时候,则无需存储空间,为 0 即可 */volatile int8_t cRxLock; volatile int8_t cTxLock; #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )uint8_t ucStaticallyAllocated; #endif#if ( configUSE_QUEUE_SETS == 1 )struct QueueDefinition *pxQueueSetContainer;#endif#if ( configUSE_TRACE_FACILITY == 1 )UBaseType_t uxQueueNumber;uint8_t ucQueueType;#endif} xQUEUE;
信号量句柄
typedef QueueHandle_t SemaphoreHandle_t;
创建二值信号量 xSemaphoreCreateBinary()
#define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( uint8_t ) 0U )#define queueQUEUE_TYPE_BASE ( ( uint8_t ) 0U )
#define queueQUEUE_TYPE_SET ( ( uint8_t ) 0U )
#define queueQUEUE_TYPE_MUTEX ( ( uint8_t ) 1U )
#define queueQUEUE_TYPE_COUNTING_SEMAPHORE ( ( uint8_t ) 2U )
#define queueQUEUE_TYPE_BINARY_SEMAPHORE ( ( uint8_t ) 3U )
#define queueQUEUE_TYPE_RECURSIVE_MUTEX ( ( uint8_t ) 4U )#define xSemaphoreCreateBinary() xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE )
- 没有消息存储空间的队列,信号量用什么表示?其实二值信号量的释放和获取都是通过操作队列结控制块构体成员uxMessageWaiting 来实现的,它表示信号量中当前可用的信号量个数
创建计数信号量 xSemaphoreCreateCounting()
#define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) )
/*
uxMaxCount 计数信号量的最大值,当达到这个值的时候,信号量不能再被释放。
uxInitialCount 创建计数信号量的初始值。
返回值 如果创建成功则返回一个计数信号量句柄,用于访问创建的计数信号量。如果创建不成功则返回 NULL。
*/
信号量删除函数 vSemaphoreDelete()
void vSemaphoreDelete( SemaphoreHandle_t xSemaphore )#define vSemaphoreDelete( xSemaphore ) vQueueDelete( ( QueueHandle_t ) ( xSemaphore ) )
信号量释放函数–普通版
BaseType_t xSemaphoreGive(SemaphoreHandle_t xSemaphore ) #define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
/*
如果信号量满,则返回错误代码(err_QUEUE_FULL)
*/
信号量释放函数–中断版
它不能释放互斥量,这是因为互斥量不可以在中断中使用,互斥量的优先级继承机制只能在任务中起作用,而在中断中毫无意义。
#define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueGiveFromISR( ( QueueHandle_t ) ( xSemaphore ), ( pxHigherPriorityTaskWoken ) )/*
如果被唤醒的任务的优先级大于当前任务的优先级,那么形参 pxHigherPriorityTaskWoken 就会被设置为 pdTRUE,然后在中断退出前执行一次上下文切换,从 FreeRTOS V7.3.0 版本开始 xHigherPriorityTaskWoken 是一个可选的参数,可以设置为 NULL
*/
信号量获取函数–普通版
#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueGenericReceive( ( QueueHandle_t ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE )
/*xSemaphore 信号量句柄。
xBlockTime 等待信号量可用的最大超时时间,单位为 tick(即系统节拍周期)。如果宏 INCLUDE_vTaskSuspend 定义为 1 且形参xTicksToWait 设置为 portMAX_DELAY ,则任务将一直阻塞在该信号量上(即没有超时时间)。
返回值 获 取 成 功 则 返 回 pdTRUE , 获取失败 返 回 errQUEUE_EMPTY。
*/
信号量获取函数–中断版
获取信号量,是一个不带阻塞机制获取信号量的函数,获取对象必须由是已经创建的信号量,信号量类型可以是二值信号量和计数信号量,它与 xSemaphoreTake()函数不同,它不能用于获取互斥量,因为互斥量不可以在中断中使用,并且互斥量特有的优先级继承机制只能在任务中起作用,而在中断中毫无意义。
#define xSemaphoreTakeFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueReceiveFromISR( ( QueueHandle_t ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ) )
6.FreeRTOS学习笔记-信号量相关推荐
- freeRtos学习笔记 (7)信号量
freeRtos学习笔记 freeRtos信号量 信号量种类 信号量分为四种:二值信号量,互斥信号量,计数信号量和递归互斥信号量,其中计数信号量用于管理系统多个共享资源,用计数值表示可用资源数目;二值 ...
- FreeRTOS学习笔记——互斥型信号量
来自:http://blog.csdn.net/xukai871105/article/details/43456985 0.前言 在嵌入式操作系统中互斥型信号量是任务间资源保护的重要手段.下面结合一 ...
- FreeRtos学习笔记(11)查找就绪任务中优先级最高任务原理刨析
FreeRtos学习笔记(11)查找就绪任务中优先级最高任务原理刨析 怎么查找就绪任务中优先级最高的? tasks.c中声明了一个全局变量 uxTopReadyPriority,任务从其他状态进入就绪 ...
- freeRtos学习笔记 (8) 任务通知
freeRtos学习笔记 freeRtos任务通知 任务通知的优缺点 freeRtos任务控制块中包含两个32位的变量,用于任务通知,在一些情况下,任务通知可以替代信号量和事件组,并且比信号量和事件组 ...
- freeRtos学习笔记 (5)事件组
freeRtos学习笔记 freeRtos事件组 为什么要用事件组? 多任务环境下, 任务.中断之间往往需要同步操作,一个事件发生会告知等待中的任 务,即形成一个任务与任务.中断与任务间的同步.事件可 ...
- FreeRTOS学习笔记
FreeRTOS学习笔记 (这是我自己学习FreeRTOS整理的笔记,仅供参考) 第一部分:实现FreeRTOS内核 变量名: 定义变量时往往会把变量的类型当作前缀加在变量上 变量类型 前缀 char ...
- 1、野火freertos学习笔记
野火freertos学习笔记 1.任务 1.1 栈 1.2 任务的切换 taskYIELD(); 1.3 临界段 2.空闲任务 3.任务优先级 4.任务延时的表现 5.时间片 5.1抢占式.协做式 6 ...
- freeRtos学习笔记 (9) 移植和CPU利用率统计
freeRtos学习笔记 (9) 移植和CPU利用率统计 使用官方固件移植 首先准备一个能跑的裸机工程 注意,freertos需要使用systick定时器,而stm32HAL库默认使用systick作 ...
- freeRtos学习笔记 (6)软件定时器
freeRtos学习笔记 freeRtos软件定时器 软件定时器需要注意事项 软件定时器的精度基于时钟节拍,例如系统时钟节拍为10ms, 软件定时器定时时间必须是10ms的整数倍,因此软件定时器一般用 ...
最新文章
- 9,线程池 threadPool 与 线程池执行器 threadPoolExecutor
- docker centos7 安装ssh
- 电脑分辨率是什么_吵翻天的2K、3K、4K屏到底是什么鬼?
- [Jetty]基于Java Servlet的支持WebSocket的服务器
- Linux驱动中相关函数查询
- CAD迷你看图 for Mac(MiniCAD)
- python 移动文件或文件夹操作
- 可用等式为:html+java=jsp表示jsp[8]._在 JSP 中 , 对 jsp:setProperty 标记描述正确的是 ()_学小易找答案...
- 酒店管理系统(功能结构图、E-R图、用例图)
- 【Spring Boot】——集成JSON工具
- signature=ac75cb7977a45c0f7d8a73dca59a4c27,合肥2016年8月24日至2016年9月5日交通违章查询...
- uniapp微信授权+获取手机号+解密手机号(带图详解)
- 关于小米路由器的局域网内相互ping设备IP的解决方法
- 历史回顾|创建PG全球生态!PostgresConf.CN2019大会召开
- 鸿蒙系统与麒麟os,华为鸿蒙系统改名为麒麟OS
- 目前市面上最受欢迎共享产品有哪些
- 关于FLEX输出时:IE提示Alternate HTML content should be placed here. This content requir
- 互联网商业模式有哪些?
- Python网络爬虫实战10:爬取中关村在线首页“今日焦点”的头条新闻列表
- CPU 平均负载为多少更合理?
热门文章
- wpf tabcontrol嵌套自动跳转上层_Python Selenium包应对嵌套网页的方法和简单 js 脚本运行的实现...
- 1gb 云服务器 和2gb的区别_(12)虚拟主机/VPS/云主机/服务器有什么区别?
- mysql 不完全插入_MySql insert插入操作不完全指北_MySQL
- cad画圆如何确定圆心_原来在CAD中画个圆也有这么多学问!你知道这些画圆的技巧吗?...
- Java 并发编程之 CopyOnWriteArrayList
- Java 算法 特殊的数字四十
- Java 算法 数列
- python使用zip迭代列表
- Java反射运行时_java反射获得运行时属性的值
- java se开发_JAVA_SE基础——3.Java程序的开发流程