0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

FreeRTOS的事件标志组

汽车电子技术 来源:玩转单片机 作者: Julian 2023-02-10 15:58 次阅读

之前介绍了使用信号量来完成同步,但是使用信号量来同步的话,任务只能与单个的事件或任务进行同步。有时候某个任务可能会需要与多个事件或任务进行同步,此时信号量就无能为力了。FreeRTOS 提供了一个可选的解决方法,那就是事件标志组。

事件标志位可以理解为一个Bit位,多个事件位就组成了事件标志组,FreeRTOS可选8个事件标志位或者24个事件标志位,具体是由configUSE_16_BIT_TICKS来确定,它为1的时候是8个标准位,为0时是24个标志位!

创建标志组

EventGroupHandle_t xEventGroupCreate( void );

返回值:

创建失败返回NULL,创建成功返回句柄

置位API函数

EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,
                                 const EventBits_t uxBitsToSet );

参数

xEventGroup:需要操作的事件标志组的句柄

uxBitsToSet:写入数值,例如0x09就表示置位第0位和第三位

读取事件组的位

EventBits_t xEventGroupWaitBits( const EventGroupHandle_t xEventGroup,
                                 const EventBits_t uxBitsToWaitFor,
                                 const BaseType_t xClearOnExit,
                                 const BaseType_t xWaitForAllBits,
                                 TickType_t xTicksToWait );

参数:

xEventGroup:事件标志组的句柄

uxBitsToWaitFor:需要等待的标志位

xClearOnExit:是否需要清除标志位

xWaitForAllBits:是否等待所有设定标志位

xTicksToWait:最大等待时间

注意:更多API函数,请参考官方相关

附上简单使用应用

#include "stm32f10x.h"
#include 
#include "FreeRTOS.h"
#include "task.h"
#include "event_groups.h"


#define START_TASK_PRIO 1      //任务优先级
#define START_STK_SIZE 128      //任务堆栈大小
TaskHandle_t StartTask_Handler;   //任务句柄
void start_task(void *pvParameters);//任务函数


#define LED0_TASK_PRIO 2       //任务优先级
#define LED0_STK_SIZE 50       //任务堆栈大小
TaskHandle_t LED0Task_Handler;     //任务句柄
void led0_task(void *p_arg);     //任务函数


EventGroupHandle_t Event_Handle = NULL;//事件标志组的句柄


void LED_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;        //定义结构体变量

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);  //开启时钟

  GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;            //选择你要设置的IO口
  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;      //设置推挽输出模式
  GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;     //设置传输速率
  GPIO_Init(GPIOC,&GPIO_InitStructure);                //初始化GPIO

  GPIO_SetBits(GPIOC,GPIO_Pin_0);             //将LED端口拉高,熄灭LED
}


int main( void ) 
{
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组 4
  LED_Init(); //初始化 LED
  //创建任务标志组
  Event_Handle = xEventGroupCreate();
  //置位标志位
  xEventGroupSetBits( ( EventGroupHandle_t) Event_Handle,
            ( EventBits_t )       0x08       );

  //创建开始任务
  xTaskCreate(
    (TaskFunction_t )start_task,     //任务函数
    (const char* )"start_task",     //任务名称
    (uint16_t )START_STK_SIZE,       //任务堆栈大小
    (void* )NULL,             //传递给任务函数的参数
    (UBaseType_t )START_TASK_PRIO,     //任务优先级
    (TaskHandle_t* )&StartTask_Handler  //任务句柄 
  );
  vTaskStartScheduler();  //开启调度
}
//开始任务函数
void start_task(void *pvParameters)
{
  taskENTER_CRITICAL();   //进入临界区
  //创建 LED0 任务
  xTaskCreate(
    (TaskFunction_t )led0_task, 
    (const char* )"led0_task", 
    (uint16_t )LED0_STK_SIZE, 
    (void* )NULL,
    (UBaseType_t )LED0_TASK_PRIO,
    (TaskHandle_t* )&LED0Task_Handler
  );
  vTaskDelete(StartTask_Handler); //删除开始任务
  taskEXIT_CRITICAL();   //退出临界区
}


//LED0 任务函数
void led0_task(void *pvParameters)
{
  while(1)
  {
    xEventGroupWaitBits( ( EventGroupHandle_t ) Event_Handle,  //句柄
               ( EventBits_t        ) 0x08,      //需要等待的位
               ( BaseType_t         ) pdTRUE ,    //需要清零
               ( BaseType_t         ) pdTRUE,      //等待所有设定标志位
               ( TickType_t         ) portMAX_DELAY );//死等待

    if(GPIO_ReadInputDataBit( GPIOC, GPIO_Pin_0))
    {
      GPIO_ResetBits( GPIOC, GPIO_Pin_0);
    }
    else
    {
      GPIO_SetBits( GPIOC, GPIO_Pin_0);
    }
    //置位标志位
    xEventGroupSetBits( ( EventGroupHandle_t) Event_Handle,
              ( EventBits_t )       0x08         );

    vTaskDelay(400);
  }
}

注意:如果LED0任务中的置位函数,那么LED0函数只会运行一次,因为标志位已经清除了,需要再次置位标志位才会继续运行!

--END--

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FreeRTOS
    +关注

    关注

    12

    文章

    473

    浏览量

    61349
  • 信号量
    +关注

    关注

    0

    文章

    53

    浏览量

    8257
  • 事件标志组
    +关注

    关注

    0

    文章

    3

    浏览量

    1239
收藏 人收藏

    评论

    相关推荐

    使用STM32CubeMX生成的FreeRTOS系统中,似乎没有新封装的事件标志,怎么解决?

    使用STM32CubeMX生成的FreeRTOS系统中,似乎没有新封装的事件标志,如果按照原生的FreeRTOS使用事件标志
    发表于 03-22 08:34

    使用FreeRTOS系统事件标志有些收不到是怎么回事?

    教下,使用FreeRTOS的的件标志, 任务貌似有些标志位收不到,是怎么回事啊 ? 比如事件标志
    发表于 04-26 06:53

    #硬声创作季 #FreeRTOSFreeRTOS-23 事件标志及实验-4

    RTOSFreeRTOS
    水管工
    发布于 :2022年11月11日 17:37:38

    转:freeRTOS事件学习

    像其他RTOS一样,freeRTOS同样有对事件标志位的创建和处理,在中断中可以通过事件传递信息给其他的任务,那么如何创建事件呢?要使用创建Event的API,首先必须配置,且包含
    发表于 08-12 18:29

    转:第18章 FreeRTOS事件标志

    第18章FreeRTOS事件标志 前面的章节我们已经讲解了任务管理和时间管理,从本章节开始讲解任务间的通信和同步机制。首先讲解任务间的通信和同步机制之一,事件标志
    发表于 09-02 12:40

    转:第26章 FreeRTOS任务事件标志

    本章节为大家讲解FreeRTOS事件标志的另一种实现方式----基于任务通知(Task Notifications)的事件标志,这里我们
    发表于 09-08 06:48

    第13章 事件标志

    转rtx操作系统前面的章节我们已经讲解了任务管理和时间管理,从本章节开始讲解任务间的通信和同步机制。首先讲解任务间的通信和同步机制之一,事件标志。 本章教程配套的例子含Cortex-M3内核
    发表于 10-05 09:15

    【NUCLEO-F412ZG试用体验】FreeRTOS_事件标志实现任务和中断的同步

    使用事件标志可以实现任务和任务之间以及任务和中断之间的通信或者同步。首先说明,本例程参考了《安富莱_STM32-V5开发板_FreeRTOS教程(V1.0)》,是在上上期报告的基础上,把按键中断由
    发表于 12-28 21:19

    怎么才能让任务等待到事件标志后一直执行并且还要把事件标志清零?

    一个任务等待事件标志执行有挂起和不挂起之分,等待到事件标志就执行一次并且把事件标志清零,等待不到事件
    发表于 09-20 03:49

    UCOS3的事件标志

    我理解的事件标志主要功能就是根据同步标志组里面的信号的标志位来执行语句。比如有A,B,C三个信号,当我们有一个任务D需要ABC三个信号都到了之后再去执行任务D.这时候就可以用到任务
    发表于 05-11 14:27

    freertos中断置位事件标志输出Error的解决办法?

    新人求教,在原子里的程序加了置位标志,串口输出Error:..\FreeRTOS\portable\RVDS\ARM_CM3\port.c,680,但是不影响程序的运行,这个是什么原因
    发表于 06-18 09:00

    【转载】AT32 FreeRTOS应用笔记

    ........................................83例程介绍 ...................................................... 85FreeRTOS 事件标志
    发表于 08-16 11:56

    怎样去设置FreeRTOS事件标志的事件位呢

    事件标志是什么意思呢?怎样去设置FreeRTOS事件标志的事件位呢?
    发表于 02-28 06:44

    freeRTOS用于任务之间同步的手段事件标志

    freeRTOS中还有一种可以用于任务之间同步的手段 — 事件标志组。
    的头像 发表于 02-10 11:10 1170次阅读

    FreeRTOS事件标志组介绍

    1、事件位(事件标志) 事件位用来表明某个事件是否发生,事件位通常用作事件标志,比如下面的几个例子: ● 当收到一条消息并且把这条消息处理掉以后就可以将某个位(标志)置 1,当队列中没有消息需要处理
    的头像 发表于 07-06 17:22 395次阅读