📄 os_q.c
字号:
}
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* 清空消息队列
*
* 函数描述 : 该函数用于清空消息队列中的内容
*
* 输入参数 : 无
*
* 返回值 : OS_NO_ERR 调用成功
* OS_ERR_EVENT_TYPE 从一个非消息队列中获取信息
* OS_ERR_PEVENT_NULL 'pevent' 是一个空指针
*********************************************************************************************************
*/
#if OS_Q_FLUSH_EN > 0
INT8U OSQFlush (OS_EVENT *pevent)
{
#if OS_CRITICAL_METHOD == 3 /* 为CPU状态寄存器分配存储变量 */
OS_CPU_SR cpu_sr;
#endif
OS_Q *pq;
#if OS_ARG_CHK_EN > 0
if (pevent == (OS_EVENT *)0)
{ /* 无效的 'pevent' */
return (OS_ERR_PEVENT_NULL);
}
if (pevent->OSEventType != OS_EVENT_TYPE_Q)
{ /* 无效的事件块类型 */
return (OS_ERR_EVENT_TYPE);
}
#endif
OS_ENTER_CRITICAL();
pq = (OS_Q *)pevent->OSEventPtr; /* 指向队列的存储结构 */
pq->OSQIn = pq->OSQStart;
pq->OSQOut = pq->OSQStart;
pq->OSQEntries = 0;
OS_EXIT_CRITICAL();
return (OS_NO_ERR);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* 等待队列中的消息
*
* 函数描述: 该函数等待发送到队列中的消息
*
* 输入参数 : pevent 指向带有期望队列的ECB的指针
*
* timeout 选择延时时间。如果非0,则任务将在指定的延时时间内等待到达队列中的消息。如果为0,
* 则任务将一直等待队列中消息的到来。
* err 指向出错代码的指针。其值为:
*
* OS_NO_ERR 调用成功,任务收到消息
* OS_TIMEOUT 在指定的延时时间内,没有收到消息
* OS_ERR_EVENT_TYPE 无效的事件类型
* OS_ERR_PEVENT_NULL 'pevent' 是一个空指针
* OS_ERR_PEND_ISR 从ISR中调用该函数,将导致挂起
*
* Returns : != (void *)0 指向接收到消息的指针
* == (void *)0 没有消息接收,,
* 'pevent' 是一个空指针,
* 没有传递给队列一个恰当的指针.
*********************************************************************************************************
*/
void *OSQPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)
{
#if OS_CRITICAL_METHOD == 3 /* 为CPU状态寄存器分配存储变量 */
OS_CPU_SR cpu_sr;
#endif
void *msg;
OS_Q *pq;
if (OSIntNesting > 0)
{ /* 如果调用来自 ISR ... ... */
*err = OS_ERR_PEND_ISR; /* ... 从ISR中不能挂起 */
return ((void *)0);
}
#if OS_ARG_CHK_EN > 0
if (pevent == (OS_EVENT *)0)
{ /* 无效的 'pevent' */
*err = OS_ERR_PEVENT_NULL;
return ((void *)0);
}
if (pevent->OSEventType != OS_EVENT_TYPE_Q)
{ /* 无效的事件块类型 */
*err = OS_ERR_EVENT_TYPE;
return ((void *)0);
}
#endif
OS_ENTER_CRITICAL();
pq = (OS_Q *)pevent->OSEventPtr; /* 指向QCB */
if (pq->OSQEntries > 0) /* 看队列中是否有消息? */
{
msg = *pq->OSQOut++; /* 是,提取最先进入的消息 */
pq->OSQEntries--; /* 更新队列中的消息数 */
if (pq->OSQOut == pq->OSQEnd)
{ /* 进行边界检查 */
pq->OSQOut = pq->OSQStart;
}
OS_EXIT_CRITICAL();
*err = OS_NO_ERR;
return (msg); /* 返回接收到的消息 */
}
OSTCBCur->OSTCBStat |= OS_STAT_Q; /* 消息无效,任务将等待 */
OSTCBCur->OSTCBDly = timeout; /* 在TCB中加载延时数 */
OS_EventTaskWait(pevent); /* 挂起任务直到事件发生或延时到 */
OS_EXIT_CRITICAL();
OS_Sched(); /* 寻找最高优先级任务就绪运行 */
OS_ENTER_CRITICAL();
msg = OSTCBCur->OSTCBMsg;
if (msg != (void *)0)
{ /* 看是否有消息? */
OSTCBCur->OSTCBMsg = (void *)0; /* 有,清除已接收的消息 */
OSTCBCur->OSTCBStat = OS_STAT_RDY;
OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* 不在等待事件 拆除TCB与ECB的链接 */
OS_EXIT_CRITICAL();
*err = OS_NO_ERR;
return (msg); /* 返回接收的消息 */
}
OS_EventTO(pevent); /* 延时到,就绪任务 */
OS_EXIT_CRITICAL();
*err = OS_TIMEOUT; /* 显示延时发生 */
return ((void *)0); /* 返回空消息 */
}
/*$PAGE*/
/*
*********************************************************************************************************
* 发送消息到队列
*
* 函数描述: 该函数发送一个消息到队列
*
* 输入参数 : pevent 指向带有期望队列的ECB的指针
*
* msg 指向发送消息的指针. 不要发送空指针
*
* 返回值 : OS_NO_ERR 调用成功,消息被发送
* OS_Q_FULL 队列由于满不接收更多的消息
* OS_ERR_EVENT_TYPE 没有传递一个指向队列的指针
* OS_ERR_PEVENT_NULL 'pevent' 是一个空指针
* OS_ERR_POST_NULL_PTR 发送一个空指针
*********************************************************************************************************
*/
#if OS_Q_POST_EN > 0
INT8U OSQPost (OS_EVENT *pevent, void *msg)
{
#if OS_CRITICAL_METHOD == 3 /* 为CPU状态寄存器分配存储变量 */
OS_CPU_SR cpu_sr;
#endif
OS_Q *pq;
#if OS_ARG_CHK_EN > 0
if (pevent == (OS_EVENT *)0)
{ /* 无效的 'pevent' */
return (OS_ERR_PEVENT_NULL);
}
if (msg == (void *)0)
{ /* 没有发送一个空指针 */
return (OS_ERR_POST_NULL_PTR);
}
if (pevent->OSEventType != OS_EVENT_TYPE_Q)
{ /* 无效的事件块类型 */
return (OS_ERR_EVENT_TYPE);
}
#endif
OS_ENTER_CRITICAL();
if (pevent->OSEventGrp != 0x00)
{ /* 看是否任务正在等待消息队列 */
OS_EventTaskRdy(pevent, msg, OS_STAT_Q); /* 就绪等待事件的最高优先级的任务,在TCB中放消息 */
OS_EXIT_CRITICAL();
OS_Sched(); /* 寻找HPT就绪运行 */
return (OS_NO_ERR);
}
pq = (OS_Q *)pevent->OSEventPtr; /* 指向QCB */
if (pq->OSQEntries >= pq->OSQSize)
{ /* 检查消息是否已满? */
OS_EXIT_CRITICAL();
return (OS_Q_FULL);
}
*pq->OSQIn++ = msg; /* 把消息插入队列 */
pq->OSQEntries++; /* 增加队列中的消息数 */
if (pq->OSQIn == pq->OSQEnd)
{ /* 边界检查 */
pq->OSQIn = pq->OSQStart;
}
OS_EXIT_CRITICAL();
return (OS_NO_ERR);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* 发送消息到队列前端
*
* 函数描述: 该函数发送消息到队列,但是不象OSQPost(), 消息被放在队列前端而不是末尾。实现后进先出。
*
* 输入参数 : pevent 指向带有期望队列的ECB的指针
*
* msg 指向发送消息的指针. 不要发送空指针
*
* 返回值 : OS_NO_ERR 调用成功,消息被发送
* OS_Q_FULL 队列由于满不接收更多的消息
* OS_ERR_EVENT_TYPE 没有传递一个指向队列的指针
* OS_ERR_PEVENT_NULL 'pevent' 是一个空指针
* OS_ERR_POST_NULL_PTR 发送一个空指针
*********************************************************************************************************
*/
#if OS_Q_POST_FRONT_EN > 0
INT8U OSQPostFront (OS_EVENT *pevent, void *msg)
{
#if OS_CRITICAL_METHOD == 3 /* 为CPU状态寄存器分配存储变量 */
OS_CPU_SR cpu_sr;
#endif
OS_Q *pq;
#if OS_ARG_CHK_EN > 0
if (pevent == (OS_EVENT *)0)
{ /* 无效的 'pevent' */
return (OS_ERR_PEVENT_NULL);
}
if (msg == (void *)0)
{ /* 没有发送一个空指针 */
return (OS_ERR_POST_NULL_PTR);
}
if (pevent->OSEventType != OS_EVENT_TYPE_Q)
{ /* 无效的事件块类型 */
return (OS_ERR_EVENT_TYPE);
}
#endif
OS_ENTER_CRITICAL();
if (pevent->OSEventGrp != 0x00)
{ /* 看是否任务正在等待消息队列 */
OS_EventTaskRdy(pevent, msg, OS_STAT_Q); /* 就绪等待事件的最高优先级的任务,在TCB中放消息 */
OS_EXIT_CRITICAL();
OS_Sched(); /* 寻找HPT就绪运行 */
return (OS_NO_ERR);
}
pq = (OS_Q *)pevent->OSEventPtr; /* 指向QCB */
if (pq->OSQEntries >= pq->OSQSize)
{ /* 检查消息是否已满? */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -