FreeRTOS - 二值信号量

文章介绍了FreeRTOS操作系统中二值信号量的概念和应用,包括创建、释放和获取信号量的函数,以及在中断处理中的使用。在示例中,通过二值信号量实现了按键中断和任务之间的通信,用于控制任务的执行和优化CPU利用率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.信号量定义

信号量(semaphore),多任务环境下使用的一种设施,负责协调多个任务,以保证任务能够正确,合理的使用公共资源。

二.二值信号量应用函数

函数原型

#include “FreeRTOS.h”

#include “semphr.h”

SemaphoreHandle_t xSemaphoreCreateBinary( void );

功能概述

创建二值信号量,并返回信号量句柄。

创建完成后,信号量状态为空。

参数

None

返回值

NULL:堆空间不足

Any other value :信号量句柄

注意事项

configSUPPORT_DYNAMIC_ALLOCATION必须置为1

函数原型

#include “FreeRTOS.h”

#include “semphr.h”

BaseType_t xSemaphoreGive( SemaphoreHandle_t ① xSemaphore );

功能概述

任务间释放信号量

参数

①:信号量句柄

返回值

pdPASS:信号量释放成功

pdFAIL: 此信号量,拥有者不是任务,任务需获取到信号量,才可以释放信号

注意事项

None

函数原型

#include “FreeRTOS.h”

#include “semphr.h”

BaseType_t xSemaphoreGiveFromISR( ①SemaphoreHandle_t xSemaphore,

②BaseType_t *pxHigherPriorityTaskWoken );

功能概述

中断,任务间释放信号量

参数

①:信号量句柄

②:表示在释放信号量成功后,是否进行上下文切换,保证高优先级任务立刻执行,FreeRTOS V7.3.0以后变为可选参数,直接设置为NULL

返回值

pdTRUE:信号量释放成功

errQUEUE_FULL:信号量已经可用

注意事项

None

函数原型

#include “FreeRTOS.h”

#include “semphr.h”

BaseType_t xSemaphoreTake( ①SemaphoreHandle_t xSemaphore,

②TickType_t xTicksToWait );

功能概述

任务间获取信号量

参数

①:信号量句柄

②:如果信号量不是立即可用,任务则进入阻塞状态,传入的等待多少个tick值,传入portMAX_DELAY任务将无限期等待中

返回值

pdPASS:信号量获取成功

pdFAIL:信号量获取失败

注意事项

只能在执行的任务中调用

函数原型

#include “FreeRTOS.h”

#include “semphr.h”

BaseType_t xSemaphoreTakeFromISR( ①SemaphoreHandle_t xSemaphore,

②signed BaseType_t *pxHigherPriorityTaskWoken );

功能概述

中断中获取信号量

参数

①:信号量句柄

②:表示在获取信号量成功后,是否进行上下文切换,保证高优先级任务立刻执行,FreeRTOS V7.3.0以后变为可选参数,直接设置为NULL

返回值

pdPASS:信号量获取成功

pdFAIL:信号量获取失败

注意事项

只能在中断中调用,没有阻塞功能

三.任务

3.1CubeMX生成二值信号量

在FreeRTOS中找到Times and Semaphore

在Binary Semaphores中添加

四.代码实现

  • gpio.c

中断回调函数在gpio中实现

extern osSemaphoreId CPUPrintfBinarySemHandle;
//按键检测回调函数
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
     if(Key1_Pin == GPIO_Pin)                                                 //判断按下的GPIO
     {
        if ( HAL_GPIO_ReadPin(GPIOA,GPIO_Pin) == GPIO_PIN_RESET)              //按下按键,导通
         {
//            HAL_Delay(10);                                                  //软件去抖动  
            if( HAL_GPIO_ReadPin(GPIOA,GPIO_Pin) == GPIO_PIN_RESET)
            {
//               HAL_GPIO_WritePin(GPIOB,Led_Red_Pin,GPIO_PIN_RESET);
//               HAL_GPIO_WritePin(GPIOB,Led_Green_Pin,GPIO_PIN_SET);
                 /*建立标志位*/
                 keyStatus = Key_down;
                 printf("按键已按下/r/n");
                 xSemaphoreGiveFromISR(CPUPrintfBinarySemHandle,NULL);
            }
         }
         else
         {
            if( HAL_GPIO_ReadPin(GPIOA,GPIO_Pin) == GPIO_PIN_SET)             // 高电平,未准备好      
            {   
//              HAL_Delay(10);                                               //软件去抖动  
                if( HAL_GPIO_ReadPin(GPIOA,GPIO_Pin) == GPIO_PIN_SET)
                {                
           
//                    HAL_GPIO_WritePin(GPIOB,Led_Red_Pin,GPIO_PIN_SET);      //关闭红灯
//                    HAL_GPIO_WritePin(GPIOB,Led_Green_Pin,GPIO_PIN_RESET);  //开启绿灯
                    /*建立标志位*/
                    keyStatus = Key_up;
                    printf("按键已抬起/r/n");
                }
            }
         }
     }
}
  • FreeRTOS.c

void Key_Task(void const * argument)
{
  /* USER CODE BEGIN Key_Task */
    keyStatus = Key_reset;
  /* Infinite loop */
    for(;;)
    {
    if(xSemaphoreTake(CPUPrintfBinarySemHandle,portMAX_DELAY) == pdPASS)
    {
        //挂起LED任务
        memset(u8TaskListBuff,0,400);
        vTaskGetRunTimeStats((char*)u8TaskListBuff);
        printf("Name      Abs Time        Time\r\n");
        printf("******************************************************\r\n");
        printf("%s",u8TaskListBuff);
        printf("******************************************************\r\n");
        keyStatus = Key_reset;
    }
  }
  /* USER CODE END Key_Task */
}
  • vTaskGetRunTimeStats

vTaskGetRunTimeStats() 来协助分析操作系统当前 task CPU 占用状态,以帮助优化 task 优先级

函数原型为:

voidvTaskGetRunTimeStats( char *pcWriteBuffer )

CubeMX配置

等待信号量到,才开始执行任务。提高CPU占有利用率

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值