OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3337|回复: 0

uCOS3学完源代码以后找到的bug,大家一起讨论下吧

[复制链接]

25

主题

57

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
246
金钱
246
注册时间
2016-5-15
在线时间
50 小时
发表于 2017-7-28 09:49:49 | 显示全部楼层 |阅读模式

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


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-23 16:42

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表