1 事件标志组

1.1.1

事件标志组是实现多任务同步的有效机制之一。

使用全局变量相比事件标志组主要有如下三个问题:

  • 使用事件标志组可以让 RTOS 内核有效地管理任务,而全局变量是无法做到的,任务的超时等机制需 要用户自己去实现。
  • 使用了全局变量就要防止多任务的访问冲突,而使用事件标志组则处理好了这个问题,用户无需担心。
  • 使用事件标志组可以有效地解决中断服务程序任务之间的同步问题。

1.1.2FreeRTOS 任务间事件标志组的实现

#define configUSE_16_BIT_TICKS 1

配置宏定义 configUSE_16_BIT_TICKS 为 1 时,每创建一个事件标志组,用户可以使用的事件标志是 8 个

#define configUSE_16_BIT_TICKS 0 //这意思是使用了32位

配置宏定义 configUSE_16_BIT_TICKS 为 0 时,每创建一个事件标志组,用户可以使用的事件标志是 24 个。

其实就是定义了一个 16 位变量,仅使用了低 8bit 或者定义了一个 32 位变量,仅使用了低 24bit。

每一个 bit 用 0 和 1 两种状态来代表事件标志。

上图说明:

  1. 任务1 运行到函数xEventGroupWaitBits,就会进入阻塞态,目的是等待事件组标志位的到来。
  2. 这时候任务2设置了1个事件标志event_flag,任务1收到了这个事件标志,继续运行任务1。

1.1.3FreeRTOS 中断方式事件标志组的实现

中断内部设置事件标志位,代替上面的普通方式的task2。

中断方式的消息机制要注意四个问题:

  • 中断函数的执行时间越短越好,防止其它低于这个中断优先级的异常不能得到及时响应。
  • 实际应用中,建议不要在中断中实现消息处理,用户可以在中断服务程序里面发送消息通知任务,在 任务中实现消息处理,这样可以有效地保证中断服务程序的实时响应。同时此任务也需要设置为高优 先级,以便退出中断函数后任务可以得到及时执行。
  • 中断服务程序中一定要调用专用于中断的事件标志设置函数,即以 FromISR 结尾的函数。
  • 在操作系统中实现中断服务程序与裸机编程的区别。
    • 如果 FreeRTOS 工程的中断函数中没有调用 FreeRTOS 的事件标志组 API 函数,与裸机编程是 一样的。
    • 如果 FreeRTOS 工程的中断函数中调用了 FreeRTOS 的事件标志组的 API 函数,退出的时候要 检测是否有高优先级任务就绪,如果有就绪的,需要在退出中断后进行任务切换,这点跟裸机编 程稍有区别
    • 推荐用户将,NVIC 优先级分组设置为 4,这样中 断优先级的管理将非常方便
    • 用户要在 FreeRTOS 多任务开启前就设置好优先级分组,一旦设置好切记不可再修改

1.2 事件标志组 API 函数

  1. xEventGroupCreate()
  2. xEventGroupCreateStatic()
  3. vEventGroupDelete()
  4. xEventGroupWaitBits()
  5. xEventGroupSetBits()
  6. xEventGroupSetBitsFromISR()
  7. xEventGroupClearBits()
  8. xEventGroupClearBitsFromISR()
  9. xEventGroupGetBits()
  10. xEventGroupGetBitsFromISR()
  11. xEventGroupSync()

函数 xEventGroupCreate 用于创建事件标志组。

返回值,如果创建成功,此函数返回事件标志组的句柄,如果 FreeRTOSConfig.h 文件中定义的 heap 空间不足会返回 NULL

static EventGroupHandle_t xCreatedEventGroup = NULL;
xCreatedEventGroup = xEventGroupCreate();
if(xCreatedEventGroup == NULL)
 {
 /* 没有创建成功,用户可以在这里加入创建失败的处理机制 */
 }

  • xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );

uxBitsToSet 是一个32位的,低24位可用。一共可以24个标志位。如0x0003

函数 xEventGroupSetBits 用于设置指定的事件标志位为 1。

使用前一定要保证事件标志组已经通过函数 xEventGroupCreate 创建了。

此函数是用于任务代码中调用的,故不可以在中断服务程序中调用此函数,中断服务程序中使用的是 xEventGroupSetBitsFromISR

a,调用此函数的过程中,其它高优先级的任务就绪了,并且也修改了事件标志,此函数返回的事件 标志位会发生变化。

b. 调用此函数的任务是一个低优先级任务,通过此函数设置了事件标志后,让一个等待此事件标志 的高优先级任务就绪了,会立即切换到高优先级任务去执行,相应的事件标志位会被函数 xEventGroupWaitBits 清除掉,等从高优先级任务返回到低优先级任务后,函数 xEventGroupSetBits 的返回值已经被修改。

1.3 实验例程说明(任务间通信)

1.4 实验例程说明(中断方式通信)