FreeRTOS二值信号量

2024-05-13 08:20
文章标签 信号量 freertos 二值

本文主要是介绍FreeRTOS二值信号量,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

一、信号量的概念

1、信号量的基本概念

2、信号量的分类

二、二值信号量简介

三、二值信号量相关API

1、创建二值信号量

2、释放二值信号量

3、获取二值信号量

四、二值信号量实操

1、实验需求

2、CubeMX配置

3、代码实现


一、信号量的概念

1、信号量的基本概念

信号量(Semaphore),是在多任务环境下使用的一种机制,是可以用来保证两个或多个关键代 码段不被并发调用。

信号量这个名字,我们可以把它拆分来看,信号可以起到通知信号的作用,然后我们的量还可以 用来表示资源的数量,当我们的量只有0和1的时候,它就可以被称作二值信号量,只有两个状 态,当我们的那个量没有限制的时候,它就可以被称作为计数型信号量

信号量也是队列的一种

2、信号量的分类

二值信号量(同步应用)

计数信号量(资源管理)

互斥信号量(互斥访问)

递归互斥信号量(简要了解即可)

二、二值信号量简介

二值信号量其实就是一个长度为1,大小为零的队列只有0和1两种状态,通常情况下,我们用它来进行互斥访问或任务同步

互斥访问:比如门跟钥匙,只有获取到钥匙才可以开门

任务同步:比如学习完知识点才能写博客

三、二值信号量相关API

函数描述
xSemaphoreCreateBinary()使用动态方式创建二值信号量
xSemaphoreCreateBinaryStatic()使用静态方式创建二值信号量
xSemaphoreGive()释放信号量
xSemaphoreGiveFromISR()在中断中释放信号量
xSemaphoreTake()获取信号量
xSemaphoreTakeFromISR()在中断中获取信号量

1、创建二值信号量

SemaphoreHandle_t xSemaphoreCreateBinary( void );

参数:

返回值:

  • 成功,返回对应二值信号量的句柄;
  • 失败,返回 NULL 。

2、释放二值信号量

BaseType_t xSemaphoreGive( SemaphoreHandle_t xSemaphore );

参数:

  • xSemaphore:要释放的信号量句柄

返回值:

  • 成功,返回 pdPASS ;
  • 失败,返回 errQUEUE_FULL 。

3、获取二值信号量

BaseType_t xSemaphoreTake( SemaphoreHandle_t xSemaphore,TickType_t xTicksToWait );

参数:

  • xSemaphore:要获取的信号量句柄
  • xTicksToWait:超时时间,0 表示不超时,portMAX_DELAY表示卡死等待;

返回值:

  • 成功,返回 pdPASS ;
  • 失败,返回 errQUEUE_FULL 。

四、二值信号量实操

1、实验需求

创建一个二值信号量,按下 KEY1 则释放信号量,按下 KEY2 获取信号量。

2、CubeMX配置

这里已经将FreeRTOS移植到STM32F103C8T6,具体操作流程看前面的文章。

 查看原理图配置按键引脚

这里已经将FreeRTOS移植到STM32F103C8T6,具体操作流程看前面的文章。

创建两个任务用来放入和获取信号量

创建一个二值信号量

3、代码实现

uart.c 重定向printf

#include "stdio.h"
int fputc(int ch,FILE *f)
{unsigned char temp[1] = {ch};HAL_UART_Transmit(&huart1,temp,1,0xffff);return ch;
}

需要打开魔术棒勾上红框内选项实现串口打印

打开freertos.c并添加代码

void StartTaskGive(void const * argument)
{for(;;){if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET){osDelay(20);if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET){                                               if(xSemaphoreGive(myBinarySemHandle) == pdPASS) printf("二值信号量获取成功\r\n");elseprintf("二值信号量放释放失败\r\n");}while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET);}osDelay(10);}
}void StartTaskTake(void const * argument)
{for(;;){if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET){osDelay(20);if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET){// 0 表示不超时,portMAX_DELAY表示卡死等待      if(xSemaphoreTake(myBinarySemHandle, portMAX_DELAY ) == pdPASS) printf("二值信号量获取成功\r\n");elseprintf("二值信号量获取失败\r\n");}while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET);}osDelay(10);}
}

可见释放二值信号量后便可以成功获取获取二值信号量,但是只能释放多次就只有第一次能释放成功,同时获取也是只能获取一次(前提是已经释放),多次获取也只有第一次能获取成功

注意:

  1. 创建后的二值信号量原先代码和修改后的代码如下:由于CubeMX内置函数中存在bug,即在创建二值信号量时就已经释放二值信号量,所以会出现不按下KEY1(释放二值信号量)时,按下KEY2就直接能获取二值信号量,如下:
  2. 若将获取二值信号量函数的第二个参数修改成卡斯等待,即portMAX_DELAY,如下
    xSemaphoreTake(myBinarySemHandle, portMAX_DELAY )

    那么会出现在没释放二值信号量前按下KEY2(获取二值信号量),那么会一直卡死等待释放二值信号量,当KEY1一按下,二值信号量会被立马获取,此时就不存在二值信号量,当KEY1再次按下时,还是会释放成功,如下:

这篇关于FreeRTOS二值信号量的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/985176

相关文章

FreeRTOS-基本介绍和移植STM32

FreeRTOS-基本介绍和STM32移植 一、裸机开发和操作系统开发介绍二、任务调度和任务状态介绍2.1 任务调度2.1.1 抢占式调度2.1.2 时间片调度 2.2 任务状态 三、FreeRTOS源码和移植STM323.1 FreeRTOS源码3.2 FreeRTOS移植STM323.2.1 代码移植3.2.2 时钟中断配置 一、裸机开发和操作系统开发介绍 裸机:前后台系

FreeRTOS内部机制学习03(事件组内部机制)

文章目录 事件组使用的场景事件组的核心以及Set事件API做的事情事件组的特殊之处事件组为什么不关闭中断xEventGroupSetBitsFromISR内部是怎么做的? 事件组使用的场景 学校组织秋游,组长在等待: 张三:我到了 李四:我到了 王五:我到了 组长说:好,大家都到齐了,出发! 秋游回来第二天就要提交一篇心得报告,组长在焦急等待:张三、李四、王五谁先写好就交谁的

FreeRTOS学习笔记(六)队列

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、队列的基本内容1.1 队列的引入1.2 FreeRTOS 队列的功能与作用1.3 队列的结构体1.4 队列的使用流程 二、相关API详解2.1 xQueueCreate2.2 xQueueSend2.3 xQueueReceive2.4 xQueueSendFromISR2.5 xQueueRecei

FreeRTOS学习笔记(二)任务基础篇

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、 任务的基本内容1.1 任务的基本特点1.2 任务的状态1.3 任务控制块——任务的“身份证” 二、 任务的实现2.1 定义任务函数2.2 创建任务2.3 启动任务调度器2.4 任务的运行与切换2.4.1 利用延时函数2.4.2 利用中断 2.5 任务的通信与同步2.6 任务的删除2.7 任务的通知2

FreeRTOS学习笔记(四)Freertos的中断管理及临界保护

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、Cortex-M 中断管理1.1 中断优先级分组1.2 相关寄存器1.3 相关宏定义1.4 FreeRTOS 开关中断 二、临界段及其保护2.1 taskENTER_CRITICAL( ) 和 taskEXIT_CRITICAL( )2.2 taskENTER_CRITICAL_FROM_ISR( )

龙芯+FreeRTOS+LVGL实战笔记(新)——05部署主按钮

本专栏是笔者另一个专栏《龙芯+RT-Thread+LVGL实战笔记》的姊妹篇,主要的区别在于实时操作系统的不同,章节的安排和任务的推进保持一致,并对源码做了改进和优化,各位可以先到本人主页下去浏览另一专栏的博客列表(目前已撰写36篇,图1所示),再决定是否订阅。此外,也可以前往本人在B站的视频合集(图2所示)观看所有演示视频,合集首个视频链接为: 借助RT-Thread和LVGL

Linux多线程——POSIX信号量与环形队列版本之生产消费模型

文章目录 POSIX信号量POSIX的操作初始化销毁等待信号量(申请资源)发布信号量(放下资源) 环形队列之生产消费模型 POSIX信号量 POSIX信号量和System V信号量是不同的标准 但是实现的功能是一样的,都是为了解决同步的问题 我们说信号量指的就是资源的数量 在生产者与消费者模型里面,生产者与消费者所认为的资源是不同的 生产者认为空间是资源,因为每次都要

信号与信号量的区别[转]

信号量(Semaphore),有时被称为信号灯,是在多环境下使用的一种设施,是可以用来保证两个或多个关键代码段不被并发调用。在进入一个关键代码段之前,线程必须获取一个信号量;一旦该关键代码段完成了,那么该线程必须释放信号量。其它想进入该关键代码段的线程必须等待直到第一个线程释放信号量。为了完成这个过程,需要创建一个信号量VI,然后将Acquire Semaphore VI以及Release Se

FreeRTOS学习笔记—④RTOS通信管理篇/同步互斥与通信(正在更新中)

二、RTOS的核心功能   RTOS的核心功能块主要分为任务管理、内核管理、时间管理以及通信管理4部分,框架图如下所示:   (1)任务管理:负责管理和调度任务的执行,确保系统中的任务能够按照预期运行。   (2)内核管理:负责系统核心功能的管理,包括内存、中断、异常处理和系统启动等。   (3)时间管理:负责所有与时间相关的操作,包括系统时钟、定时器、任务延迟和周期性任务的执行。   (4)通

基于STM32的RTOS--freertos的使用(HAL实现多任务)

一:STM32cubemx配置         1:工程建立                         (1)打开stm32cubemx  点击进入芯片选择页面                                         (2)选择对应的芯片型号双击         2:调试接口配置                  3:时钟设置