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
  • 相关阅读:
    android工程混淆和反编译
    php+列出目录文件
    php+大文件管理
    支持粘贴图片的富文本编辑器
    web上传整个文件夹
    文件夹管理
    断点续传
    超大文件上传方案
    ueditor+word粘贴上传
    java+大文件上传
  • 原文地址:https://www.cnblogs.com/mrguoguo/p/13716583.html
Copyright © 2011-2022 走看看