分类:
2009-03-23 16:33:18
ucos觉得使用它还是需要很多技巧性的,也就是说ucos需要技巧性的操作,今天我就我对邮箱这一块的看法说说。下面我用一个例子说一下
首先例子的功能就是创建一个邮箱myMbox利用它所存取的msg不同而进行相应的任务调度。程序片段如下
OS_EVENT *myMbox;
Static INT8U TaskAMsg,TaskBMsg;
myMbox = OSMboxCreate((void *)TaskAMsg)
void TaskA(void *i)
{
for (;;)
{
if(OSMboxPend(myMbox,0,&myErr)== (void *)& TaskAMsg)
{
Uart_Printf("TaskA\n");
OSTimeDly(100); (1)
OSMboxPost(myMbox,(void *)& TaskBMsg);
OSTimeDly(100); (2)
}
}
}
void TaskB(void *i)
{
for (;;)
{
if(OSMboxPend(myMbox,0,&myErr) == (void *)& TaskBMsg)
{
Uart_Printf("TaskB\n");
OSTimeDly(100); (1)
OSMboxPost(myMbox,(void *)& TaskAMsg);
OSTimeDly(100); (2)
}
}
OSTaskCreate(TaskA, (void *)0, (void *)&Task_Stk5[STK_size_S - 1], 6);
OSTaskCreate(TaskB, (void *)0, (void *)&Task_Stk6[STK_size_S - 1], 7);
大概的程序片度如上,这里我特地把OSTimeDly分成两种情况放置,但程序运行的结果是一样的,个人认为放置在位置(2)上容易理解,下面我们要讨论的是放在位置一上是个怎么回事。
从程序中我们可以大概看出,首先创建了一个邮箱myMbox 初始化它的消息内容为TaskAMsg(想想这里可以初始化为TaskBMsg吗?)好了从任务A开始看起。首先程序运行当然是先执行TaskA了,因为它的优先级是最高的是吧。那么由于邮箱有初始化也就是msg != (void*)0;的情况,这个时候OSMboxPend就直接返回了Msg,它是一个地址。在if语句中判断是不是TaskA要等的消息,如果是就执行if语句的内容,从初始化我们知道这里肯定会执行if语句的内容了。那么好了打印完了之后就是OSTimeDly(100)了,也就是说TaskA到了这里就开始被挂起100个tick了。这时候是怎么挂起的呢,对就是直接从Rdy表中把它给删除掉,等到100个tick过去后在重新添加近Rdy表。我们要注意的是,在这里TaskA没有被放在事件等待的Rdy里头。那么程序在这100个tick期间去做什么去了呢!当然程序挂起了TaskA也就只能跑到TaskB去了。到了TaskB由于邮箱这个时候还没有消息(看清楚OSMboxPost放在OSTimeDly后面),也就是TaskB执行了OSMboxPend,但由于邮箱里头的msg是空的,那么它就将TaskB给挂起了,挂起了放在哪里了呢?注意了,这个时候TaskB就被添加在事件等待列表里头了。然后程序去做什么去了?这个时候如果TaskA和TaskB如果都还没有Rdy的话,那么程序就去执行IDLE任务拉。等到TaskA的tick到了之后就执行OSMboxPost(myMbox,(void *)& TaskBMsg);也就是给myMbox投递一封邮件了,邮件的内容是TaskBMsg因为我们的收信人是TaskB。这个时候OSMboxPost首先会检查事件等待列表中是否有任务在等待,如果有的话就把里头优先级最高的任务给拿出来放到Rdy表里头去并且将我们刚才邮寄的信转发给它并放到它自己的信箱里头,这里我们是把给TaskB的信放在TaskB的OSTCBMsg里头,然后看看这个任务是否已经就绪了,如果是就把它添加到Rdy里头去。那么这这里TaskB是不是已经就绪了呢?
是的,到这里,TaskB就被添加到Rdy表去了。跟着TaskA就回到if语句上,第一次判断邮箱是非空的,但里面的消息并不是TaskA所要的,这时候OSMboxPend还把邮箱清空了。第二次执行OSMboxPend的时候由于邮箱在第一次的时候被清空了,这个时候TaskA就被挂起拉,并且添加到事件等待列表中去。然后进行任务切换了,任务切换到TaskB去。执行OSMboxPend未执行完的语句。那么之前是执行到OSSched那里,现在往下去执行msg = OSTCBCur->OSTCBMsg;这条语句。我们知道刚才在TaskA的OSMboxPost的时候它把信放在TaskB的OSTCBMsg里头,那么这个时候OSMboxPend就不等待了,就执行if语句了哦。跟着的过程就和上面的一样了。到这里把OSTimeDly放在位置(1)的情况个人分析就结束了,那么放在位置(2)呢,这也太容易理解了吧。