Cjy_JDxy 发表于 2020-3-10 19:41

任哲书第五章第6个例子的问题

我正在看任哲的《嵌入式实时操作系统uC/OS-II原理及应用(第3版)》。
看到第五章例5-6:下面是一个使用信号量实现独占式访问共享资源而出现了任务级
反转的应用程序示例。
代码如下:

#include "includes.h"

#defineTASK_STK_SIZE   512                        //任务堆栈长度





OS_STK   StartTaskStk;//定义任务堆栈区
OS_STK   MyTaskStk;                //定义任务堆栈区
OS_STK   YouTaskStk;                //定义任务堆栈区
OS_STK   HerTaskStk;                //定义任务堆栈区
INT16S   key;                                        //用于退出uCOS_II的键

char *s1="MyTask running";
char *s2="YouTask running";
char *s3="HerTask running";
char *ss="MyTask pend_Semp";

INT8U   err;                                                                         //用于退出的键
INT8U       y=0;                                //字符显示位置
INT32U Times=0;
OS_EVENT *Semp;                                                //定义事件控制块



void StartTask(void *data);                //声明起始任务
voidMyTask(void *data);                        //声明任务
void YouTask(void *data);                        //声明任务
void HerTask(void *data);                        //声明任务
/************************主函数*********************************************/
voidmain (void)
{


       OSInit();                                        //初始化uCOS_II

       PC_DOSSaveReturn();                                //保存Dos环境
       PC_VectSet(uCOS, OSCtxSw);                        //安装uCOS_II中断
       Semp=OSSemCreate(1);                                //定义信号量
       OSTaskCreate(StartTask,                        //创建任务StartTask
                (void *)0,                                //给任务传递参数
                &StartTaskStk,//设置任务堆栈栈顶指针
                0);                                //使任务StartTask的优先级别为0

       OSStart();                                        //启动uCOS_II的多任务管理
}
/***********************任务StartTask*******************************************/

voidStartTask (void *pdata)
{


#if OS_CRITICAL_METHOD == 3
       OS_CPU_SRcpu_sr;
#endif

       pdata = pdata;

       OS_ENTER_CRITICAL();
       PC_VectSet(0x08, OSTickISR);                //安装uCOS_II时钟中断向量
       PC_SetTickRate(OS_TICKS_PER_SEC);                //设置uCOS_II时钟频率
       OS_EXIT_CRITICAL();
          //Semp=OSSemCreate(1);                                //定义信号量
       OSStatInit();                                //初始化uCOS_II的统计任务
       OSTaskCreate(MyTask,                                //创建任务MyTask
                (void *)0,                                                        //给任务传递参数
                &MyTaskStk,        //设置任务堆栈栈顶指针
                3);                                                                        //使任务的优先级为1
        OSTaskCreate(YouTask,                                //创建任务YouTask
                (void *)0,                                                        //给任务传递参数
                &YouTaskStk,        //设置任务堆栈栈顶指针
                4);                                                                        //使任务的优先级为2
                OSTaskCreate(HerTask,                                //创建任务YouTask
                (void *)0,                                                        //给任务传递参数
                &HerTaskStk,        //设置任务堆栈栈顶指针
                5);                                                                        //使任务的优先级为2
       for (;;)
       {


        //如果按下Esc键则退出uCOS_II
                if (PC_GetKey(&key) == TRUE)
                {
                                if (key == 0x1B)
                                {
                                       PC_DOSReturn();
                                }
                }

                  OSTimeDlyHMSM(0,0,3,0);                //延时3秒
        }
}
/***********************任务MyTask*******************************************/

voidMyTask (void *pdata)
{


#if OS_CRITICAL_METHOD == 3
       OS_CPU_SRcpu_sr;
#endif

       pdata = pdata;




       for (;;)
       {
               OSTimeDlyHMSM(0,0,0,200);                        //等待200ms
               {
                                PC_DispStr(10,++y,
                                        ss,
                                        DISP_BGND_BLACK+DISP_FGND_WHITE);
                                OSSemPend(Semp,0,&err);                //请求信号量
                                PC_DispStr(10,++y,
                                                s1,
                                                DISP_BGND_BLACK+DISP_FGND_WHITE);
                                OSSemPost(Semp);                        //发送信号量
               }

                  OSTimeDlyHMSM(0,0,0,200);                //延时1s
        }
}
/***********************任务YouTask*******************************************/

voidYouTask (void *pdata)
{


#if OS_CRITICAL_METHOD == 3
       OS_CPU_SRcpu_sr;
#endif

       pdata = pdata;



       for (;;)
       {

                        PC_DispStr(10,++y,
                                        s2,
                                        DISP_BGND_BLACK+DISP_FGND_WHITE);


                  OSTimeDlyHMSM(0,0,0,300);                //延时300毫秒
       }
}
/***********************任务HerTask*******************************************/

voidHerTask (void *pdata)
{


#if OS_CRITICAL_METHOD == 3
       OS_CPU_SRcpu_sr;
#endif

       pdata = pdata;



       for (;;)
       {
                       OSSemPend(Semp,0,&err);                                                //请求信号量
                        PC_DispStr(10,++y,
                                        s3,
                                        DISP_BGND_BLACK+DISP_FGND_WHITE);
                        for(Times;Times<20000000;Times++)                                //延时
                        {
                                OS_Sched();
                        }
                       OSSemPost(Semp);                                                //发送信号量
                  OSTimeDlyHMSM(0,0,1,0);                //延时1秒
       }
}

/************************End*************************************************/

按照书上所说,现象为:

可实际我运行,什么也打印不出来。
检查好久,没有头绪。
请高手指教,谢谢!

Cjy_JDxy 发表于 2020-3-10 20:25

我试着调试了一下:
把代码改为:
OSTaskCreate(MyTask,                              //创建任务MyTask
                (void *)0,                                                      //给任务传递参数
                &MyTaskStk,      //设置任务堆栈栈顶指针
                1);                                                                        //使任务的优先级为1
      OSTaskCreate(YouTask,                              //创建任务YouTask
                (void *)0,                                                      //给任务传递参数
                &YouTaskStk,      //设置任务堆栈栈顶指针
                2);                                                                        //使任务的优先级为2
                OSTaskCreate(HerTask,                              //创建任务YouTask
                (void *)0,                                                      //给任务传递参数
                &HerTaskStk,      //设置任务堆栈栈顶指针
                3);                                                                        //使任务的优先级为2
优先级分别为1,2,3,则执行效果为:

HerTask得不到执行。
OSTaskCreate(MyTask,                              //创建任务MyTask
                (void *)0,                                                      //给任务传递参数
                &MyTaskStk,      //设置任务堆栈栈顶指针
                2);                                                                        //使任务的优先级为1
      OSTaskCreate(YouTask,                              //创建任务YouTask
                (void *)0,                                                      //给任务传递参数
                &YouTaskStk,      //设置任务堆栈栈顶指针
                3);                                                                        //使任务的优先级为2
                OSTaskCreate(HerTask,                              //创建任务YouTask
                (void *)0,                                                      //给任务传递参数
                &HerTaskStk,      //设置任务堆栈栈顶指针
                4);                                                                        //使任务的优先级为2
如果优先级分别改为2,3,4,则执行效果为:

只有MyTask任务执行。
页: [1]
查看完整版本: 任哲书第五章第6个例子的问题