• 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
  • 相关阅读:
    Qt开发陷阱一QSTACKWIDGET
    【解决】安装compass失败(gem install compass)
    Qt使用MySQL笔记一
    win7双系统安装openSUSE13.2解决【引导加载器安装期间出错】问题
    【转载】Sublime Text 3065 Keygen and Patcher
    HTML4,HTML5,XHTML 之间有什么区别?
    【转】实例解说双缓冲
    【MFC】利用双缓冲和随机函数rand()实现蒲公英飞舞
    基本sql语句--入门语句
    Linux使用jstat命令查看jvm的GC情况
  • 原文地址:https://www.cnblogs.com/mrguoguo/p/13716697.html
Copyright © 2020-2023  润新知