您的位置:首页 > 其它

向消息队列发送一个消息(FIFO),OSQPost()

2017-04-12 10:17 330 查看
程序清单 L6.23是OSQPost()函数的源代码。在确认事件控制块是消息队列后 [L6.23(1)],OSQPost()函数检查是否有任务在等待该消息队列中的消息[L6.23(2)]。当事件控制块的.OSEventGrp域为非0值时,说明该消息队列的等待任务列表中有任务。这时,调用OSEventTaskRdy()函数 [见6.02节,使一个任务进入就绪状态,OSEventTaskRdy()]从列表中取出最高优先级的任务[L6.23(3)],并将它置于就绪状态。然后调用函数OSSched() [L6.23(4)]进行任务的调度。如果上面取出的任务的优先级在整个系统就绪的任务里也是最高的,而且OSQPost()函数不是中断服务子程序调用的,就执行任务切换,该最高优先级任务被执行。否则的话,OSSched()函数直接返回,调用OSQPost()函数的任务继续执行。

程序清单 L6.23 向消息队列发送一条消息
INT8U OSQPost (OS_EVENT *pevent, void *msg)
{
OS_Q   *pq;
OS_ENTER_CRITICAL();
if (pevent->OSEventType != OS_EVENT_TYPE_Q) {	                (1)
OS_EXIT_CRITICAL();
return (OS_ERR_EVENT_TYPE);
}
if (pevent->OSEventGrp) {	                                    (2)
OSEventTaskRdy(pevent, msg, OS_STAT_Q);	                  (3)
OS_EXIT_CRITICAL();
OSSched();                                                           (4)
return (OS_NO_ERR);
} else {
pq = pevent->OSEventPtr;
if (pq->OSQEntries >= pq->OSQSize) {	                     (5)
OS_EXIT_CRITICAL();
return (OS_Q_FULL);
} else {
*pq->OSQIn++ = msg;	                                  (6)
pq->OSQEntries++;
if (pq->OSQIn == pq->OSQEnd) {
pq->OSQIn = pq->OSQStart;
}
OS_EXIT_CRITICAL();
}
return (OS_NO_ERR);
}
}

如果没有任务等待该消息队列中的消息,而且此时消息队列未满[L6.23(5)],指向该消息的指针被插入到消息队列中[L6.23(6)]。这样,下一个调用OSQPend()函数的任务就可以马上得到该消息。注意,如果此时消息队列已满,那么该消息将由于不能插入到消息队列中而丢失。
此外,如果OSQPost()函数是由中断服务子程序调用的,那么即使产生了更高优先级的任务,也不会在调用OSSched()函数时发生任务切换。这个动作一直要等到中断嵌套的最外层中断服务子程序调用OSIntExit()函数时才能进行(见3.09节,µC/OS-II中的中断)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐