这里我们重点的说一下函数os_evt_set,isr_evt_set和os_evt_wait_and,因为本章节配套的例子使用的是这三个函数。
13.2.1 函数os_evt_set函数原型:
- void os_evt_set (
- U16 event_flags, /* 16位的事件标志设置 */
- OS_TID task ); /* 要设置事件标志的任务ID */
复制代码
函数描述:
函数os_evt_set用于设置指定任务的事件标志。
(1)第1个参数表示16个可设置的事件标志位。因为RTX的每个任务创建时有16个可设置的事件标志,这里用U16类型的变量event_flag就可以表示,变量event_flag的某个位设置为1,那么指定RTX任务的事件标志相应位就设置为1。变量event_flag设置为0的位对RTX任务的事件标志相应位没有影响。比如设置变量event_flag = 0x0003就表示将RTX任务事件标志的位0和位1设置为1,其余位没有变化。
(2)第2个参数是任务ID。
使用这个函数要注意以下问题:
1. 此函数是用于任务代码中调用的,故不可以在中断服务程序中调用此函数,中断服务程序中使用的是isr_evt_set
使用举例:
- #include
-
- __task void task1 (void) {
- ..
- os_evt_set (0x0003, tsk2);
- ..
- }
复制代码
13.2.2 函数isr_evt_set函数原型:
- void isr_evt_set (
- U16 event_flags, /* 16位的事件标志设置 */
- OS_TID task ); /* 要设置事件标志的任务ID */
复制代码
函数描述:
函数isr_evt_set用于设置指定任务的事件标志。
(1)第1个参数表示16个可设置的事件标志位。因为RTX的每个任务创建时有16个可设置的事件标志,这里用U16类型的变量event_flag就可以表示,变量event_flag的某个位设置为1,那么指定RTX任务的事件标志相应位就设置为1。变量event_flag设置为0的位对RTX任务的事件标志相应位没有影响。比如设置变量event_flag = 0x0003就表示将RTX任务事件标志的位0和位1设置为1,其余位没有变化。
(2)第2个参数是任务ID。
使用这个函数要注意以下问题:
1. 此函数是用于中断服务程序中调用的,故不可以在任务中调用此函数,任务中使用的是os_evt_set。
2. 事件标志函数isr_evt_set的调用不能太频繁,太频繁的话会大大增加系统内核的开销,会造成事件标志得不到及时处理从而造成丢失事件标志的情况。
使用举例:
- #include
-
- void EXTI0_IRQHandler (void){
- ..
- isr_evt_set (0x0003, tsk2);
- ..
- }
复制代码
13.2.3 函数os_evt_wait_and函数原型:
- OS_RESULT os_evt_wait_and (
- U16 wait_flags, /* 16位的事件标志等待 */
- U16 timeout ); /* 超时时间设置 */
复制代码
函数描述:
函数os_evt_wait_and用于等待事件标志被设置。
1. 第1个参数表示任务等待的事件标志位。因为RTX的每个任务创建时有16个可以设置的事件标志,这里用U16类型的变量event_flag就可以设置,变量event_flag的那位设置为1,那么RTX任务的事件标志就等待那个位被设置为1。而且要所有要求的位都被设置为1才可以。比如设置变量event_flag = 0x0003就表示RTX任务在等待事件标志的位0和位1都被设置为1。
2. 第2个参数表示设在的等待时间,范围0-0xFFFF,当参数设置为0-0xFFFE时,表示等这么多个时钟节拍,参数设置为0xFFFF时表示无限等待直到事件标志满足要求。
3. 函数返回OS_R_EVT表示等待的事件标志位都被设置了,也就是返回成功。返回OS_R_TMO表示超时。
使用这个函数要注意以下问题:
1. 当要求的事件标志位都被设置为1时或者设置的超时时间溢出时,函数os_evt_wait_and才会返回。
2. 如果函数os_evt_wait_and返回前所要求的事件标志位都设置了,那么此函数会在返回前将相应的事件标志位清零,其它位不受此影响。如果初学者不是太理解这个问题,可以看本章节配套的例子,这样会有一个清晰的认识。
使用举例:
- #include
- #define BIT_0 (1 << 0)
- #define BIT_1 (1 << 1)
- #define BIT_ALL (BIT_0 | BIT_1)
-
- __task void AppTaskMsgPro(void)
- {
- OS_RESULT xResult;
- const uint16_t usMaxBlockTime = 500; /* 延迟周期 */
-
- while(1)
- {
- /*
- 1. 等待K2按键按下设置bit0和K3按键按下设置bit1,都设置了执行OS_R_EVT消息
- 2. 退出前bit0和bit1被清除,这里是bit0和bit1都被设置才表示“退出”。
- 3. 每个任务都有自己的16位事件标志位,也就是os_evt_wait_and的第一个参数是无符号16位整形。
- */
- xResult = os_evt_wait_and (BIT_ALL, usMaxBlockTime);
-
- switch (xResult)
- {
- /* 接收到bit1和bit0都被设置的消息 */
- case OS_R_EVT:
- printf("接收到bit0和bit1都被设置的消息rn");
- break;
-
- /* 超时 */
- case OS_R_TMO:
- bsp_LedToggle(1);
- bsp_LedToggle(4);
- break;
-
- /* 其他值不处理 */
- default:
- break;
- }
- }
- }
复制代码