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

 

posted @ 2020-09-23 10:07  一颗大白鲸  阅读(921)  评论(0编辑  收藏  举报