OSQPend的分析

void  *OSQPend (OS_EVENT *pevent, INT16U timeout, INT8U *perr)


pevent 消息队列事件指针;timout被消息队列阻塞的超时时间;perr错误代号存储地址

1、检查参数合法性,包括pevent地址是否为空、perr地址是否为空;事件类型是否为消息队列;中断嵌套层数是否大于0,大于0表示有中断在执行,此时不能调用本函数;任务锁嵌套层数是否大于0,大于0不能调用本函数

OS_ENTER_CRITICAL();
pq = (OS_Q *)pevent->OSEventPtr;

2、关中断,取得消息队列事件指针所指向的消息队列

if (pq->OSQEntries > 0) 

3、当消息队列入口地址大于0,表示消息队列中有数据,将消息队列中的数据出口地址赋值给一个地址变量pmsg,递增出口地址且递减入口地址数(减少消息队列中数据数量);当数据出口地址到了消息队列末端时,重新赋值数据出口地址,返回消息队列中数据地址,置位perr无错标志

4、设置当前任务的任务控制块状态为消息队列挂起,挂起状态为挂起中(还有超时和终止两种状态),设置超时时间

OS_EventTaskWait(pevent)————————————————需要了解void  OSTimeTick (void)中的内容:检测当超时时间马上要到(下一step就到),假如有事件位,清空事件位,并置位事件超时;没有事件位,置位事件OK;然后当该任务是挂起状态,则置位任务准备组和准备表。在systick中调用了该函数,该函数后是OSIntExit();,OSIntExit();中执行了任务调度。

5、OS_EventTaskWait(pevent)函数实现了事件没有发送的话,挂起该任务。

在任务控制块中存储挂起该任务的事件指针;在事件控制块中的任务信息中,置位该任务,也就是添加事件中挂起的任务ID(优先级);在运行任务的任务信息中,清楚该任务的信息,防止被调度;当该任务所在的优先级字节为0,表明整个优先级组没有任务,清空优先组代表的那个位,避免无效工作

6、执行任务调度,运行了其他任务,该任务的上下文被保存到堆栈中

7、当消息队列中收到消息,(post动作),则会将该任务的上下文切换到运行任务信息中,再进行任务调度,从而恢复了该任务的运行


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值