FreeRTOS--信号量

2023-05-16

信号量的基本概念:

     信号量是一种实现任务间通信的机制,可以实现任务之间同步或者临界资源的互斥访问,常用于协助一组相互竞争的任务来访问临界资源。信号量是一个非负整数,所以获取它的任务都会将整数减一,当该整数值为零时,所有试图获取他的任务都将处于阻塞态,通常一个信号量的计数值用于对应有效的资源数,表示剩下的可被占用的互斥资源数

0:表示没有积累下来的释放信号量的操作,且有可能有在此信号量上阻塞的任务

正值:表示有一个或者多个释放信号量的操作。

二值信号量:

   二值信号量既可以用于临界资源访问也可以用于同步功能。二值信号量和互斥信号量非常相似,但是有一些细微的差别,互斥量有优先级继承机制,二值信号量没有这个机制,二值信号量更偏向于同步功能,互斥量更偏向于临界资源的访问。

   用作同步时,信号量在创建后应被置为空,任务1获取信号量而进入阻塞,任务2在某种条件发生后释放信号量,于是任务1获得信号量进入就绪态,如果任务1的优先级最高,就会立即切换任务,从而达到两个任务的同步。可以将二值信号量看做是只有一个消息的消息队列,这个队列只能为满或者空。

计数信号量:

    计数信号量用于计数,用于事件计数和资源管理,信号量的数值表示还有多少个事件没被处理,任务必须先获取信号量才能获取资源的访问权,当信号量的计数为零时 表示系统中没有可用资源。在使用完资源之后  要归信号量。

互斥信号量:

    互斥信号量时特殊的二值信号量,适用于简单的互锁,保护临界资源。·创建后信号量的个数是满的,任务在使用临界资源时,先获取互斥信号量  让其他任务不能进入临界资源 保证临界资源的安全。

递归信号量:

   递归信号量对于已获取递归互斥量的任务可以重复获取该递归信号量的值,任务成功获取几次递归互斥量就要返还几次,在此之前递归信号量都处于无效状态,其他任务无法获取,只有持有递归信号量的任务才能获取与释放。

 

二值信号量的运作机制:

    

 计数信号量的运作机制:

 创建信号量函数:

1.创建二值信号量:

xSemaphoreCreateBinary()用于创建一个二值信号量,并返回一个句柄。其实二值信号
量和互斥量都共同使用一个类型 SemaphoreHandle_t 的句柄。使 用 该 函数 创 建 的 二 值信 号 量 是 空的 , 在 使 用函 数 xSemaphoreTake()获取之前必须先调用函数 xSemaphoreGive()释放后才可以获取。所有 FreeRTOS 的对象在创建的时候都默认使用动态内存 分配方案。
//二值信号量创建实例
SemaphoreHandle_t xSemaphore =NULL;
void vATask(void * pvParameters)
{
  //创建一个信号量
  xSemaphore=xSemphoreCreateBinary();
  if(xSemaphore==NULL)
    {
        //内存不足 创建失败

    }
    else
    {
        /*信号量现在可以使用,句柄存在变量 xSemaphore 中
 这个时候还不能调用函数 xSemaphoreTake()来获取信号量
 因为使用 xSemaphoreCreateBinary()函数创建的信号量是空的
在第一次获取之前必须先调用函数 xSemaphoreGive()先提交*/
        }
}

 2.创建计数信号量:

xSemaphoreCreateCounting ()用于创建一个计数信号量。要想使用该函数必须在
FreeRTOSConfig.h 中把宏 configSUPPORT_DYNAMIC_ALLOCATION 定义为 1,即开启动
态内存分配。其实该宏在 FreeRTOS.h 中默认定义为 1,即所有 FreeRTOS 的对象在创建的
时候都默认使用动态内存分配方案。

 

 void vATask( void * pvParameters )
 {
 SemaphoreHandle_t xSemaphore;
/* 创建一个计数信号量, 用于事件计数 */ 
xSemaphore = xSemaphoreCreateCounting( 5, 5 );  
if ( xSemaphore != NULL ) {
 /* 计数信号量创建成功 */
 }
}

 信号量删除函数vSemaphoreDelete():

  

vSemaphoreDelete()用于删除一个信号量,包括二值信号量,计数信号量,互斥量和递
归互斥量。

 信号量释放函数:

   FreeRTOS 提供了信号量释放函数,每调用一次该函数就释放一个信号量,无论是你的信号量是二值信号量还是计数信号量,都要注意可用信号量的范围,当用作二值信号量的时候,必须确保其可用值在 0~1 范围内;而用作计 数信号量的话,其范围是由用户在创建时指定 uxMaxCount,其最大可用信号量不允许超出 uxMaxCount,这代表我们不能一直调用信号量释放函数来释放信号量,其实一直调用也是无法释放成功的.

 

//使用实例
 static void Send_Task(void* parameter)
 {
 BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为 pdPASS */
while (1) {
 /* K1 被按下 */
 if ( Key_Scan(KEY1_GPIO_PORT,KEY1_GPIO_PIN) == KEY_ON ) {
 xReturn = xSemaphoreGive( BinarySem_Handle );//给出二值信号量 
 if ( xReturn == pdTRUE ) 
 printf("BinarySem_Handle 二值信号量释放成功!\r\n"); 
 else 
printf("BinarySem_Handle 二值信号量释放失败!\r\n"); 
}
 /* K2 被按下 */
if ( Key_Scan(KEY2_GPIO_PORT,KEY2_GPIO_PIN) == KEY_ON ) {
 xReturn = xSemaphoreGive( BinarySem_Handle );//给出二值信号量 
 if ( xReturn == pdTRUE ) 
 printf("BinarySem_Handle 二值信号量释放成功!\r\n"); 
 else 
 printf("BinarySem_Handle 二值信号量释放失败!\r\n"); 
 }
 vTaskDelay(20);
 }
 }

信号量获取函数:

  与释放信号量对应的是获取信号量,我们知道,当信号量有效的时候,任务才能获取
信号量,当任务获取了某个信号量的时候,该信号量的可用个数就减一,当它减到 0 的时
候,任务就无法再获取了,并且获取的任务会进入阻塞态. 释放信号量实际上是一次消息出队操作,阻塞时间由用户指定 xBlockTime,当有任务试图获取信号量的时候,当且仅当信号量有效的时候,任务才能读 获取到信号量。如果信号量无效,在用户指定的阻塞超时时间中,该任务将保持阻塞状态 以等待信号量有效。当其它任务或中断释放了有效的信号量,该任务将自动由阻塞态转移 为就绪态。当任务等待的时间超过了指定的阻塞时间,即使信号量中还是没有可用信号量, 任务也会自动从阻塞态转移为就绪态。
 static void Receive_Task(void* parameter)
 {
BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为 pdPASS */
 while (1) {
//获取二值信号量 xSemaphore,没获取到则一直等待 
xReturn = xSemaphoreTake(BinarySem_Handle,/* 二值信号量句柄 */ 
portMAX_DELAY); /* 等待时间 */ 
 if (pdTRUE == xReturn) 
 printf("BinarySem_Handle 二值信号量获取成功!\n\n"); 
 LED1_TOGGLE;
 }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

FreeRTOS--信号量 的相关文章

  • FreeRTOS系列

    1 多任务系统 1 1 前后台系统 单片机裸机开发时 一般都是在main函数里面用while 1 做一个大循环来完成所有的处理 循环中调用相应的函数完成所需的处理 有时也需要在中断中完成一些处理 相对于多任务系统而言 这就是单人单任务系统也
  • FreeRTOS config开始的宏

    FreeRTOSConfig h系统配置文件中可以自定义 FreeRTOS h中定义默认值 configAPPLICATION ALLOCATED HEAP 默认情况下FreeRTOS的堆内存是由编译器来分配的 将宏configAPPLIC
  • 【FreeRTOS 信号量】互斥信号量

    互斥信号量与二值信号量类似 但是互斥信号量可以解决二值信号量出现的优先级翻转问题 解决办法就是优先级继承 普通互斥信号量创建及运行 参阅安富莱电子demo 互斥信号量句柄 static SemaphoreHandle t xMutex NU
  • STM32F103移植FreeRTOS必须搞明白的系列知识---3(堆栈)

    STM32F103移植FreeRTOS必须搞明白的系列知识 1 Cortex CM3中断优先级 STM32F103移植FreeRTOS必须搞明白的系列知识 2 FreeRTOS任务优先级 STM32F103移植FreeRTOS必须搞明白的系
  • STM32CubeMX+FreeRTOS学习笔记(一)

    嵌入式实时操作系统FreeRTOS 基本概述 在嵌入式领域当中 实时操作系统的应用越来越广泛了 目前嵌入式操作系统种类很多 例如 Clinux C OS II C OS III FreeRTOS RT Thread等等 这篇文章所记录的就是
  • FreeRTOS 软件定时器的使用

    FreeRTOS中加入了软件定时器这个功能组件 是一个可选的 不属于freeRTOS内核的功能 由定时器服务任务 其实就是一个定时器任务 来提供 软件定时器是当设定一个定时时间 当达到设定的时间之后就会执行指定的功能函数 而这个功能函数就叫
  • FreeRTOS学习笔记<中断>

    中断概念 Cortex M的NVIC最多支持240个IRQ 中断请求 1个不可屏蔽中断 NMI 1个Systick 滴答定时器 定时器中断和多个系统异常 Cortex M处理器有多个用于管中断和异常的可编程寄存器 这些寄存器大多数都在 NV
  • FreeRTOS打印任务对CPU的占有率

    1 配置RTOS 1 打开RTOS Config Parameter 找到Run Time And Task States gathering related definitions 使能GENERATE RUN TIME STATS US
  • 基于HAL库的FREERTOS----------一.任务

    FreeROTS 就是一个免费的 RTOS 类系统 这里要注意 RTOS 不是指某一个确定的系统 而是指一类系统 比如 UCOS FreeRTOS RTX RT Thread 等这些都是 RTOS 类操作系统 FreeRTOS 是 RTOS
  • FreeRTOS+CubeMX系列第一篇——初识FreeRTOS

    文章目录 一 关于FreeRTOS 二 FreeRTOS的特点 三 如何在CubeMX上配置FreeRTOS 四 FreeRTOS文档资料 五 同系列博客 一 关于FreeRTOS 1 什么是FreeRTOS FreeRTOS是一个迷你的实
  • 【FreeRTOS(三)】任务状态

    文章目录 任务状态 任务挂起 vTaskSuspend 取消任务挂起 vTaskResume 挂起任务调度器 vTaskSuspendAll 取消挂起任务调度器 xTaskResumeAll 代码示例 任务挂起 取消任务挂起 代码示例 挂起
  • Error: L6218E: Undefined symbol vApplicationGetIdleTaskMemory (referred from tasks.o).

    我用的是F103ZET6的板子 移植成功后 编译出现两个错误是关于stm32f10x it c 里 void SVC Handler void void PendSV Handler void 两个函数的占用问题 随后编译出现以下两个问题
  • stm32f103zet6移植标准库的sdio驱动

    sdio移植 st官网给的标准库有给一个用于st出的评估板的sdio外设实现 但一是文件结构有点复杂 二是相比于国内正点原子和野火的板子也有点不同 因此还是需要移植下才能使用 当然也可以直接使用正点原子或野火提供的实例 但为了熟悉下sdio
  • FreeRTOS学习(三)开关中断

    声明及感谢 跟随正点原子资料学习 在此作为学习的记录和总结 环境 keil stm32f103 背景知识 Cotex M3的NVIC最多支持240个IRQ 中断请求 1个不可屏蔽 NMI 1个Systick 滴答定时器 Cortex M处理
  • 啊哈C的简单使用

    打开啊哈C 新建一个程序输出hello world include
  • FreeRTOS学习笔记(8)---- 软件定时器

    使用FreeRTOS软件定时器需要在文件FreeRTOSConfig h先做如下配置 1 configUSE TIMERS 使能软件定时器 2 configTIMER TASK PRIORITY 定时器任务优先级 3 configTIMER
  • 单片机通信数据延迟问题排查

    1 问题说明 笔者在最近的项目中 发现系统的响应延迟较高 经过排查 排除了单片机运行卡死的问题 2 原因分析 具体排查过程这里就不细致说明了 直接给出排查后原因 任务执行周期规划不合理 导致freertos队列发送接收到的命令有延迟 为了便
  • STM32 Freertos 添加 外部sram heap_5.c

    1 添加外部SRAM 初始化 2 添加heap 5 c 3 初始化heap 5 c 外部堆栈 Define the start address and size of the two RAM regions not used by the
  • 使用 GCC 编译器的 ARM 内核的堆栈回溯(当存在 MSP 到 PSP 切换时)

    核心 ARM Cortex M4 编译器 GCC 5 3 0 ARM EABI 操作系统 免费 RTOS 我正在使用 gcc 库函数 Unwind Reason Code Unwind Backtrace Unwind Trace Fn v
  • 当一个任务写入变量而其他任务读取该变量时,我们是否需要信号量?

    我正在研究 freeRtos 并且我有一个名为 x 的变量 现在 每秒只有一个任务正在写入该变量 而其他任务正在读取该变量值 我需要用互斥锁来保护变量吗 如果变量为 32 位或更小 并且其值是独立的并且不与任何其他变量一起解释 则不需要互斥

随机推荐

  • 美女体验小米无人机4K版:直接解锁新手模式

    其实说实话 xff0c 这小米无人机4K版我们拿到手上已经挺长时间的了 但是奈何全北京禁飞 xff0c 所以一直没有机会飞飞看 xff0c 于是我们就在解禁之后的第一时间 xff0c 跑到了六环外为大家带来试飞 就让我们从开箱开始 xff0
  • intel realsense摄像头标定教程(win10环境)

    intel realsense摄像头标定教程 准备工具 Intel RealSense D400 Series Dynamic Calibration Toolsprint target fixed width pdf或者对应手机app I
  • TCP网络编程例子(C语言实现)

    说明 xff1a 之前在CSDN上找TCP编程时 xff0c 发现有各种版本 不同版本之间写法不一 xff0c 所以自己写了个C语言版本的 xff0c 记录下来 服务端代码 xff1a span class token comment TC
  • D435i相机的标定及VINS-Fusion config文件修改

    引言 当我们想使用D435i相机去跑VINS Fusion时 xff0c 如果不把标定过的相机信息写入config文件中就运行 xff0c 这样运动轨迹会抖动十分严重 xff0c 里程计很容易漂 接下来将介绍如何标定D435i相机 xff0
  • 【C语言】--- while(1)语句内的if(i--)的无限循环

    例子 span class token macro property span class token directive keyword include span span class token string lt stdio h gt
  • uC/OS-III移植后发现程序停在空闲任务出不来

    今天移植了一下UCOS III的源码到STM32F103RCT6的板子上 xff0c 然后发现在所有任务都初始化完成后 xff0c 使用OSTimeDlyHMSM函数进行延时后就再也跳不出空闲任务了 xff0c 当时还以为是在移植程序的时候
  • 对uC/OS-III时钟节拍运转机制的一点理解

    目录 如何产生时基信号系统时钟中断管理时基任务时基列表更新写在最后 我在初学uC OS III的时候 xff0c 时基产生后到底是如何去驱动操作系统运转的 xff0c 对于这个问题一直有很多疑问 xff0c 最后读了手册并且仔细推敲源码后终
  • Altium Designer 常见的问题和解决办法,常更!

    本人的Altium Designer 版本是18 1 8 问题1 xff1a AD左上角有一个坐标显示框 xff0c 今天按键盘不小心弄没了 xff0c 然后弄出来后发现又会随着鼠标移动跟着移动 xff0c 不再固定到左上角了 相关解释 x
  • 推荐一款串口调试助手(win10,无广告,功能齐全,操作简单)

    目录 1 安装2 打开软件3 测试功能4 使用脚本功能5 波形显示功能6 升级专业版 作为一个搞嵌入式软件的 xff0c 串口是我们经常需要使用的一个外设资源 xff0c 对应的我们在调试的时候就需要用到一些工具 xff0c 本人也用过目前
  • STM32L1单片机的ADC必须开启HSI才能工作

    之前玩过F1和F4的板子 xff0c 这段时间 xff0c 接个项目需要用低功耗 xff0c 所以就整了STM32L151单片机 xff0c 然后今天在写ADC的时候 xff0c 发现了一个问题 xff0c 就是STM32L151MCU必须
  • 深入理解Linux文件系统与日志文件,快来看!

    目录 一 inode与block1 1 inode和block概述1 2 inode的内容 1 11 3 inode的内容 1 21 4 inode的内容 1 31 5 inode的号码1 6 文件存储小结1 7 inode的大小1 8 i
  • AT 指令集详解

    AT 指令集详解 1 AT的历史与应用1 1 AT的历史1 2 AT的优点1 3 AT命令与ppp协议的关系 2 AT的命令格式3 DCE的状态切换与AT的命令拨号流程3 1 初始化DCE的Modem设备3 2 拨号连接3 3 数据传输及处
  • 幽暗的廊桥,热烈的遗梦:火了25年的中年“杰克苏”童话

    廊桥是一种有遮盖的桥梁 路人经过一段幽暗隐蔽的空间后 xff0c 已身在彼岸 廊桥遗梦 的作者罗伯特 詹姆斯 沃勒于2017年3月10日凌晨 xff0c 在美国德克萨斯州弗雷德里克斯堡的家中去世 xff0c 享年77岁 作者当年如有神助 x
  • STM32L152 实现电源电压采集 基于HAL库实现

    CudeMX中对相关ADC的配置 这里用ADC1的通道17 keil中 自己编写 ADC Getvalue的值的函数 在主函数中调用 在debug模式下 可以在watch窗口中看见相关值 单位为mv
  • 基本共射放大电路的动态分析以及放大电路Q点的稳定

    求解静态 xff1a 直流通路 xff1a VCC 61 Ubeq 43 Ibq Rb gt Ibq gt Ieq 2 动态分析 xff1a 交流通路 xff1a H参数等效 xff1a 在放大过程中 xff1a 动态的Ube秉承动态的Ib
  • FreeRTOS 创建任务

    用已经移植好的工程模板 创建一个简单的任务 xff08 电量LED灯 xff09 1 硬件初始化 需要用到开发板上的LED灯小江LED灯相关的函数初始化 xff0c 在main c中创建一个Init xff08 xff09 函数 xff0c
  • 差分放大电路及动态分析

    由温度引起的零点漂移成为温漂 xff0c 引入负反馈 加入Re电阻 从抑制温度漂移的角度来说 希望Re越大越好 但是会导致放大倍数变小 加一个镜像的电路可以让两边一起浮动 但是两个Re可以共用一个 于是改成下面的 形式 Re电阻现在的作用变
  • FreeRTOS的启动流程

    目前的RTOS中有两种比较流行的启动方式 万事俱备 只欠东风 xff1a 在main函数中将硬件初始化 xff0c rtos系统初始化 xff0c 所有任务的创建都完成 再启动RTOS的调度器 xff08 在刚刚创建的的任务中选择一个优先级
  • FreeRTOS--消息队列

    队列 xff1a 队列又称为消息队列 xff0c 是一种用于任务间通信的数据结构 xff0c 是一种异步通信方式 xff0c 实现接收来自其他任务或者中断的不固定长度的消息 xff0c 任务能够从队列中读取消息 xff0c 当队列中消息是空
  • FreeRTOS--信号量

    信号量的基本概念 xff1a 信号量是一种实现任务间通信的机制 xff0c 可以实现任务之间同步或者临界资源的互斥访问 xff0c 常用于协助一组相互竞争的任务来访问临界资源 信号量是一个非负整数 xff0c 所以获取它的任务都会将整数减一