一、RTX的事件标志组里面的API函数总共有6个:如下图
下面分别介绍下这6个函数
1、os_evt_clr函数原型
void os_evt_clr ( U16 clear_flags, /* Bit pattern of event flags to clear */ OS_TID task ); /* The task that the events apply to */函数描述:
该函数用于清除指定的任务的事件标志
第一个参数是清除的事件的标志位
第二个参数是任务的ID
使用举例:
__task void task1 (void) { .. os_evt_clr (0x0002, tsk2); .. }2、os_evt_get函数的原型
U16 os_evt_get (void);函数描述:
确定导致os_evt_wait_or函数完成事件。
使用举例:
__task void task1 (void) { U16 ret_flags; if (os_evt_wait_or (0x0003, 500) == OS_R_EVT) { ret_flags = os_evt_get (); printf("Events %04x received.\n",ret_flags); } .. }3、os_evt_set函数原型
void os_evt_set ( U16 event_flags, /* Bit pattern of event flags to set */ OS_TID task );函数描述:
该函数用于设置指定任务的事件标志
第一个参数表示设置的事件标志位
第二个参数是任务的ID
使用举例:
__task void task1 (void) { .. os_evt_set (0x0003, tsk2); .. }4、os_evt_wait_and函数原型
OS_RESULT os_evt_wait_and ( U16 wait_flags, /* Bit pattern of events to wait for */ U16 timeout ); /* Length of time to wait for event */函数描述:
该函数用于等待事件标志被设置
第一个参数是任务等待事件标志位
第二个参数是设置等待的时间,范围在0 --0xFFFF之间 如果是0XFFFF就无限等待
函数的返回值 OS_R_EVT表示等待的事件标志位都被设置了,也就是返回成功,返回是OS_R_TMO表示失败
使用举例:
__task void task1 (void) { OS_RESULT result; result = os_evt_wait_and (0x0003, 500); if (result == OS_R_TMO) { printf("Event wait timeout.\n"); } else { printf("Event received.\n"); } .. }5、os_evt_wait_or函数原型
OS_RESULT os_evt_wait_or ( U16 wait_flags, /* Bit pattern of events to wait for */ U16 timeout ); /* Length of time to wait for event */函数描述:
该函数用于等待事件标志被设置
第一个参数是任务等待事件标志位
第二个参数是设置等待的时间,范围在0 --0xFFFF之间 如果是0XFFFF就无限等待
注意os_evt_wait_or和os_evt_wait_and的区别在于 os_evt_wait_or的事件标志位只要有一位被设置就可以满足,而os_evt_wait_and必须每位都要满足才可以
使用举例:
__task void task1 (void) { OS_RESULT result; result = os_evt_wait_or (0x0003, 500); if (result == OS_R_TMO) { printf("Event wait timeout.\n"); } else { printf("Event received.\n"); } .. }
6、isr_evt_set函数原型
void isr_evt_set (
U16 event_flags, /* Bit pattern of event flags to set */
OS_TID task ); /* The task that the events apply to */
函数描述:
该函数用于设置指定事件的标志 只能在中断函数中使用
第一个参数是任务等待事件标志位
第二个参数是任务ID
使用举例:
void timer1 (void) __irq { .. isr_evt_set (0x0008, tsk1); .. }
下面是实验的列子
实验目的:
学习RTX的事件标志组
实验内容:
1、k1键按下发送事件
2、k2键按下发送事件
3、k3键按下清除事件
4、AppTaskStart任务 实现按键扫描 和LED闪烁
5、AppTaskUserKey任务 实现按键的处理
6、AppTaskLED任务 实现LED的点亮
下面是完整的代码
#include "bsp.h" /* 底层硬件驱动 */ #include <RTL.h> static uint64_t AppTaskLEDStk[256/8];/*任务栈*/ static uint64_t AppTaskStartStk[512/8];/*任务栈*/ static uint64_t AppTaskUserKeyStk[512/8];/*任务栈*/ /*任务句柄*/ OS_TID HandleTaskLED = NULL; OS_TID HandleTaskKey = NULL; /*函数声明*/ static void AppTaskCreate(void); __task void AppTaskLED(void); __task void AppTaskStart(void); /* ********************************************************************************************************* * 函 数 名: main * 功能说明: c程序入口 * 形 参:无 * 返 回 值: 错误代码(无需处理) ********************************************************************************************************* */ int main(void) { /* ST固件库中的启动文件已经执行了 SystemInit() 函数,该函数在 system_stm32f4xx.c 文件,主要功能是 配置CPU系统的时钟,内部Flash访问时序,配置FSMC用于外部SRAM */ bsp_Init();/**/ os_sys_init_user(AppTaskStart, /*任务函数*/ 3, /*任务优先级*/ &AppTaskStartStk, /*任务栈*/ sizeof(AppTaskStartStk));/*任务栈大小*/ /* 进入主程序循环体 */ while (1) { ; } } /* ********************************************************************************************************* * 函 数 名: AppTaskLED * 功能说明: LED闪烁的任务 * 形 参:无 * 返 回 值: 无 ********************************************************************************************************* */ __task void AppTaskLED(void) { static uint8_t i = 0; OS_RESULT xResult = 0; uint16_t Evt = 0; while(1) { xResult = os_evt_wait_and(0x05,0xFFFF);/*等待时间标志被设置*/ switch(xResult) { case OS_R_EVT: i++; Evt = os_evt_get(); printf("事件标志位%d\r\n",Evt); break; case OS_R_TMO: printf("事件标志超时\r\n"); break; default: break; } if(i % 2 == 0) { GPIO_ResetBits(GPIOI,GPIO_Pin_10);/*点亮LED*/ } else { GPIO_SetBits(GPIOI,GPIO_Pin_10);/*熄灭LED*/ } os_dly_wait(100);/*系统延时函数 因为时钟节拍为1000 所以这里是延时800ms,也就是使AppTaskLED任务挂起800MS*/ } } __task void AppTaskKey(void) { uint8_t ucKeyCode = 0; while(1) { ucKeyCode = bsp_GetKey(); switch(ucKeyCode) { case KEY_DOWN_K1: printf("发送事件标志0x01\r\n"); os_evt_set(0x01,HandleTaskLED); break; case KEY_DOWN_K2: printf("发送事件标志0x04\r\n"); os_evt_set(0x04,HandleTaskLED); break; case KEY_DOWN_K3: os_evt_clr(0x05,HandleTaskLED); printf("已经清除的事件标志位\r\n"); break; case JOY_DOWN_U: break; case JOY_DOWN_D: break; default: break; } os_dly_wait(20); } } /* ********************************************************************************************************* * 函 数 名:AppTaskCreate * 功能说明: 任务创建 * 形 参:无 * 返 回 值: 无 ********************************************************************************************************* */ static void AppTaskCreate(void) { HandleTaskLED = os_tsk_create_user(AppTaskLED, /*任务函数*/ 1, /*优先级 注意RTX的数字越小,优先级越低*/ &AppTaskLEDStk, /*任务栈起始地址*/ sizeof(AppTaskLEDStk));/*任务栈大小*/ HandleTaskKey = os_tsk_create_user(AppTaskKey, /*任务函数*/ 2, /*优先级 注意RTX的数字越小,优先级越低*/ &AppTaskUserKeyStk, /*任务栈起始地址*/ sizeof(AppTaskUserKeyStk));/*任务栈大小*/ } /* ********************************************************************************************************* * 函 数 名:AppTaskStart * 功能说明: 开始任务 * 形 参:无 * 返 回 值: 无 ********************************************************************************************************* */ __task void AppTaskStart(void) { AppTaskCreate();/*创建AppTaskLED任务*/ while(1) { if((os_time_get() % 100) == 0) { GPIO_SetBits(GPIOF,GPIO_Pin_7);/*熄灭LED*/ } else if((os_time_get() %150) == 0) { GPIO_ResetBits(GPIOF,GPIO_Pin_7);/*点亮LED*/ } os_dly_wait(10);/*系统延时函数*/ bsp_KeyScan(); } }
实验现象:
k1和k2都按下一次实现LED的反转,k3按下清除事件标志