<FreeRTOS入门第九节>事件标志位
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 前言
- 一、事件标志位是什么?
- 二、API介绍
- 1.事件标志位的创建
- 2.事件标志位的设置
- 3.事件标志位清除
- 4.获取某一位的事件清除函数
- 三、案例
- 总结
前言
今天又学习了FreeRTOS的事件标志位的处理。呀呼。
一、事件标志位是什么?
事件标志位能有效的解决一个任务与多个任务的同步,这是信号量不能解决的。
事件标志位就是指定一个位来存储一个任务或者事件的标志,是运行还是没有运行,运行就将这位置‘1’,没有运行就置‘0’,然后在获取这个位的标志来判断这个任务或者事件是否在运行。
二、API介绍
1.事件标志位的创建
/*动态创建事件标志位形参:无EventGroupHandle_t返回值的函数成功:其他值失败:NULL
*/
EventGroupHandle_t xEventGroupCreate( void )
2.事件标志位的设置
/*设置事件标志位的值置‘1’xEventGroup:事件标志位的句柄uxBitsToSet:设置的位(后面看案例,这里不解释)EventBits_t的返回函数成功:pdTRUE失败:pdFLASE
*/
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,const EventBits_t uxBitsToSet )
3.事件标志位清除
/*清除事件标志位xEventGroup:事件标志位的句柄uxBitsToClear:设置的位(后面看案例,这里不解释)EventBits_t的返回函数成功:pdTRUE失败:pdFLASE
*/
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup,const EventBits_t uxBitsToClear )
4.获取某一位的事件清除函数
/*获取某一位的事件标志位xEventGroup:事件标志位的句柄uxBitsToWaitFor:事件的标志位位置(可以使用|来定义多个位)xClearOnExit:退出uxBitsToWaitFor时是否清除标志位,pdTRUE开启,pdFLASE关闭xWaitForAllBits:pdTRUE当uxBitsToWaitFor的所以事件标志位都置‘1’才会返回。pdFALSE当uxBitsToWaitFor的某一个位的事件标志位置‘1’就会返回xTicksToWait:事件阻塞时间EventBits_t的返回函数成功:pdTRUE失败:pdFLASE
*/
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,const EventBits_t uxBitsToWaitFor,const BaseType_t xClearOnExit,const BaseType_t xWaitForAllBits,TickType_t xTicksToWait )
三、案例
main.c
#include "main.h"
#include "usart.h"
#include "gpio.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
#include "Timers.h"
#include "event_groups.h"
#include "stdio.h"
#include "Key.h"
#ifdef __GNUC__ //printf重定向
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{HAL_UART_Transmit(&huart1, (uint8_t*)&ch,1,HAL_MAX_DELAY);return ch;
}TaskHandle_t HandlerTask1;
TaskHandle_t Task_Name4;BaseType_t xReturn;
SemaphoreHandle_t Task1semaphore;TimerHandle_t AutoTimerTask;
TimerHandle_t OneTimerTask;EventGroupHandle_t EventGroupTask1;void SystemClock_Config(void);
StackType_t xTask3Static[128];
StaticTask_t xTaskTCB;StackType_t xIdle3Static[128];
StaticTask_t xIdleTCB;StackType_t xTimerStatic[526];
StaticTask_t xTimerTCB;
void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,StackType_t ** ppxIdleTaskStackBuffer,uint32_t * pulIdleTaskStackSize ){*ppxIdleTaskTCBBuffer=&xIdleTCB; *ppxIdleTaskStackBuffer=xIdle3Static;*pulIdleTaskStackSize=128;
}
void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer,StackType_t ** ppxTimerTaskStackBuffer,uint32_t * pulTimerTaskStackSize ){* ppxTimerTaskTCBBuffer=&xTimerTCB;* ppxTimerTaskStackBuffer=xTimerStatic;* pulTimerTaskStackSize=526;
}void Task1Function( void * param){for(;;){vTaskDelay(100);}
}
void Task2Function(void* param){uint8_t num;EventBits_t EventFlag;for(;;){num=Key_config();if(EventGroupTask1!=NULL){switch(num){case 1:xEventGroupSetBits(EventGroupTask1,(1<<0));break;case 2:xEventGroupSetBits(EventGroupTask1,(1<<2));break;case 3:#if 1EventFlag=xEventGroupWaitBits((EventGroupHandle_t) EventGroupTask1,(EventBits_t) (1<<0)|(1<<2),(BaseType_t) pdTRUE,(BaseType_t) pdFALSE,(TickType_t) 50);#elseEventFlag=xEventGroupGetBits(EventGroupTask1);//xEventGroupClearBits(EventGroupTask1,(1<<0)|(1<<1));#endifprintf("Event->Flag:%d\r\n",EventFlag);break;}}//vTaskDelay(100);}
}
void Task3Funtion(void* param){TickType_t st_time=xTaskGetTickCount(); while(1){uint32_t num =1;xTaskDelayUntil(&st_time,30);}}void Task4Funtion(void* param){taskENTER_CRITICAL();//创建标志位EventGroupTask1=xEventGroupCreate();//创建任务xReturn=xTaskCreate(Task1Function,"Task1",128,NULL,2,&HandlerTask1);xTaskCreate(Task2Function,"Task2",128,NULL,2,NULL);xTaskCreateStatic(Task3Funtion,"Task3",128,NULL,2,xTask3Static,&xTaskTCB);if(xReturn == pdPASS){uint8_t buffS[20]="Task1 Create OK..\r\n";HAL_UART_Transmit(&huart1,(uint8_t*)buffS,strlen(buffS)*sizeof(char),HAL_MAX_DELAY);}vTaskDelete(Task_Name4);taskEXIT_CRITICAL();
}int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_USART1_UART_Init();xTaskCreate(Task4Funtion,"Task4",600,NULL,1,&Task_Name4);vTaskStartScheduler();while (1){}}void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;RCC_OscInitStruct.HSIState = RCC_HSI_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK){Error_Handler();}
}void Error_Handler(void)
{__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */
}#ifdef USE_FULL_ASSERTvoid assert_failed(uint8_t *file, uint32_t line)
{}
#endif /* USE_FULL_ASSERT */
效果展示
总结
事件标志位总的说就是用来记录任务或者事件的运行状态的。
有些人心如花木,皆向阳而生 --《剑来》
何为凡人,何为仙,岂闻韶华尽何年,回首沧桑,此恨绵绵,风月如剑,看我破天。道不尽仙凡殊途,尽人间 --《凡人修仙传》
<FreeRTOS入门第九节>事件标志位相关推荐
- FreeRTOS源码分析与应用开发07:事件标志组
目录 1. 概述 2. 事件标志组类型 3. 创建事件标志组 4. 删除事件标志组 5. 设置事件标志位 5.1 任务级设置 5.2 中断级设置 6. 清除事件标志位 6.1 任务级清除 6.2 中断 ...
- FreeRTOS记录(七、FreeRTOS信号量、事件标志组、邮箱和消息队列、任务通知的关系)
我们在前面单独介绍过FreeRTOS的任务通知和消息队列, 但是在FreeRTOS中任务间的通讯还有信号量,邮箱,事件组标志等可以使用 这篇文章就这些成员与消息队列和任务通知的关系进行说明分析 ..增 ...
- FreeRTOS 事件标志组 ——提高篇
假设你已经看过FreeRTOS 事件标志组这篇随笔了. 之前的基础篇,真的就只是简单了解一下,相当于大学实验室的实验,但是,我们实际公司项目中,需要更多地思考,就算我们之前只是学习了基础概念以及基础语 ...
- FreeRTOS 任务计数信号量,任务二值信号量,任务事件标志组,任务消息邮箱
以下基础内容转载自安富莱电子: http://forum.armfly.com/forum.php 本章节为大家讲解 FreeRTOS 计数信号量的另一种实现方式----基于任务通知(Task Not ...
- 【FreeRTOS】小白进阶之如何使用FreeRTOS事件标志组
事件标志组使用浅析. 1.头文件声明 #include "FreeRTOS.h" #include "task.h" #include "event_ ...
- FreeRTOS操作系统——任务通知模拟消息邮箱及事件标志组(十八)
FreeRTOS操作系统学习 文章目录 FreeRTOS操作系统学习 一.消息邮箱API函数 二.消息邮箱实验 三.事件标志组实验 总结 一.消息邮箱API函数 任务通知也可用来向任务发送数据,但是相 ...
- FreeRTOS基于任务通知的信号量 事件标志组 消息邮箱
FreeRTOS创建的任务都有一个任务控制块. 任务控制块本质上是一个结构体变量,用于记录任务的相关的消息. 结构体变量中有一个专门用于任务通知的32位变量ulNotifiedValue. ulNot ...
- STM32中事件标志位与中断标志位
事件标志位:FlagStatus 中断标志位:ITStatus 当一个事件发生时,事件标志位由硬件置1,此时无论是否使能中断 若在此时使能中断将产生中断,其实中断标志已经被置1(产生事件的时候) 可见 ...
- RTX5 | 事件标志组04 - 线程同步(逻辑与)
文章目录 一.前言 二.实验目的 三.API 3.1.osEventFlagsWait 四.代码 4.1.main.h 4.2.main.c 五.Event Recorder 5.1.分别长按按键KE ...
最新文章
- 手动部署OpenStack环境(三:OpenStack环境预配置)
- 重新分区_手机DATA重新分区教程(超详细)
- MySQL的索引类型及简单优化
- AI 假冒老板骗取 173 万!
- adodb.connection id password windows用户_Windows 12发布了?一款号称可以取代win10的山寨Windows系统...
- 笔记.cloudflare 的橙色云代理ssl坑
- 命令行 蓝牙_蓝牙键盘接入UOS系统的方法
- k2路由器linux系统,【路由器】斐讯K1/K2刷专版潘多拉固件以及教程
- 在线网上书店管理系统
- nginx 启动 报错,80端口被占用问题,80端口无法杀掉问题
- 如何使用 Skopeo 做一个优雅的镜像搬运工
- 问题解决:尝试解决maven依赖找不到的n种姿势
- 智慧园区数据可视化解决方案
- 2021年嵌入式面试题汇总(最新经典)
- 1000以内的“完数”
- dma-buf 由浅入深(一) —— 最简单的 dma-buf 驱动程序
- 【2019.09.30】“福大同好”——原型设计展示~(软工实践第四次作业)
- hdu2546-饭卡???
- 03,redis多键值对,哈希散列hset
- 32_STM32内部温度传感器实验