1、flag.c中:
void OS_FlagTaskRdy (OS_TCB *p_tcb,
OS_FLAGS flags_rdy,
CPU_TS ts)
{
p_tcb->FlagsRdy = flags_rdy;
p_tcb->PendStatus= OS_STATUS_PEND_OK; p_tcb->PendOn = OS_TASK_PEND_ON_NOTHING;
p_tcb->TS = ts;
switch (p_tcb->TaskState) {
case OS_TASK_STATE_RDY:
case OS_TASK_STATE_DLY:
case OS_TASK_STATE_DLY_SUSPENDED:
case OS_TASK_STATE_SUSPENDED:
break;
case OS_TASK_STATE_PEND:
case OS_TASK_STATE_PEND_TIMEOUT:
OS_TaskRdy(p_tcb);
p_tcb->TaskState = OS_TASK_STATE_RDY;
break;
case OS_TASK_STATE_PEND_SUSPENDED:
case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED:
p_tcb->TaskState =OS_TASK_STATE_SUSPENDED; //这里应该有 //OS_TickListRemove(p_tcb); break;
default:
break;
}
OS_PendListRemove(p_tcb);
}
2、OSFlagPend()中,参数检查程序段:
#if OS_CFG_ARG_CHK_EN > 0u
if (p_grp == (OS_FLAG_GRP *)0) {
*p_err = OS_ERR_OBJ_PTR_NULL;
return ((OS_FLAGS)0);
}
switch (opt) {
case OS_OPT_PEND_FLAG_CLR_ALL:
case OS_OPT_PEND_FLAG_CLR_ANY:
case OS_OPT_PEND_FLAG_SET_ALL:
case OS_OPT_PEND_FLAG_SET_ANY:
case OS_OPT_PEND_FLAG_CLR_ALL | OS_OPT_PEND_FLAG_CONSUME:
case OS_OPT_PEND_FLAG_CLR_ANY | OS_OPT_PEND_FLAG_CONSUME:
case OS_OPT_PEND_FLAG_SET_ALL | OS_OPT_PEND_FLAG_CONSUME:
case OS_OPT_PEND_FLAG_SET_ANY | OS_OPT_PEND_FLAG_CONSUME:
case OS_OPT_PEND_FLAG_CLR_ALL | OS_OPT_PEND_NON_BLOCKING:
case OS_OPT_PEND_FLAG_CLR_ANY | OS_OPT_PEND_NON_BLOCKING:
case OS_OPT_PEND_FLAG_SET_ALL | OS_OPT_PEND_NON_BLOCKING:
case OS_OPT_PEND_FLAG_SET_ANY | OS_OPT_PEND_NON_BLOCKING:
case OS_OPT_PEND_FLAG_CLR_ALL | OS_OPT_PEND_FLAG_CONSUME |OS_OPT_PEND_NON_BLOCKING:
case OS_OPT_PEND_FLAG_CLR_ANY | OS_OPT_PEND_FLAG_CONSUME |OS_OPT_PEND_NON_BLOCKING:
case OS_OPT_PEND_FLAG_SET_ALL | OS_OPT_PEND_FLAG_CONSUME |OS_OPT_PEND_NON_BLOCKING:
case OS_OPT_PEND_FLAG_SET_ANY | OS_OPT_PEND_FLAG_CONSUME |OS_OPT_PEND_NON_BLOCKING:
break;
default:
*p_err = OS_ERR_OPT_INVALID;
return ((OS_OBJ_QTY)0);
}
#endif
当系统配置未使能宏:OS_CFG_FLAG_MODE_CLR_EN时,opt里出现与CLR相关的宏,这个参数检查应该报错才对。实际上,当出现未使能宏OS_CFG_FLAG_MODE_CLR_EN,却在opt中使能了CLR相关选项,在这段参数检查代码中没有报错,但是在OSFlagPend()后续的处理中也会报错,给err值赋值OS_ERR_OPT_INVALID。
3、所有内核对象的PendAbort()函数中,以下代码段:
while (p_pend_list->NbrEntries >(OS_OBJ_QTY)0u) {
p_tcb = p_pend_list->HeadPtr->TCBPtr;
OS_PendAbort((OS_PEND_OBJ *)((void *)p_grp),
p_tcb,
ts);
nbr_tasks++;
if (opt != OS_OPT_PEND_ABORT_ALL) {
break; // //应该算上OS_OPT_PEND_ABORT_ALL| OS_OPT_POST_NO_SCHED }
}
4、OS_TaskInitTCB( )在OSTaskCreate()时会被调用,用来初始化tcb中的各字段,里面有一段:
#if (OS_CFG_PEND_MULTI_EN > 0u)
p_tcb->PendDataTblPtr =(OS_PEND_DATA *)0;
p_tcb->PendDataTblEntries = (OS_OBJ_QTY )0u;
#endif
其实这里不需要条件编译,无论如何PendDataTblPtr和PendDataTblEntries都应该是存在于tcb中的,都应该在初始化时被清零。
5、OS_TickListInsert()中,若opt==OS_OPT_TIME_PERIODIC时,它需要用用到保存在TCB结构体中与tick操作相关的一个变量->TickCtrPerv,这个变量记录的是上一次调用延时函数OSTimeDly时算出来的->TickCtrMatch,但是如果是第一次进入OSTimeDly()使用OS_OPT_TIME_PERIODIC选项时,就会出问题,这时TCB里记录的TickCtrPrev等于0.
6、以下应该不是bug,我对此抱有疑问。所有的Pend函数中,比如OSSemPend()、
OSTaskQPend()函数,在从阻塞态恢复调度后:
OSSched();
CPU_CRITICAL_ENTER();
switch (OSTCBCurPtr->PendStatus) {
case OS_STATUS_PEND_OK:
p_void =OSTCBCurPtr->MsgPtr;
*p_msg_size =OSTCBCurPtr->MsgSize;
if (p_ts != (CPU_TS *)0) {
*p_ts = OSTCBCurPtr->TS;
}
*p_err = OS_ERR_NONE;
break;
case OS_STATUS_PEND_ABORT:
p_void = (void *)0;
*p_msg_size = (OS_MSG_SIZE)0;
if (p_ts != (CPU_TS *)0) {
*p_ts = (CPU_TS )0; //这里我觉得应该是:*p_ts = OSTCBCurPtr->TS;
}
*p_err = OS_ERR_PEND_ABORT;
break;
case OS_STATUS_PEND_TIMEOUT:
default:
p_void = (void *)0;
*p_msg_size = (OS_MSG_SIZE)0;
if (p_ts != (CPU_TS *)0) {
*p_ts = OSTCBCurPtr->TS;
}
*p_err = OS_ERR_TIMEOUT;
break;
}
OS_VERSION == 30300
|