FreeRTOS事件标志组

——————(正点原子FreeRTOS学习笔记)

开始学习FreeRTOS,学习参考书籍和视频来自正点原子FreeRTOS源码详解与应用开发,北京航空航天大学出版社


1    事件标志组简介
1 、事件位( 事件标志)
        事件位用来表明某个事件是否发生,事件位通常用作事件标志,比如下面的几个例子:
● 当收到一条消息并且把这条消息处理掉以后就可以将某个位(标志)置 1,当队列中没有 消息需要处理的时候就可以将这个位(标志)置 0。
● 当把队列中的消息通过网络发送输出以后就可以将某个位(标志)置 1,当没有数据需要 从网络发送出去的话就将这个位(标志)置 0。
● 现在需要向网络中发送一个心跳信息,将某个位(标志)置 1。现在不需要向网络中发送 心跳信息,这个位(标志)置 0。

2 、事件组
        一个事件组就是一组的事件位,事件组中的事件位通过位编号来访问,同样,以上面列出 的三个例子为例:
● 事件标志组的 bit0 表示队列中的消息是否处理掉。
● 事件标志组的 bit1 表示是否有消息需要从网络中发送出去。
● 事件标志组的 bit2 表示现在是否需要向网络发送心跳信息。

3 、事件标志组和事件位 的 数据类型
        事件标志组的数据类型为 EventGroupHandle_t,当 configUSE_16_BIT_TICKS 为 1 的时候 事件标志组可以存储 8 个事件位,当 configUSE_16_BIT_TICKS 为 0 的时候事件标志组存储 24 个事件位。 事件标志组中的所有事件位都存储在一个无符号的 EventBits_t 类型的变量中,EventBits_t 在 event_groups.h 中有如下定义:
typedef TickType_t EventBits_t;
        数据类型 TickType_t 在文件 portmacro.h 中有如下定义:
#if( configUSE_16_BIT_TICKS == 1 )
        typedef uint16_t TickType_t;
        #define portMAX_DELAY ( TickType_t ) 0xffff
#else
        typedef uint32_t TickType_t;
        #define portMAX_DELAY ( TickType_t ) 0xffffffffUL
        #define portTICK_TYPE_IS_ATOMIC 1
#endif
        可以看出当 configUSE_16_BIT_TICKS 为 0 的时候 TickType_t 是个 32 位的数据类型,因 此 EventBits_t 也是个 32 位的数据类型。EventBits_t 类型的变量可以存储 24 个事件位,另外的 那高 8 位有其他用。事件位 0 存放在这个变量的 bit0 上,变量的 bit1 就是事件位 1,以此类推。 对于 STM32 来说一个事件标志组最多可以存储 24 个事件位,如图 16.1.1 所示:
                                         FreeRTOS事件标志组_第1张图片

2  创建事件标志组
        FreeRTOS 提供了两个用于创建事件标志组的函数,如表 16.2.1 所示:
                    

1 、函数 xEventGroupCreate()
        此函数用于创建一个事件标志组,所需要的内存通过动态内存管理方法分配。由于内部处 理 的 原 因 , 事 件 标 志 组 可 用 的 bit 数 取 决 于 configUSE_16_BIT_TICKS , 当 configUSE_16_BIT_TICKS1 为 1 的 时 候 事 件 标 志 组 有 8 个 可 用 的 位 (bit0~bit7) , 当 configUSE_16_BIT_TICKS 为 0 的时候事件标志组有 24 个可用的位(bit0~bit23)。EventBits_t 类 型的变量用来存储事件标志组中的各个事件位,函数原型如下:
        EventGroupHandle_t xEventGroupCreate( void )
参数:
        无。
返回值:
        NULL: 事件标志组创建失败。
        其他值: 创建成功的事件标志组句柄。
2 、函数 xEventGroupCreateStatic()
        此函数用于创建一个事件标志组定时器,所需要的内存需要用户自行分配,此函数原型如 下:
        EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer )
参数:
        pxEventGroupBuffer : 参数指向一个 StaticEventGroup_t 类型的变量,用来保存事件标志组结 构体。
返回值:
        NULL: 事件标志组创建失败。
        其他值: 创建成功的事件标志组句柄。

3  设置事件位
        FreeRTOS 提供了 4 个函数用来设置事件标志组中事件位(标志),事件位(标志)的设置包括 清零和置 1 两种操作,这 4 个函数如表 16.3.1 所示:
                
                

1 、函数 xEventGroupClearBits()
        将事件标志组中的指定事件位清零,此函数只能用在任务中,不能用在中断服务函数中! 中断服务函数有其他的 API 函数。函数原型如下:
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup,
                                                        const EventBits_t uxBitsToClear );
参数:
        xEventGroup : 要操作的事件标志组的句柄。
        uxBitsToClear : 要清零的事件位,比如要清除 bit3 的话就设置为 0X08。可以同时清除多个 bit,如设置为 0X09 的话就是同时清除 bit3 和 bit0。
返回值:
        任何值: 将指定事件位清零之前的事件组值。
2 、函数 xEventGroupClearBitsFromISR()
        此函数为函数 xEventGroupClearBits()的中断级版本,也是将指定的事件位(标志)清零。此 函数用在中断服务函数中,此函数原型如下:
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup,
                                                                    const EventBits_t uxBitsToSet );
参数:
        xEventGroup : 要操作的事件标志组的句柄。
        uxBitsToClear : 要清零的事件位,比如要清除 bit3 的话就设置为 0X08。可以同时清除多个 bit,如设置为 0X09 的话就是同时清除 bit3 和 bit0。
返回值:
        pdPASS : 事件位清零成功。
        pdFALSE:  事件位清零失败。

3、函数 xEventGroupSetBits()
        设置指定的事件位为 1,此函数只能用在任务中,不能用于中断服务函数,此函数原型如 下:
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,
                                                    const EventBits_t uxBitsToSet );
参数:
        xEventGroup : 要操作的事件标志组的句柄。
        uxBitsToClear : 指定要置 1 的事件位,比如要将 bit3 值 1 的话就设置为 0X08。可以同时将 多个 bit 置 1,如设置为 0X09 的话就是同时将 bit3 和 bit0 置 1。
返回值:
        任何值: 在将指定事件位置 1 后的事件组值。
4、 、数 函数 xEventGroupSetBitsFromISR()
        此函数也用于将指定的事件位置 1,此函数是 xEventGroupSetBits()的中断版本,用在中断 服务函数中,函数原型如下:
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup,
                                                                    const EventBits_t uxBitsToSet,
                                                                    BaseType_t * pxHigherPriorityTaskWoken );
参数:
        xEventGroup : 要操作的事件标志组的句柄。
        uxBitsToClear : 指定要置 1 的事件位,比如要将 bit3 值 1 的话就设置为 0X08。可以同时将 多个 bit 置 1,如设置为 0X09 的话就是同时将 bit3 和 bit0 置 1。
        pxHigherPriorityTaskWoken: :标记退出此函数以后是否进行任务切换,这个变量的值函数会自 动设置的,用户不用进行设置,用户只需要提供一个变量来保存 这个值就行了。当此值为 pdTRUE 的时候在退出中断服务函数之 前一定要进行一次任务切换。
返回值:
        pdPASS : 事件位置 1 成功。
        pdFALSE:  事件位置 1 失败。

4  获取事件标志组值
        我们可以通过 FreeRTOS 提供的 API 函数来查询事件标准组值,FreeRTOS 一共提供了两个 这样的 API 函数,如表 16.4.1 所示:

1 、函数 xEventGroupGetBits()
        此函数用于获取当前事件标志组的值,也就是各个事件位的值。此函数用在任务中,不能 用在中断服务函数中。此函数是个宏,真正执行的是函数 xEventGroupClearBits(),函数原型如
下:
        EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup )
参数:
        xEventGroup : 要获取的事件标志组的句柄。
返回值:
        任何值:当前事件标志组的值。
2 、函数 xEventGroupGetBitsFromISR()
        获取当前事件标志组的值,此函数是 xEventGroupGetBits()的中断版本,函数原型如下:
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup )
参数:
        xEventGroup : 要获取的事件标志组的句柄。
返回值:
        任何值:  当前事件标志组的值。

5  等待指定的事件位
        某个任务可能需要与多个事件进行同步,那么这个任务就需要等待并判断多个事件位(标 志),使用函数 xEventGroupWaitBits()可以完成这个功能。调用函数以后如果任务要等待的事件 位还没有准备好(置 1 或清零)的话任务就会进入阻塞态,直到阻塞时间到达或者所等待的事件 位准备好。函数原型如下:
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
                                                    const EventBits_t uxBitsToWaitFor,
                                                    const BaseType_t xClearOnExit,
                                                    const BaseType_t xWaitForAllBits,
                                                    const TickType_t xTicksToWait );
参数:
        xEventGroup : 指定要等待的事件标志组。
        uxBitsToWaitFord: 指定要等待的事件位,比如要等待bit0和(或)bit2的时候此参数就是0X05, 如果要等待 bit0 和(或)bit1 和(或)bit2 的时候此参数就是 0X07,以此类推。
        xClearOnExit: 此参数要是为pdTRUE的话,那么在退出此函数之前由参数uxBitsToWaitFor 所设置的这些事件位就会清零。如果设置位 pdFALSE 的话这些事件位就
不会改变。
        xWaitForAllBits: 此参数如果设置为 pdTRUE 的话,当 uxBitsToWaitFor 所设置的这些事件 位都置 1,或者指定的阻塞时间到的时候函数 xEventGroupWaitBits()才会
返回。当此函数为 pdFALSE 的话,只要 uxBitsToWaitFor 所设置的这些事
件 位 其 中 的 任 意 一 个 置 1 , 或 者 指 定 的 阻 塞 时 间 到 的 话 函 数
xEventGroupWaitBits()就会返回。
xTicksToWait :  设置阻塞时间,单位为节拍数。
返回值:
        任何值:  返回当所等待的事件位置 1 以后的事件标志组的值,或者阻塞时间到。根 据这个值我们就知道哪些事件位置 1 了。如果函数因为阻塞时间到而返回 的话那么这个返回值就不代表任何的含义。

你可能感兴趣的:(嵌入式,STM32)