zoukankan      html  css  js  c++  java
  • UCOSIII 任务间通信 消息队列 和task 内建消息队列

    使用情况

      一个任务或者中断服务程序与另一个任务交流信息

    使用方法

      消息队列服务函数的实现代码在os_q.c文件中,在编译时,将os_cfg.h文件中的配置常数OS_CFG_Q_EN设为1就可启用这些服务函数。

      常用消息队列的服务函数有:

    • OSQCreate()       创建消息队列
    • OSQPend()          等待消息队列中的信息
    • OSQPost()           向消息队列中发送消息

    void  OSQCreate (OS_Q        *p_q,                    指向消息队列控制块的指针
                              CPU_CHAR    *p_name,           指向字符串的指针——消息队列的名字
                              OS_MSG_QTY   max_qty,        指定消息队列的最大长度(必须为非零)
                              OS_ERR      *p_err)                该函数返回的错误码

    void  *OSQPend (OS_Q         *p_q,                    指向消息队列控制块的指针
                             OS_TICK       timeout,              指定等待消息的超时时间(时钟节拍数)
                             OS_OPT        opt,                    
                             OS_MSG_SIZE  *p_msg_size,   接受的消息的大小(字节数,可用sizeof获取)
                             CPU_TS       *p_ts,                   指向一个时间戳的指针
                             OS_ERR       *p_err)                 该函数返回的错误码

    opt  OS_OPT_PEND_BLOCKING  阻塞模式(任务挂起等待该对象)

           OS_OPT_PEND_NON_BLOCKING  非阻塞模式(没有任何消息存在时,任务直接返回)

    void  OSQPost (OS_Q         *p_q,                        指向消息队列控制块的指针  
                           void         *p_void,                      实际发送的消息内容
                           OS_MSG_SIZE   msg_size,           设定消息的大小(字节数)
                           OS_OPT        opt,                  
                           OS_ERR       *p_err)                    该函数返回的错误码

    opt  OS_OPT_POST_FIFO   待发送的消息保存在消息队列的末尾(FIFO)

           OS_OPT_POST_LIFO   待发送的消息保存在消息队列的开头(LIFO)

           +OS_OPT_POST_ALL  向所有等待该消息队列的任务发送消息(否则只发送到最高级)

           +OS_OPT_POST_NO_SCHED 禁止在本函数内执行任务调度操作

    #define KEYMSG_Q_NUM 1 //按键消息队列的数量
    #define DATAMSG_Q_NUM 4 //发送数据的消息队列的数量
    OS_Q KEY_Msg; //定义一个消息队列,用于按键消息传递,模拟消息邮箱
    OS_Q DATA_Msg; //定义一个消息队列,用于发送数据

      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 //ALIENTEK 探索者STM32F429开发板 UCOSIII实验
     13 //例11-1 UCOSIII 消息传递
     14 
     15 //UCOSIII中以下优先级用户程序不能使用,ALIENTEK
     16 //将这些优先级分配给了UCOSIII的5个系统内部任务
     17 //优先级0:中断服务服务管理任务 OS_IntQTask()
     18 //优先级1:时钟节拍任务 OS_TickTask()
     19 //优先级2:定时任务 OS_TmrTask()
     20 //优先级OS_CFG_PRIO_MAX-2:统计任务 OS_StatTask()
     21 //优先级OS_CFG_PRIO_MAX-1:空闲任务 OS_IdleTask()
     22 //技术支持:www.openedv.com
     23 //淘宝店铺:http://eboard.taobao.com  
     24 //广州市星翼电子科技有限公司  
     25 //作者:正点原子 @ALIENTEK/
     26 
     27 //任务优先级
     28 #define START_TASK_PRIO        3
     29 //任务堆栈大小    
     30 #define START_STK_SIZE         128
     31 //任务控制块
     32 OS_TCB StartTaskTCB;
     33 //任务堆栈    
     34 CPU_STK START_TASK_STK[START_STK_SIZE];
     35 //任务函数
     36 void start_task(void *p_arg);
     37 
     38 //任务优先级
     39 #define MAIN_TASK_PRIO        4
     40 //任务堆栈大小    
     41 #define MAIN_STK_SIZE         128
     42 //任务控制块
     43 OS_TCB Main_TaskTCB;
     44 //任务堆栈    
     45 CPU_STK MAIN_TASK_STK[MAIN_STK_SIZE];
     46 void main_task(void *p_arg);
     47 
     48 
     49 //任务优先级
     50 #define KEYPROCESS_TASK_PRIO     5
     51 //任务堆栈大小    
     52 #define KEYPROCESS_STK_SIZE     128
     53 //任务控制块
     54 OS_TCB Keyprocess_TaskTCB;
     55 //任务堆栈    
     56 CPU_STK KEYPROCESS_TASK_STK[KEYPROCESS_STK_SIZE];
     57 //任务函数
     58 void Keyprocess_task(void *p_arg);
     59 
     60 //任务优先级
     61 #define MSGDIS_TASK_PRIO    6
     62 //任务堆栈
     63 #define MSGDIS_STK_SIZE        128
     64 //任务控制块
     65 OS_TCB    Msgdis_TaskTCB;
     66 //任务堆栈
     67 CPU_STK    MSGDIS_TASK_STK[MSGDIS_STK_SIZE];
     68 //任务函数
     69 void msgdis_task(void *p_arg);
     70 
     71 //LCD刷屏时使用的颜色
     72 int lcd_discolor[14]={    WHITE, BLACK, BLUE,  BRED,      
     73                         GRED,  GBLUE, RED,   MAGENTA,            
     74                         GREEN, CYAN,  YELLOW,BROWN,             
     75                         BRRED, GRAY };
     76 ////////////////////////消息队列//////////////////////////////
     77 #define KEYMSG_Q_NUM    1    //按键消息队列的数量
     78 #define DATAMSG_Q_NUM    4    //发送数据的消息队列的数量
     79 OS_Q KEY_Msg;                //定义一个消息队列,用于按键消息传递,模拟消息邮箱
     80 OS_Q DATA_Msg;                //定义一个消息队列,用于发送数据
     81                         
     82 ////////////////////////定时器////////////////////////////////
     83 u8 tmr1sta=0;     //标记定时器的工作状态
     84 OS_TMR    tmr1;    //定义一个定时器
     85 void tmr1_callback(void *p_tmr,void *p_arg); //定时器1回调函数
     86                         
     87 //加载主界面
     88 void ucos_load_main_ui(void)
     89 {
     90     POINT_COLOR = RED;
     91     LCD_ShowString(10,10,200,16,16,"Apollo STM32F4/F7");    
     92     LCD_ShowString(10,30,200,16,16,"UCOSIII Examp 11-1");
     93     LCD_ShowString(10,50,200,16,16,"Message Queue");
     94     LCD_ShowString(10,70,220,16,16,"KEY_UP:LED1 KEY0:Refresh LCD");
     95     LCD_ShowString(10,90,200,16,16,"KEY1:Tmr1 KEY2:BEEP");
     96     
     97     POINT_COLOR = BLACK;
     98     LCD_DrawLine(0,107,239,107);        //画线
     99     LCD_DrawLine(119,107,119,319);        //画线
    100     LCD_DrawRectangle(125,110,234,314);    //画矩形
    101     POINT_COLOR = RED;
    102     LCD_ShowString(0,130,100,16,16,"tmr1 state:");
    103     LCD_ShowString(0,170,120,16,16,"DATA_Msg Size:");
    104     LCD_ShowString(0,210,120,16,16,"DATA_Msg rema:");
    105     LCD_ShowString(0,250,100,16,16,"DATA_Msg:");
    106     POINT_COLOR = BLUE;
    107     LCD_ShowString(10,150,100,16,16,"TMR1 STOP! ");
    108 }
    109 
    110 //查询DATA_Msg消息队列中的总队列数量和剩余队列数量
    111 void check_msg_queue(u8 *p)
    112 {
    113     CPU_SR_ALLOC();
    114     u8 msgq_remain_size;    //消息队列剩余大小
    115     OS_CRITICAL_ENTER();    //进入临界段
    116     msgq_remain_size = DATA_Msg.MsgQ.NbrEntriesSize-DATA_Msg.MsgQ.NbrEntries;
    117     p = mymalloc(SRAMIN,20);    //申请内存
    118     sprintf((char*)p,"Total Size:%d",DATA_Msg.MsgQ.NbrEntriesSize);    //显示DATA_Msg消息队列总的大小
    119     LCD_ShowString(10,190,100,16,16,p);
    120     sprintf((char*)p,"Remain Size:%d",msgq_remain_size);    //显示DATA_Msg剩余大小
    121     LCD_ShowString(10,230,100,16,16,p);
    122     myfree(SRAMIN,p);        //释放内存
    123     OS_CRITICAL_EXIT();        //退出临界段
    124 }
    125                         
    126 int main(void)
    127 {
    128     OS_ERR err;
    129     CPU_SR_ALLOC();
    130     
    131     Stm32_Clock_Init(360,25,2,8);   //设置时钟,180Mhz   
    132     HAL_Init();                     //初始化HAL库
    133     delay_init(180);                //初始化延时函数
    134     uart_init(115200);              //初始化USART
    135     LED_Init();                     //初始化LED 
    136     KEY_Init();                     //初始化按键
    137     PCF8574_Init();                 //初始化PCF8974
    138     SDRAM_Init();                   //初始化SDRAM
    139     LCD_Init();                        //初始化LCD
    140     my_mem_init(SRAMIN);            //初始化内部内存池
    141     ucos_load_main_ui();            //加载主UI
    142     
    143     OSInit(&err);                    //初始化UCOSIII
    144     OS_CRITICAL_ENTER();            //进入临界区    
    145     //创建开始任务
    146     OSTaskCreate((OS_TCB     * )&StartTaskTCB,        //任务控制块
    147                  (CPU_CHAR    * )"start task",         //任务名字
    148                  (OS_TASK_PTR )start_task,             //任务函数
    149                  (void        * )0,                    //传递给任务函数的参数
    150                  (OS_PRIO      )START_TASK_PRIO,     //任务优先级
    151                  (CPU_STK   * )&START_TASK_STK[0],    //任务堆栈基地址
    152                  (CPU_STK_SIZE)START_STK_SIZE/10,    //任务堆栈深度限位
    153                  (CPU_STK_SIZE)START_STK_SIZE,        //任务堆栈大小
    154                  (OS_MSG_QTY  )0,                    //任务内部消息队列能够接收的最大消息数目,为0时禁止接收消息
    155                  (OS_TICK      )0,                    //当使能时间片轮转时的时间片长度,为0时为默认长度,
    156                  (void       * )0,                    //用户补充的存储区
    157                  (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR|OS_OPT_TASK_SAVE_FP, //任务选项,为了保险起见,所有任务都保存浮点寄存器的值
    158                  (OS_ERR     * )&err);                //存放该函数错误时的返回值
    159     OS_CRITICAL_EXIT();                //退出临界区     
    160     OSStart(&err);                  //开启UCOSIII
    161     while(1)
    162     {
    163     } 
    164 }
    165 
    166 //开始任务函数
    167 void start_task(void *p_arg)
    168 {
    169     OS_ERR err;
    170     CPU_SR_ALLOC();
    171     p_arg = p_arg;
    172     
    173     CPU_Init();
    174 #if OS_CFG_STAT_TASK_EN > 0u
    175    OSStatTaskCPUUsageInit(&err);      //统计任务                
    176 #endif
    177     
    178 #ifdef CPU_CFG_INT_DIS_MEAS_EN        //如果使能了测量中断关闭时间
    179     CPU_IntDisMeasMaxCurReset();    
    180 #endif
    181     
    182 #if    OS_CFG_SCHED_ROUND_ROBIN_EN     //当使用时间片轮转的时候
    183     //使能时间片轮转调度功能,设置默认的时间片长度
    184     OSSchedRoundRobinCfg(DEF_ENABLED,1,&err);  
    185 #endif    
    186         
    187     OS_CRITICAL_ENTER();    //进入临界区
    188     //创建消息队列KEY_Msg
    189     OSQCreate ((OS_Q*        )&KEY_Msg,    //消息队列
    190                 (CPU_CHAR*    )"KEY Msg",    //消息队列名称
    191                 (OS_MSG_QTY    )KEYMSG_Q_NUM,    //消息队列长度,这里设置为1
    192                 (OS_ERR*    )&err);        //错误码
    193     //创建消息队列DATA_Msg
    194     OSQCreate ((OS_Q*        )&DATA_Msg,    
    195                 (CPU_CHAR*    )"DATA Msg",    
    196                 (OS_MSG_QTY    )DATAMSG_Q_NUM,    
    197                 (OS_ERR*    )&err);    
    198     //创建定时器1
    199     OSTmrCreate((OS_TMR        *)&tmr1,        //定时器1
    200                 (CPU_CHAR    *)"tmr1",        //定时器名字
    201                 (OS_TICK     )0,            //0ms
    202                 (OS_TICK     )50,          //50*10=500ms
    203                 (OS_OPT         )OS_OPT_TMR_PERIODIC, //周期模式
    204                 (OS_TMR_CALLBACK_PTR)tmr1_callback,//定时器1回调函数
    205                 (void        *)0,            //参数为0
    206                 (OS_ERR        *)&err);        //返回的错误码
    207     //创建主任务
    208     OSTaskCreate((OS_TCB     * )&Main_TaskTCB,        
    209                  (CPU_CHAR    * )"Main task",         
    210                  (OS_TASK_PTR )main_task,             
    211                  (void        * )0,                    
    212                  (OS_PRIO      )MAIN_TASK_PRIO,     
    213                  (CPU_STK   * )&MAIN_TASK_STK[0],    
    214                  (CPU_STK_SIZE)MAIN_STK_SIZE/10,    
    215                  (CPU_STK_SIZE)MAIN_STK_SIZE,        
    216                  (OS_MSG_QTY  )0,                    
    217                  (OS_TICK      )0,                      
    218                  (void       * )0,                    
    219                  (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR|OS_OPT_TASK_SAVE_FP,
    220                  (OS_ERR     * )&err);            
    221     //创建按键任务
    222     OSTaskCreate((OS_TCB     * )&Keyprocess_TaskTCB,        
    223                  (CPU_CHAR    * )"Keyprocess task",         
    224                  (OS_TASK_PTR )Keyprocess_task,             
    225                  (void        * )0,                    
    226                  (OS_PRIO      )KEYPROCESS_TASK_PRIO,     
    227                  (CPU_STK   * )&KEYPROCESS_TASK_STK[0],    
    228                  (CPU_STK_SIZE)KEYPROCESS_STK_SIZE/10,    
    229                  (CPU_STK_SIZE)KEYPROCESS_STK_SIZE,        
    230                  (OS_MSG_QTY  )0,                    
    231                  (OS_TICK      )0,                      
    232                  (void       * )0,                    
    233                  (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR|OS_OPT_TASK_SAVE_FP,
    234                  (OS_ERR     * )&err);            
    235     //创建MSGDIS任务
    236     OSTaskCreate((OS_TCB     * )&Msgdis_TaskTCB,        
    237                  (CPU_CHAR    * )"Msgdis task",         
    238                  (OS_TASK_PTR )msgdis_task,             
    239                  (void        * )0,                    
    240                  (OS_PRIO      )MSGDIS_TASK_PRIO,     
    241                  (CPU_STK   * )&MSGDIS_TASK_STK[0],    
    242                  (CPU_STK_SIZE)MSGDIS_STK_SIZE/10,    
    243                  (CPU_STK_SIZE)MSGDIS_STK_SIZE,        
    244                  (OS_MSG_QTY  )0,                    
    245                  (OS_TICK      )0,                      
    246                  (void       * )0,                    
    247                  (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,
    248                  (OS_ERR     * )&err);    
    249     OS_CRITICAL_EXIT();    //退出临界区
    250     OSTaskDel((OS_TCB*)0,&err);    //删除start_task任务自身
    251 }
    252 
    253 //定时器1的回调函数
    254 void tmr1_callback(void *p_tmr,void *p_arg)
    255 {
    256     u8 *pbuf;
    257     static u8 msg_num;
    258     OS_ERR err;
    259     pbuf = mymalloc(SRAMIN,10);    //申请10个字节
    260     if(pbuf)    //申请内存成功
    261     {
    262         msg_num++;
    263         sprintf((char*)pbuf,"ALIENTEK %d",msg_num);
    264         //发送消息
    265         OSQPost((OS_Q*        )&DATA_Msg,        
    266                 (void*        )pbuf,
    267                 (OS_MSG_SIZE)10,
    268                 (OS_OPT        )OS_OPT_POST_FIFO,
    269                 (OS_ERR*    )&err);
    270         if(err != OS_ERR_NONE)
    271         {
    272             myfree(SRAMIN,pbuf);    //释放内存
    273             OSTmrStop(&tmr1,OS_OPT_TMR_NONE,0,&err); //停止定时器1
    274             tmr1sta = !tmr1sta;
    275             LCD_ShowString(10,150,100,16,16,"TMR1 STOP! ");
    276         }
    277     }    
    278 }
    279 
    280 //主任务的任务函数
    281 void main_task(void *p_arg)
    282 {
    283     u8 key,num;
    284     OS_ERR err;
    285     u8 *p;
    286     while(1)
    287     {
    288         key = KEY_Scan(0);  //扫描按键
    289         if(key)
    290         {
    291             //发送消息
    292             OSQPost((OS_Q*        )&KEY_Msg,        
    293                     (void*        )&key,
    294                     (OS_MSG_SIZE)1,
    295                     (OS_OPT        )OS_OPT_POST_FIFO,
    296                     (OS_ERR*    )&err);
    297         }
    298         num++;
    299         if(num%10==0) check_msg_queue(p);//检查DATA_Msg消息队列的容量
    300         if(num==50)
    301         {
    302             num=0;
    303             LED0=!LED0;
    304         }
    305         OSTimeDlyHMSM(0,0,0,10,OS_OPT_TIME_PERIODIC,&err);   //延时10ms
    306     }
    307 }
    308 
    309 //按键处理任务的任务函数
    310 void Keyprocess_task(void *p_arg)
    311 {    
    312     u8 num,beepsta=1;
    313     u8 *key;
    314     OS_MSG_SIZE size;
    315     OS_ERR err;
    316     while(1)
    317     {
    318         //请求消息KEY_Msg
    319         key=OSQPend((OS_Q*            )&KEY_Msg,   
    320                     (OS_TICK        )0,
    321                     (OS_OPT            )OS_OPT_PEND_BLOCKING,
    322                     (OS_MSG_SIZE*    )&size,        
    323                     (CPU_TS*        )0,
    324                     (OS_ERR*        )&err);
    325         switch(*key)
    326         {
    327             case WKUP_PRES:        //KEY_UP控制LED1
    328                 LED1=!LED1;
    329                 break;
    330             case KEY2_PRES:        //KEY2控制蜂鸣器
    331                 beepsta=!beepsta;
    332                PCF8574_WriteBit(BEEP_IO,beepsta);
    333                 break;
    334             case KEY0_PRES:        //KEY0刷新LCD背景
    335                 num++;
    336                 LCD_Fill(126,111,233,313,lcd_discolor[num%14]);
    337                 break;
    338             case KEY1_PRES:        //KEY1控制定时器1
    339                 tmr1sta = !tmr1sta;
    340                 if(tmr1sta) 
    341                 {
    342                     OSTmrStart(&tmr1,&err);
    343                     LCD_ShowString(10,150,100,16,16,"TMR1 START!");
    344                 }
    345                 else
    346                 {
    347                     OSTmrStop(&tmr1,OS_OPT_TMR_NONE,0,&err); //停止定时器1
    348                     LCD_ShowString(10,150,100,16,16,"TMR1 STOP! ");
    349                 }
    350                 break;
    351         }
    352     }
    353 }
    354 
    355 //显示消息队列中的消息
    356 void msgdis_task(void *p_arg)
    357 {
    358     u8 *p;
    359     OS_MSG_SIZE size;
    360     OS_ERR err; 
    361     while(1)
    362     {
    363         //请求消息
    364         p=OSQPend((OS_Q*        )&DATA_Msg,   
    365                   (OS_TICK        )0,
    366                   (OS_OPT        )OS_OPT_PEND_BLOCKING,
    367                   (OS_MSG_SIZE*    )&size,    
    368                   (CPU_TS*        )0,
    369                   (OS_ERR*        )&err);
    370         LCD_ShowString(5,270,100,16,16,p);
    371         myfree(SRAMIN,p);    //释放内存
    372         OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_PERIODIC,&err); //延时1s
    373     }
    374 }
    View Code

    //创建消息队列KEY_Msg
    OSQCreate ((OS_Q* )&KEY_Msg, //消息队列
    (CPU_CHAR* )"KEY Msg", //消息队列名称
    (OS_MSG_QTY )KEYMSG_Q_NUM, //消息队列长度,这里设置为1
    (OS_ERR* )&err); //错误码
    //创建消息队列DATA_Msg
    OSQCreate ((OS_Q* )&DATA_Msg,
    (CPU_CHAR* )"DATA Msg",
    (OS_MSG_QTY )DATAMSG_Q_NUM,
    (OS_ERR* )&err);
    //创建定时器1
    OSTmrCreate((OS_TMR *)&tmr1, //定时器1
    (CPU_CHAR *)"tmr1", //定时器名字
    (OS_TICK )0, //0ms
    (OS_TICK )50, //50*10=500ms
    (OS_OPT )OS_OPT_TMR_PERIODIC, //周期模式
    (OS_TMR_CALLBACK_PTR)tmr1_callback,//定时器1回调函数
    (void *)0, //参数为0
    (OS_ERR *)&err); //返回的错误码

    //定时器1的回调函数
    void tmr1_callback(void *p_tmr,void *p_arg)
    {
    u8 *pbuf;
    static u8 msg_num;
    OS_ERR err;
    pbuf = mymalloc(SRAMIN,10); //申请10个字节
    if(pbuf) //申请内存成功
    {
    msg_num++;
    sprintf((char*)pbuf,"ALIENTEK %d",msg_num);
    //发送消息
    OSQPost((OS_Q* )&DATA_Msg,
    (void* )pbuf,
    (OS_MSG_SIZE)10,
    (OS_OPT )OS_OPT_POST_FIFO,
    (OS_ERR* )&err);
    if(err != OS_ERR_NONE)
    {
    myfree(SRAMIN,pbuf); //释放内存
    OSTmrStop(&tmr1,OS_OPT_TMR_NONE,0,&err); //停止定时器1
    tmr1sta = !tmr1sta;
    LCD_ShowString(10,150,100,16,16,"TMR1 STOP! ");
    }
    }
    }

    //发送消息
    OSQPost((OS_Q* )&KEY_Msg,
    (void* )&key,
    (OS_MSG_SIZE)1,
    (OS_OPT )OS_OPT_POST_FIFO,
    (OS_ERR* )&err);

    //请求消息KEY_Msg
    key=OSQPend((OS_Q* )&KEY_Msg,
    (OS_TICK )0,
    (OS_OPT )OS_OPT_PEND_BLOCKING,
    (OS_MSG_SIZE* )&size,
    (CPU_TS* )0,
    (OS_ERR* )&err);

    //请求消息
    p=OSQPend((OS_Q* )&DATA_Msg,
    (OS_TICK )0,
    (OS_OPT )OS_OPT_PEND_BLOCKING,
    (OS_MSG_SIZE* )&size,
    (CPU_TS* )0,
    (OS_ERR* )&err);

    内建消息 

    //创建MSGDIS任务
    OSTaskCreate((OS_TCB * )&Msgdis_TaskTCB,
    (CPU_CHAR * )"Msgdis task",
    (OS_TASK_PTR )msgdis_task,
    (void * )0,
    (OS_PRIO )MSGDIS_TASK_PRIO,
    (CPU_STK * )&MSGDIS_TASK_STK[0],
    (CPU_STK_SIZE)MSGDIS_STK_SIZE/10,
    (CPU_STK_SIZE)MSGDIS_STK_SIZE,
    (OS_MSG_QTY )TASK_Q_NUM, //任务Msgdis_task需要使用内建消息队列,消息队列长度为4
    (OS_TICK )0,
    (void * )0,
    (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR|OS_OPT_TASK_SAVE_FP,
    (OS_ERR * )&err);

    发送

    //发送消息
    OSTaskQPost((OS_TCB* )&Msgdis_TaskTCB, //向任务Msgdis发送消息
    (void* )pbuf,
    (OS_MSG_SIZE)10,
    (OS_OPT )OS_OPT_POST_FIFO,
    (OS_ERR* )&err);
    if(err != OS_ERR_NONE)
    {
    myfree(SRAMIN,pbuf); //释放内存
    OSTmrStop(&tmr1,OS_OPT_TMR_NONE,0,&err); //停止定时器1
    tmr1sta = !tmr1sta;
    LCD_ShowString(40,150,100,16,16,"TMR1 STOP! ");
    }

    //请求消息
    p=OSTaskQPend((OS_TICK )0,
    (OS_OPT )OS_OPT_PEND_BLOCKING,
    (OS_MSG_SIZE* )&size,
    (CPU_TS* )0,
    (OS_ERR* )&err );

      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 //UCOSIII中以下优先级用户程序不能使用,ALIENTEK
     14 //将这些优先级分配给了UCOSIII的5个系统内部任务
     15 //优先级0:中断服务服务管理任务 OS_IntQTask()
     16 //优先级1:时钟节拍任务 OS_TickTask()
     17 //优先级2:定时任务 OS_TmrTask()
     18 //优先级OS_CFG_PRIO_MAX-2:统计任务 OS_StatTask()
     19 //优先级OS_CFG_PRIO_MAX-1:空闲任务 OS_IdleTask()
     20 
     21 
     22 //任务优先级
     23 #define START_TASK_PRIO        3
     24 //任务堆栈大小    
     25 #define START_STK_SIZE         128
     26 //任务控制块
     27 OS_TCB StartTaskTCB;
     28 //任务堆栈    
     29 CPU_STK START_TASK_STK[START_STK_SIZE];
     30 //任务函数
     31 void start_task(void *p_arg);
     32 
     33 //任务优先级
     34 #define MAIN_TASK_PRIO        4
     35 //任务堆栈大小    
     36 #define MAIN_STK_SIZE         128
     37 //任务控制块
     38 OS_TCB Main_TaskTCB;
     39 //任务堆栈    
     40 CPU_STK MAIN_TASK_STK[MAIN_STK_SIZE];
     41 void main_task(void *p_arg);
     42 
     43 //任务优先级
     44 #define MSGDIS_TASK_PRIO    6
     45 //任务堆栈
     46 #define MSGDIS_STK_SIZE        128
     47 //任务控制块
     48 OS_TCB    Msgdis_TaskTCB;
     49 //任务堆栈
     50 CPU_STK    MSGDIS_TASK_STK[MSGDIS_STK_SIZE];
     51 //任务函数
     52 void msgdis_task(void *p_arg);
     53 
     54 //LCD刷屏时使用的颜色
     55 int lcd_discolor[14]={    WHITE, BLACK, BLUE,  BRED,      
     56                         GRED,  GBLUE, RED,   MAGENTA,            
     57                         GREEN, CYAN,  YELLOW,BROWN,             
     58                         BRRED, GRAY };
     59 
     60 #define TASK_Q_NUM    4        //发任务内建消息队列的长度
     61                         
     62 ////////////////////////定时器////////////////////////////////
     63 u8 tmr1sta=0;     //标记定时器的工作状态
     64 OS_TMR    tmr1;    //定义一个定时器
     65 void tmr1_callback(void *p_tmr,void *p_arg); //定时器1回调函数
     66                         
     67                         
     68 //加载主界面
     69 void ucos_load_main_ui(void)
     70 {
     71     POINT_COLOR = RED;
     72     LCD_ShowString(10,10,200,16,16,"Apollo STM32F4/F7");    
     73     LCD_ShowString(10,30,200,16,16,"UCOSIII Examp 11-2");
     74     LCD_ShowString(10,50,200,16,16,"Task Queue");
     75     LCD_ShowString(10,70,220,16,16,"KEY_UP:Tmr1");
     76     LCD_ShowString(10,90,200,16,16,"2016/1/21");
     77     
     78     POINT_COLOR = BLACK;
     79     LCD_DrawLine(0,107,239,107);        //画线
     80     POINT_COLOR = RED;
     81     LCD_ShowString(30,130,100,16,16,"tmr1 state:");
     82     LCD_ShowString(30,170,120,16,16,"Task_QMsg Size:");
     83     LCD_ShowString(30,210,120,16,16,"Task_QMsg rema:");
     84     LCD_ShowString(30,250,100,16,16,"Task_QMsg:");
     85     POINT_COLOR = BLUE;
     86     LCD_ShowString(40,150,100,16,16,"TMR1 STOP! ");
     87 }
     88 
     89 //查询DATA_Msg消息队列中的总队列数量和剩余队列数量
     90 void check_msg_queue(u8 *p)
     91 {
     92     CPU_SR_ALLOC();
     93     u8 msgq_remain_size;    //消息队列剩余大小
     94     OS_CRITICAL_ENTER();    //进入临界段
     95     msgq_remain_size =Msgdis_TaskTCB.MsgQ.NbrEntriesSize-Msgdis_TaskTCB.MsgQ.NbrEntries;
     96     p = mymalloc(SRAMIN,20);    //申请内存
     97     sprintf((char*)p,"Total Size:%d",Msgdis_TaskTCB.MsgQ.NbrEntriesSize);    //显示DATA_Msg消息队列总的大小
     98     LCD_ShowString(40,190,100,16,16,p);
     99     sprintf((char*)p,"Remain Size:%d",msgq_remain_size);    //显示DATA_Msg剩余大小
    100     LCD_ShowString(40,230,100,16,16,p);
    101     myfree(SRAMIN,p);        //释放内存
    102     OS_CRITICAL_EXIT();        //退出临界段
    103 }
    104                         
    105 int main(void)
    106 {
    107     OS_ERR err;
    108     CPU_SR_ALLOC();
    109     
    110     Stm32_Clock_Init(360,25,2,8);   //设置时钟,180Mhz   
    111     HAL_Init();                     //初始化HAL库
    112     delay_init(180);                //初始化延时函数
    113     uart_init(115200);              //初始化USART
    114     LED_Init();                     //初始化LED 
    115     KEY_Init();                     //初始化按键
    116     PCF8574_Init();                 //初始化PCF8974
    117     SDRAM_Init();                   //初始化SDRAM
    118     LCD_Init();                        //初始化LCD
    119     my_mem_init(SRAMIN);            //初始化内部内存池
    120     ucos_load_main_ui();            //加载主UI
    121     
    122     OSInit(&err);                    //初始化UCOSIII
    123     OS_CRITICAL_ENTER();            //进入临界区    
    124     //创建开始任务
    125     OSTaskCreate((OS_TCB     * )&StartTaskTCB,        //任务控制块
    126                  (CPU_CHAR    * )"start task",         //任务名字
    127                  (OS_TASK_PTR )start_task,             //任务函数
    128                  (void        * )0,                    //传递给任务函数的参数
    129                  (OS_PRIO      )START_TASK_PRIO,     //任务优先级
    130                  (CPU_STK   * )&START_TASK_STK[0],    //任务堆栈基地址
    131                  (CPU_STK_SIZE)START_STK_SIZE/10,    //任务堆栈深度限位
    132                  (CPU_STK_SIZE)START_STK_SIZE,        //任务堆栈大小
    133                  (OS_MSG_QTY  )0,                    //任务内部消息队列能够接收的最大消息数目,为0时禁止接收消息
    134                  (OS_TICK      )0,                    //当使能时间片轮转时的时间片长度,为0时为默认长度,
    135                  (void       * )0,                    //用户补充的存储区
    136                  (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR|OS_OPT_TASK_SAVE_FP, //任务选项,为了保险起见,所有任务都保存浮点寄存器的值
    137                  (OS_ERR     * )&err);                //存放该函数错误时的返回值
    138     OS_CRITICAL_EXIT();                //退出临界区     
    139     OSStart(&err);                  //开启UCOSIII
    140     while(1)
    141     {
    142     } 
    143 }
    144 
    145 //开始任务函数
    146 void start_task(void *p_arg)
    147 {
    148     OS_ERR err;
    149     CPU_SR_ALLOC();
    150     p_arg = p_arg;
    151     
    152     CPU_Init();
    153 #if OS_CFG_STAT_TASK_EN > 0u
    154    OSStatTaskCPUUsageInit(&err);      //统计任务                
    155 #endif
    156     
    157 #ifdef CPU_CFG_INT_DIS_MEAS_EN        //如果使能了测量中断关闭时间
    158     CPU_IntDisMeasMaxCurReset();    
    159 #endif
    160     
    161 #if    OS_CFG_SCHED_ROUND_ROBIN_EN  //当使用时间片轮转的时候
    162     //使能时间片轮转调度功能,设置默认的时间片长度
    163     OSSchedRoundRobinCfg(DEF_ENABLED,1,&err);  
    164 #endif    
    165         
    166     OS_CRITICAL_ENTER();    //进入临界区
    167     //创建定时器1
    168     OSTmrCreate((OS_TMR        *)&tmr1,        //定时器1
    169                 (CPU_CHAR    *)"tmr1",        //定时器名字
    170                 (OS_TICK     )0,            //0ms
    171                 (OS_TICK     )50,           //50*10=500ms
    172                 (OS_OPT         )OS_OPT_TMR_PERIODIC, //周期模式
    173                 (OS_TMR_CALLBACK_PTR)tmr1_callback,//定时器1回调函数
    174                 (void        *)0,            //参数为0
    175                 (OS_ERR        *)&err);        //返回的错误码
    176     //创建主任务
    177     OSTaskCreate((OS_TCB     * )&Main_TaskTCB,        
    178                  (CPU_CHAR    * )"Main task",         
    179                  (OS_TASK_PTR )main_task,             
    180                  (void        * )0,                    
    181                  (OS_PRIO      )MAIN_TASK_PRIO,     
    182                  (CPU_STK   * )&MAIN_TASK_STK[0],    
    183                  (CPU_STK_SIZE)MAIN_STK_SIZE/10,    
    184                  (CPU_STK_SIZE)MAIN_STK_SIZE,        
    185                  (OS_MSG_QTY  )0,                    
    186                  (OS_TICK      )0,                      
    187                  (void       * )0,                    
    188                  (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR|OS_OPT_TASK_SAVE_FP,
    189                  (OS_ERR     * )&err);                    
    190     //创建MSGDIS任务
    191     OSTaskCreate((OS_TCB     * )&Msgdis_TaskTCB,        
    192                  (CPU_CHAR    * )"Msgdis task",         
    193                  (OS_TASK_PTR )msgdis_task,             
    194                  (void        * )0,                    
    195                  (OS_PRIO      )MSGDIS_TASK_PRIO,     
    196                  (CPU_STK   * )&MSGDIS_TASK_STK[0],    
    197                  (CPU_STK_SIZE)MSGDIS_STK_SIZE/10,    
    198                  (CPU_STK_SIZE)MSGDIS_STK_SIZE,        
    199                  (OS_MSG_QTY  )TASK_Q_NUM,        //任务Msgdis_task需要使用内建消息队列,消息队列长度为4                    
    200                  (OS_TICK      )0,                      
    201                  (void       * )0,                    
    202                  (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR|OS_OPT_TASK_SAVE_FP,
    203                  (OS_ERR     * )&err);    
    204     OS_CRITICAL_EXIT();    //退出临界区
    205     OSTaskDel((OS_TCB*)0,&err);    //删除start_task任务自身
    206 }
    207 
    208 //定时器1的回调函数
    209 void tmr1_callback(void *p_tmr,void *p_arg)
    210 {
    211     u8 *pbuf;
    212     static u8 msg_num;
    213     OS_ERR err;
    214     pbuf = mymalloc(SRAMIN,10);    //申请10个字节
    215     if(pbuf)    //申请内存成功
    216     {
    217         msg_num++;
    218         sprintf((char*)pbuf,"ALIENTEK %d",msg_num);
    219         //发送消息
    220         OSTaskQPost((OS_TCB*    )&Msgdis_TaskTCB,    //向任务Msgdis发送消息
    221                     (void*        )pbuf,
    222                     (OS_MSG_SIZE)10,
    223                     (OS_OPT        )OS_OPT_POST_FIFO,
    224                     (OS_ERR*    )&err);
    225         if(err != OS_ERR_NONE)
    226         {
    227             myfree(SRAMIN,pbuf);    //释放内存
    228             OSTmrStop(&tmr1,OS_OPT_TMR_NONE,0,&err); //停止定时器1
    229             tmr1sta = !tmr1sta;
    230             LCD_ShowString(40,150,100,16,16,"TMR1 STOP! ");
    231         }
    232     }    
    233 }
    234 
    235 //主任务的任务函数
    236 void main_task(void *p_arg)
    237 {
    238     u8 key,num;
    239     OS_ERR err;
    240     u8 *p;
    241     while(1)
    242     {
    243         key = KEY_Scan(0);  //扫描按键
    244         if(key==WKUP_PRES)
    245         {
    246             tmr1sta = !tmr1sta;
    247             if(tmr1sta) 
    248             {
    249                 OSTmrStart(&tmr1,&err);
    250                 LCD_ShowString(40,150,100,16,16,"TMR1 START!");
    251             }
    252             else
    253             {
    254                 OSTmrStop(&tmr1,OS_OPT_TMR_NONE,0,&err); //停止定时器1
    255                 LCD_ShowString(40,150,100,16,16,"TMR1 STOP! ");
    256             }
    257         }
    258         num++;
    259         if(num%10==0) check_msg_queue(p);//检查DATA_Msg消息队列的容量
    260         if(num==50)
    261         {
    262             num=0;
    263             LED0=!LED0;
    264         }
    265         OSTimeDlyHMSM(0,0,0,10,OS_OPT_TIME_PERIODIC,&err);   //延时10ms
    266     }
    267 }
    268 
    269 //显示消息队列中的消息
    270 void msgdis_task(void *p_arg)
    271 {
    272     u8 *p;
    273     OS_MSG_SIZE size;
    274     OS_ERR err; 
    275     while(1)
    276     {
    277         //请求消息
    278         p=OSTaskQPend((OS_TICK        )0,
    279                       (OS_OPT        )OS_OPT_PEND_BLOCKING,
    280                       (OS_MSG_SIZE*    )&size,
    281                       (CPU_TS*        )0,
    282                       (OS_ERR*      )&err );
    283         LCD_ShowString(40,270,100,16,16,p);
    284         myfree(SRAMIN,p);    //释放内存
    285         OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_PERIODIC,&err); //延时1s
    286     }
    287 }
    View Code
  • 相关阅读:
    BZOJ 2034 【2009国家集训队】 最大收益
    vijos P1780 【NOIP2012】 开车旅行
    BZOJ 2115 【WC2011】 Xor
    BZOJ 3631 【JLOI2014】 松鼠的新家
    BZOJ 4717 改装
    BZOJ 2957 楼房重建
    BZOJ 4034 【HAOI2015】 T2
    BZOJ 1834 【ZJOI2010】 network 网络扩容
    BZOJ 2440 【中山市选2011】 完全平方数
    BZOJ 2733 【HNOI2012】 永无乡
  • 原文地址:https://www.cnblogs.com/mrguoguo/p/13716583.html
Copyright © 2011-2022 走看看