搜索
bottom↓
回复: 0

请教 《嵌入式实时操作系统分uCOS-II原理及应用 >

[复制链接]

出0入0汤圆

发表于 2013-6-4 17:34:58 | 显示全部楼层 |阅读模式
本书的P146 例5-6
使用一个信号量实现独占式访问资源而出现了任务优先级反转的应用实例:


/************************Test*************************************/
#include "includes.h"
#define  TASK_STK_SIZE   512                                //任务堆栈长度
OS_STK   StartTaskStk[TASK_STK_SIZE];                        //定义任务堆栈区
OS_STK   MyTaskStk[TASK_STK_SIZE];                        //定义任务堆栈区
OS_STK   YouTaskStk[TASK_STK_SIZE];                        //定义任务堆栈区
OS_STK   HerTaskStk[TASK_STK_SIZE];                        //定义任务堆栈区
INT16S   key;                                                //用于退出的键
char*s1="MyTask正在运行";
char*s2="YouTask正在运行";
char*s3="HerTask正在运行";
char*ss="MyTask请求信号量";
INT8U err;                                                 
INT8U y=0;                                                //字符显示位置
INT32U Times=0;                                       
OS_EVENT *Semp;                                                //定义事件控制块
void  StartTask(void *data);                                //声明起始任务
void  MyTask(void *data);                                //声明任务
void  YouTask(void *data);                                //声明任务
void  HerTask(void *data);                                //声明任务
/************************主函数*********************************/
void  main (void)
{
    OSInit( );                                                //初始化uCOS_II
    PC_DOSSaveReturn( );                                //保存Dos环境
    PC_VectSet(uCOS, OSCtxSw);                                //安装uCOS_II中断
    Semp = OSSemCreate (1);                                //定义信号量
    OSTaskCreate(StartTask,                                //创建任务StartTask
        (void*)0,                                        //给任务传递参数
        &StartTaskStk[TASK_STK_SIZE - 1],                //设置任务堆栈栈顶
        0);                                                //使任务的优先级别为0
    OSStart( );                                                //启动多任务管理
}
/***********************任务StartTask*******************************/
void  StartTask (void *pdata)
{
#if OS_CRITICAL_METHOD == 3
    OS_CPU_SR  cpu_sr;
#endif
    pdata = pdata;
    OS_ENTER_CRITICAL( );
    PC_VectSet(0x08, OSTickISR);                //安装时钟中断向量
    PC_SetTickRate(OS_TICKS_PER_SEC);                //设置uCOS_II时钟频率
    OS_EXIT_CRITICAL( );

    OSStatInit( );                                //初始化统计任务
    OSTaskCreate(MyTask,                        //创建任务MyTask
                (void*)0,                        //给任务传递参数
                &MyTaskStk[TASK_STK_SIZE - 1],        //设置任务堆栈栈顶
                3);                                //使任务的优先级别为3
    OSTaskCreate(YouTask,                        //创建任务YouTask
                (void*)0,                        //给任务传递参数
                &YouTaskStk[TASK_STK_SIZE - 1],        //设置任务堆栈栈顶
                4);                                //使任务的优先级别为4
    OSTaskCreate(HerTask,                        //创建任务HerTask
                (void*)0,                        //给任务传递参数
                &HerTaskStk[TASK_STK_SIZE - 1],        //设置任务堆栈栈顶
                5);                                //使任务的优先级别为5
    for (;;)
    {
        //如果按下Esc键则退出uCOS_II
                if (PC_GetKey(&key) == TRUE)
                {
            if (key == 0x1B)
                    {
                PC_DOSReturn( );
            }
        }
        OSTimeDlyHMSM(0, 0, 3, 0);        //等待3秒
    }
}
/************************任务MyTask*******************************/
void  MyTask (void *pdata)
{
#if OS_CRITICAL_METHOD == 3
    OS_CPU_SR  cpu_sr;
#endif
    pdata = pdata;
  
    for (;;)
    {  
        OSTimeDlyHMSM(0, 0, 1, 200);                 //等待200毫秒                                          
        {
            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);                //等待200毫秒
    }
}
/************************任务YouTask******************************/
void  YouTask (void *pdata)
{
#if OS_CRITICAL_METHOD == 3
    OS_CPU_SR  cpu_sr;
#endif
    pdata = pdata;     
     
    for (;;)
    {                                          
        PC_DispStr(10,++y,
                s2,
                DISP_BGND_BLACK+DISP_FGND_WHITE );                                 
        OSTimeDlyHMSM(0, 0, 0, 300);                //等待300毫秒
    }
}
/************************任务HerTask******************************/
void  HerTask (void *pdata)
{
#if OS_CRITICAL_METHOD == 3
    OS_CPU_SR  cpu_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**************************************/

运行结果为:
            YouTask running
            HerTask  running
            YouTask running
            YouTask running
            YouTask running
            MyTask  pend_Semp
            YouTask running  
            YouTask running  
            YouTask running  
            YouTask running  
            YouTask running  
            YouTask running  
            MyTask  running
。。。。。。

我是这么理解的程序执行后,StartTask一直在 OSTimeDlyHMSM(0, 0, 3, 0);        ,MyTask先执行 OSTimeDlyHMSM(0, 0, 1, 200);  后YouTask执行,输出            

YouTask running 后 OSTimeDlyHMSM(0, 0, 0, 300);    HerTask执行,输出 HerTask  running 后进入Times的for循环,不停的调用 OS_Sched(); 切换任务,
因为MyTask延时200ms    YouTask延时的300ms 那么肯定是MyTask先到时间获得CPU使用权,继续执行,输出 MyTask  pend_Semp 然后才在OSSemPend(Semp,0,&err);
里面,YouTask才获得CPU试用权输出 YouTask running 直到HerTask执行 OSSemPost(Semp) ...
我感觉结果应该是:
            YouTask running
            HerTask  running
            MyTask  pend_Semp
            YouTask running
            YouTask running
            YouTask running
            YouTask running  
            YouTask running  
            YouTask running  
            YouTask running  
            YouTask running  
            YouTask running  
            MyTask  running

请教大家 我什么地方理解错了,谢谢指点了....

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-25 23:07

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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