UCOSIII 事件标志组

使用情况

    当任务需要与多个事件的发生同步,可以使用事件标志组。有两种情况:

  1. 或同步——等待多个事件发生,任何一个事件发生,任务就发生(同步)
  2. 与同步——等待多个事件发生,当所有事件都发生,任务就发生(同步)

使用方法

    事件标志组服务函数的实现代码在os_flag.c文件中,在编译时,将os_cfg.h文件中的配置常数OS_CFG_FLAG+EN设为1就可启用这些服务函数。

    常用的事件标志组的服务函数有:

  • OSFlagCreate() 创建事件标志组
  • OSFlagPend()    等待事件标志
  • OSFlagPost()     向事件标志组发布标志

void OSFlagCreate(OS_FLAG_GRP  *p_grp,            指向事件标志组的指针

                               CPU_CHAR       *p_name,         字符串——事件标志组的名字

                               OS_FLAGS         flags,               事件标志组的初始值

                               OS_ERR             err)                  该函数返回的错误码

OS_FLAGS  OSFlagPend(OS_FLAG_GRP  *p_grp,    指向事件标志组的指针

                                       OS_FLAGS        flags,        等待事件标志组的哪一位

                                       OS_TICK           timeout,  指定等待事件标志组的超时时间(时钟节拍数)

                                       OS_OPT            opt,

                                       CPU_TS            *p_ts,       指向时间戳

                                       OS_ERR            *p_err)      该函数返回的错误码

opt  决定任务等待的条件

            OS_OPT_PEND_FLAG_CLR_ALL           等待标志组所有的标志清零

            OS_OPT_PEND_FLAG_CLR_ANY          等待标志组任意一个标志清零

            OS_OPT_PEND_FLAG_SET_ALL            等待标志组所有的标志置位

            OS_OPT_PEND_FLAG_SET_ANY          等待标志组任意一个标志置位

        辅助选项

            +OS_OPT_PEND_FLAG_CONSUME     等待条件满足后将对应的标志清零

            +OS_OPT_PEND_BLOCKING (OS_OPT_PEND_NON_BLOCKING)

            在标志组不满足条件时,任务选择挂起(不挂起)

OS_FLAGS OSFlagPost(OS_FLAG_GRP   *p_grp,     指向事件标志组的指针

                                     OS_FLAGS          flags,        决定对哪些标志位进行置位或清零

                                     OS_OPT             opt,

                                     OS_ERR              *p_err)     函数返回错误码

opt   OS_OPT_POST_FLAG_SET 置位  OS_OPT_POST_FLAG_CLR 清零

  1 #include "sys.h"
  2 #include "delay.h"
  3 #include "usart.h"
  4 #include "led.h"
  5 #include "lcd.h"
  6 #include "key.h"
  7 #include "pcf8574.h"
  8 #include "ltdc.h"
  9 #include "sdram.h"
 10 #include "malloc.h"
 11 #include "includes.h"
 12 
 13 
 14 //UCOSIII中以下优先级用户程序不能使用,ALIENTEK
 15 //将这些优先级分配给了UCOSIII的5个系统内部任务
 16 //优先级0:中断服务服务管理任务 OS_IntQTask()
 17 //优先级1:时钟节拍任务 OS_TickTask()
 18 //优先级2:定时任务 OS_TmrTask()
 19 //优先级OS_CFG_PRIO_MAX-2:统计任务 OS_StatTask()
 20 //优先级OS_CFG_PRIO_MAX-1:空闲任务 OS_IdleTask()
 21 /
 22 
 23 //任务优先级
 24 #define START_TASK_PRIO        3
 25 //任务堆栈大小    
 26 #define START_STK_SIZE         128
 27 //任务控制块
 28 OS_TCB StartTaskTCB;
 29 //任务堆栈    
 30 CPU_STK START_TASK_STK[START_STK_SIZE];
 31 //任务函数
 32 void start_task(void *p_arg);
 33 
 34 //任务优先级
 35 #define MAIN_TASK_PRIO        4
 36 //任务堆栈大小    
 37 #define MAIN_STK_SIZE         128
 38 //任务控制块
 39 OS_TCB Main_TaskTCB;
 40 //任务堆栈    
 41 CPU_STK MAIN_TASK_STK[MAIN_STK_SIZE];
 42 void main_task(void *p_arg);
 43 
 44 //任务优先级
 45 #define FLAGSPROCESS_TASK_PRIO    5
 46 //任务堆栈大小    
 47 #define FLAGSPROCESS_STK_SIZE     128
 48 //任务控制块
 49 OS_TCB Flagsprocess_TaskTCB;
 50 //任务堆栈    
 51 CPU_STK FLAGSPROCESS_TASK_STK[FLAGSPROCESS_STK_SIZE];
 52 //任务函数
 53 void flagsprocess_task(void *p_arg);
 54 
 55 
 56 //LCD刷屏时使用的颜色
 57 int lcd_discolor[14]={    WHITE, BLACK, BLUE,  BRED,      
 58                         GRED,  GBLUE, RED,   MAGENTA,            
 59                         GREEN, CYAN,  YELLOW,BROWN,             
 60                         BRRED, GRAY };
 61 
 62 ////////////////////////事件标志组//////////////////////////////
 63 #define KEY0_FLAG        0x01
 64 #define KEY1_FLAG        0x02
 65 #define KEYFLAGS_VALUE    0X00                        
 66 OS_FLAG_GRP    EventFlags;        //定义一个事件标志组
 67                         
 68                         
 69 //加载主界面
 70 void ucos_load_main_ui(void)
 71 {
 72     POINT_COLOR = RED;
 73     LCD_ShowString(30,10,200,16,16,"Apollo STM32F4/F7");    
 74     LCD_ShowString(30,30,200,16,16,"UCOSIII Examp 12-1");
 75     LCD_ShowString(30,50,200,16,16,"Event Flags");
 76     LCD_ShowString(30,70,200,16,16,"ATOM@ALIENTEK");
 77     LCD_ShowString(30,90,200,16,16,"2016/1/21");
 78     POINT_COLOR = BLACK;
 79     LCD_DrawRectangle(5,130,234,314);    //画矩形
 80     POINT_COLOR = BLUE;
 81     LCD_ShowString(30,110,220,16,16,"Event Flags Value:0");
 82 }
 83                    
 84 int main(void)
 85 {
 86     OS_ERR err;
 87     CPU_SR_ALLOC();
 88     
 89     Stm32_Clock_Init(360,25,2,8);   //设置时钟,180Mhz   
 90     HAL_Init();                     //初始化HAL库
 91     delay_init(180);                //初始化延时函数
 92     uart_init(115200);              //初始化USART
 93     LED_Init();                     //初始化LED 
 94     KEY_Init();                     //初始化按键
 95     PCF8574_Init();                 //初始化PCF8974
 96     SDRAM_Init();                   //初始化SDRAM
 97     LCD_Init();                        //初始化LCD
 98     my_mem_init(SRAMIN);            //初始化内部内存池
 99     ucos_load_main_ui();            //加载主UI
100     
101     OSInit(&err);                    //初始化UCOSIII
102     OS_CRITICAL_ENTER();            //进入临界区    
103     //创建开始任务
104     OSTaskCreate((OS_TCB     * )&StartTaskTCB,        //任务控制块
105                  (CPU_CHAR    * )"start task",         //任务名字
106                  (OS_TASK_PTR )start_task,             //任务函数
107                  (void        * )0,                    //传递给任务函数的参数
108                  (OS_PRIO      )START_TASK_PRIO,     //任务优先级
109                  (CPU_STK   * )&START_TASK_STK[0],    //任务堆栈基地址
110                  (CPU_STK_SIZE)START_STK_SIZE/10,    //任务堆栈深度限位
111                  (CPU_STK_SIZE)START_STK_SIZE,        //任务堆栈大小
112                  (OS_MSG_QTY  )0,                    //任务内部消息队列能够接收的最大消息数目,为0时禁止接收消息
113                  (OS_TICK      )0,                    //当使能时间片轮转时的时间片长度,为0时为默认长度,
114                  (void       * )0,                    //用户补充的存储区
115                  (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR|OS_OPT_TASK_SAVE_FP, //任务选项,为了保险起见,所有任务都保存浮点寄存器的值
116                  (OS_ERR     * )&err);                //存放该函数错误时的返回值
117     OS_CRITICAL_EXIT();                //退出临界区     
118     OSStart(&err);                  //开启UCOSIII
119     while(1)
120     {
121     } 
122 }
123 
124 //开始任务函数
125 void start_task(void *p_arg)
126 {
127     OS_ERR err;
128     CPU_SR_ALLOC();
129     p_arg = p_arg;
130     
131     CPU_Init();
132 #if OS_CFG_STAT_TASK_EN > 0u
133    OSStatTaskCPUUsageInit(&err);      //统计任务                
134 #endif
135     
136 #ifdef CPU_CFG_INT_DIS_MEAS_EN        //如果使能了测量中断关闭时间
137     CPU_IntDisMeasMaxCurReset();    
138 #endif
139     
140 #if    OS_CFG_SCHED_ROUND_ROBIN_EN  //当使用时间片轮转的时候
141     //使能时间片轮转调度功能,设置默认的时间片长度
142     OSSchedRoundRobinCfg(DEF_ENABLED,1,&err);  
143 #endif    
144         
145     OS_CRITICAL_ENTER();    //进入临界区
146     //创建一个事件标志组
147     OSFlagCreate((OS_FLAG_GRP*)&EventFlags,        //指向事件标志组
148                  (CPU_CHAR*      )"Event Flags",    //名字
149                  (OS_FLAGS      )KEYFLAGS_VALUE,    //事件标志组初始值
150                  (OS_ERR*        )&err);            //错误码
151     //创建主任务
152     OSTaskCreate((OS_TCB*     )&Main_TaskTCB,        
153                  (CPU_CHAR*   )"Main task",         
154                  (OS_TASK_PTR )main_task,             
155                  (void*       )0,                    
156                  (OS_PRIO      )MAIN_TASK_PRIO,     
157                  (CPU_STK*    )&MAIN_TASK_STK[0],    
158                  (CPU_STK_SIZE)MAIN_STK_SIZE/10,    
159                  (CPU_STK_SIZE)MAIN_STK_SIZE,        
160                  (OS_MSG_QTY  )0,                    
161                  (OS_TICK      )0,                      
162                  (void*       )0,                    
163                  (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR|OS_OPT_TASK_SAVE_FP,
164                  (OS_ERR*     )&err);                        
165     //创建MSGDIS任务
166     OSTaskCreate((OS_TCB*     )&Flagsprocess_TaskTCB,        
167                  (CPU_CHAR*   )"Flagsprocess task",         
168                  (OS_TASK_PTR )flagsprocess_task,             
169                  (void*       )0,                    
170                  (OS_PRIO      )FLAGSPROCESS_TASK_PRIO,     
171                  (CPU_STK*       )&FLAGSPROCESS_TASK_STK[0],    
172                  (CPU_STK_SIZE)FLAGSPROCESS_STK_SIZE/10,    
173                  (CPU_STK_SIZE)FLAGSPROCESS_STK_SIZE,        
174                  (OS_MSG_QTY  )0,                    
175                  (OS_TICK      )0,                      
176                  (void*       )0,                    
177                  (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR|OS_OPT_TASK_SAVE_FP,
178                  (OS_ERR*       )&err);    
179     OS_CRITICAL_EXIT();    //退出临界区
180     OSTaskDel((OS_TCB*)0,&err);    //删除start_task任务自身
181 }
182 
183 //主任务的任务函数
184 void main_task(void *p_arg)
185 {
186     u8 key,num;
187     OS_FLAGS flags_num;
188     OS_ERR err;
189     while(1)
190     {
191         key = KEY_Scan(0);  //扫描按键
192         if(key == KEY0_PRES)
193         {
194             //向事件标志组EventFlags发送标志
195             flags_num=OSFlagPost((OS_FLAG_GRP*)&EventFlags,
196                                  (OS_FLAGS      )KEY0_FLAG,
197                                  (OS_OPT      )OS_OPT_POST_FLAG_SET,
198                                  (OS_ERR*      )&err);
199             LCD_ShowxNum(174,110,flags_num,1,16,0);
200             printf("事件标志组EventFlags的值:%d
",flags_num);
201         }
202         else if(key == KEY1_PRES)
203         {
204             //向事件标志组EventFlags发送标志
205             flags_num=OSFlagPost((OS_FLAG_GRP*)&EventFlags,
206                                  (OS_FLAGS      )KEY1_FLAG,
207                                  (OS_OPT      )OS_OPT_POST_FLAG_SET,
208                                  (OS_ERR*     )&err);
209             LCD_ShowxNum(174,110,flags_num,1,16,0);
210             printf("事件标志组EventFlags的值:%d
",flags_num);
211         }
212         num++;
213         if(num==50)
214         {
215             num=0;
216             LED0=!LED0;
217         }
218         OSTimeDlyHMSM(0,0,0,10,OS_OPT_TIME_PERIODIC,&err);   //延时10ms
219     }
220 }
221 
222 //事件标志组处理任务
223 void flagsprocess_task(void *p_arg)
224 {
225     u8 num;
226     OS_ERR err; 
227     while(1)
228     {
229         //等待事件标志组
230         OSFlagPend((OS_FLAG_GRP*)&EventFlags,
231                    (OS_FLAGS    )KEY0_FLAG+KEY1_FLAG,
232                     (OS_TICK     )0,
233                    (OS_OPT        )OS_OPT_PEND_FLAG_SET_ALL+OS_OPT_PEND_FLAG_CONSUME, // 收到 k1和k0 的消息 并清零标志位
234                    (CPU_TS*     )0,
235                    (OS_ERR*        )&err);
236         num++;
237         LED1=!LED1;
238         LCD_Fill(6,131,233,313,lcd_discolor[num%14]);
239         printf("事件标志组EventFlags的值:%d
",EventFlags.Flags);
240         LCD_ShowxNum(174,110,EventFlags.Flags,1,16,0);
241     }
242 }
View Code
原文地址:https://www.cnblogs.com/mrguoguo/p/13716697.html