UC/OS-II学习笔记之消息队列使用
UC/OS-II学习笔记之消息队列使用
对消息队列的学习理解有点难,对技术来说,一本好的书一般是原理和例子相结合的,可惜我找到的很少。书上说消息队列实际上是多个邮箱组成的数组,是一个列表。这个数组其实是个指针数组,里面每个指针可以指向不同类型的变量,通过传递一个个指针,我们可以做到传递指针所指向的一个个变量。(顺便复习下,一个邮箱只能传递一个指针,而队列可传递多个)。#include <INCLUDES.H>
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
OS_STK TaskStk[3][MaxStkSize];//定义3个堆栈
void task0(void *dat);//定义任务0
void task1(void *dat);//定义任务1
long con1=0;
long con2=0;
OS_EVENT *Com1; //定义一个指针
void *ComMsg1[3]; //定义一个指针数组
u8 err;
u8 st[4]={0x01,0x02,0x03,0x04};//定义一个数组
u8 aa[4]={0x05,0x04,0x06,0x09};//定义一个数组
u8 a1=0xFF;//定义一个数
main()
{
OSInit();//初始化ucosii
InitTimer0();
Com1=OSQCreate(&ComMsg1[0],3);//建立一个消息队列(即为数组指针) 消息内存大小为3
OSQPost(Com1,(void*)&st[0]); //发送到队列
OSQPost(Com1,(void*)&aa[0]); //发送到队列
OSQPost(Com1,(void*)&a1); //发送到队列
OSTaskCreate(task0,(void*)0,&TaskStk[0][0],5);//建立任务 定义好它的优先级等参数
OSTaskCreate(task1,(void*)0,&TaskStk[1][0],6);
OSStart();//系统启动
}
void task0(void *dat)//任务0
{
dat="dat";//防止编译有错误
while(1)
{
con1++;
OSTimeDly(2);
}
}
void task1(void *dat)
{
u8 *msg1;
u8 cc,b;
dat="dat";//防止编译有错误
while(1)
{
msg1=OSQPend(Com1,0,&err);
cc=*msg1;
b=*(msg1+1);
con2++;
OSTimeDly(2);
}
}
心得:
Com1=OSQCreate(&ComMsg1[0],3),建立一个队列,将*Com1指针将指向队列指针数组*ComMsg1[3]的首地址。3表示内存大小。
OSQPost(Com1,(void*)&st[0]),是以先入先出发送消息到队列,由*ComMsg1[0]指向数组st的首地址,同时队列消息数加一。
OSQPost(Com1,(void*)&aa[0])发一个消息给队列,此时是由*ComMsg1[1]指向aa数组的首地址,同时队列消息数加一。; 依此类推,发下一个也是一样。(如果队列满了,再发送消息到队列的话,队列将会出现错误)。
msg1=OSQPend(Com1,0,&err);是等待消息队列函数,获得指针数组里的第一个指针ComMsg1[0],该指针指向st[0],。cc=*msg1是通过指针获得指向的具体值st[0]=0x01;如果再调用一次msg1=OSQPend(Com1,0,&err),将获得指针数组里下一个指针ComMsg1[1],依此类推。
每调用一次OSQPend函数,该函数会将队列的消息减一,Com1指向下一个消息指针*ComMsg1[i++],直到队列完全没有消息为止。在例子中,只有3个消息,程序将执行3次任务1后,队列已经没有消息了,所以将任务1暂停