系列文章目录
文章目录
- 系列文章目录
- 事件标志组
- 事件标志组API函数
- 实验测试
事件标志组
事件标志位:用一个位来表示事件是否可以发生。
事件标志组是一组事件标志位的集合
特点:
1.每一个位表示一个事件(高8位不是)
2.每一位事件的含义由用户自己决定,1表示事件发生了,0表示事件未发生
3.任意任务或中断都可以读写这些位
4.可以等待某一位成立或等待多位同时成立
一个事件组包含了一个EventBits_t数据类型的变量,是一个16位或32位的无符号数据类型
typedef TickType_t EventBits_t;
#if ( configUSE_16_BIT_TICKS = = 1 )
typedef uint16_t TickType_t;
#else
typedef uint32_t TickType_t;
#endif
但是高8位用作存储事件标志组的控制信息,低24位用作存储事件标志,最多存储24个事件标志。
队列和信号量在事件发生的时候,只能有一个任务被唤醒,而且队列的数据在读取后就消失了,信号量在获取后就减少了;
事件标志组不同,事件发生的时候,会唤醒所有符合条件的任务,且可以选择保留事件或者清除事件。
事件标志组API函数
函数 | 描述 |
---|---|
xEventGroupCreate() | 使用动态方式创建事件标志组 |
xEventGroupCreateStatic() | 使用静态方式创建事件标志组 |
xEventGroupClearBits() | 清零事件标志位 |
xEventGroupClearBitsFromISR() | 在中断中清零事件标志位 |
xEventGroupSetBits() | 设置事件标志位 |
xEventGroupSetBitsFromISR() | 在中断中设置事件标志位 |
xEventGroupWaitBits() | 等待事件标志位 |
xEventGroupSync() | 设置事件标志位,并等待事件标志位 |
1.动态创建API函数
EventGroupHandle_t xEventGroupCreate ( void ) ;
返回值:
NULL:事件标志组创建失败
其他值:事件标志组创建成功,返回其句柄
2.清除事件标志位API函数
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup,const EventBits_t uxBitsToClear )
形参:
xEventGroup:待操作的事件标志组句柄
uxBitsToSet :待清零的事件标志位
返回值:
整数 :清零事件标志位之前事件组中事件标志位的值
3.设置事件标志位API函数
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,const EventBits_t uxBitsToSet )
形参:
xEventGroup :待操作的事件标志组句柄
uxBitsToSet :待设置的事件标志位
返回值:
整数:函数返回时,事件组中的事件标志位值
4.等待事件标志位API函数
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToWaitFor,
const BaseType_t xClearOnExit,
const BaseType_t xWaitForAllBits,
TickType_t xTicksToWait )
形参:
xEvenrGroup :等待的事件标志组句柄
uxBitsToWaitFor:等待的事件标志位,可以用逻辑或等待多个事件标志位
xClearOnExit:等待到事件标志位后,清除对应的事件标志位,pdTRUE 清除uxBitsToWaitFor指定位,pdFALSE不清除
xWaitForAllBits :等待 uxBitsToWaitFor 中的所有事件标志位(逻辑与)pdTRUE等待的位全部为1,pdFALSE某个为1
xTicksToWait:等待的阻塞时间
返回值:
等待的事件标志位值 :等待事件标志位成功,返回等待到的事件标志位
其他值 :等待事件标志位失败,返回事件组中的事件标志位
可以等待某一位,也可以等待多位
5.同步函数
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet,
const EventBits_t uxBitsToWaitFor,
TickType_t xTicksToWait)
形参:
xEventGroup :等待事件标志所在事件组
uxBitsToSet :达到同步点后,要设置的事件标志
uxBitsToWaitFor: 等待的事件标志
xTicksToWait: 等待的阻塞时间
返回值:
等待的事件标志位值 :等待事件标志位成功,返回等待到的事件标志位
其他值 :等待事件标志位失败,返回事件组中的事件标志位
实验测试
任务1:创建任务2和任务3,并且创建事件标志组
任务2;将事件标志组相应事件位置1,模拟事件发生
任务3:同时等待事件标志组中的多个事件位发生,发生全部置1进行处理
EventGroupHandle_t eventgroup_handle;
#define EVENTBIT_0 (1 << 0)
#define EVENTBIT_1 (1 << 1)
/**
* @brief FreeRTOS例程入口函数
* @param 无
* @retval 无
*/
void freertos_demo(void)
{
xTaskCreate((TaskFunction_t ) start_task,
(char * ) "start_task",
(configSTACK_DEPTH_TYPE ) START_TASK_STACK_SIZE,
(void * ) NULL,
(UBaseType_t ) START_TASK_PRIO,
(TaskHandle_t * ) &start_task_handler );
vTaskStartScheduler();
}
void start_task( void * pvParameters )
{
taskENTER_CRITICAL(); /* 进入临界区 */
eventgroup_handle = xEventGroupCreate();
if(eventgroup_handle != NULL)
{
printf("事件标志组创建成功!!\r\n");
}
xTaskCreate((TaskFunction_t ) task1,
(char * ) "task1",
(configSTACK_DEPTH_TYPE ) TASK1_STACK_SIZE,
(void * ) NULL,
(UBaseType_t ) TASK1_PRIO,
(TaskHandle_t * ) &task1_handler );
xTaskCreate((TaskFunction_t ) task2,
(char * ) "task2",
(configSTACK_DEPTH_TYPE ) TASK2_STACK_SIZE,
(void * ) NULL,
(UBaseType_t ) TASK2_PRIO,
(TaskHandle_t * ) &task2_handler );
vTaskDelete(NULL);
taskEXIT_CRITICAL(); /* 退出临界区 */
}
/* 任务一,释放二值信号量 */
void task1( void * pvParameters )
{
uint8_t key = 0;
while(1)
{
key = key_scan(0);
if(key == KEY0_PRES)
{
xEventGroupSetBits( eventgroup_handle, EVENTBIT_0); /* 将事件标志组的bit0位置1 */
}else if(key == KEY1_PRES)
{
xEventGroupSetBits( eventgroup_handle, EVENTBIT_1); /* 将事件标志组的bit1位置1 */
}
vTaskDelay(10);
}
}
/* 任务二,获取二值信号量 */
void task2( void * pvParameters )
{
EventBits_t event_bit = 0;
while(1)
{
event_bit = xEventGroupWaitBits( eventgroup_handle, /* 事件标志组句柄 */
EVENTBIT_0 | EVENTBIT_1, /* 等待事件标志组的bit0和bit1位 */
pdTRUE, /* 成功等待到事件标志位后,清除事件标志组中的bit0和bit1位 */
pdTRUE, /* 等待事件标志组的bit0和bit1位都置1,就成立 */
portMAX_DELAY ); /* 死等 */
printf("等待到的事件标志位值为:%#x\r\n",event_bit);
}
}