OpenEdv-开源电子网

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

关于嵌入式实时操作系统(任哲)第三章课后第17题程序运行结果的疑问

[复制链接]

0

主题

4

帖子

0

精华

新手入门

积分
12
金钱
12
注册时间
2023-4-3
在线时间
7 小时
发表于 2023-4-4 09:55:59 | 显示全部楼层 |阅读模式
1金钱
本帖最后由 xiaoyuba 于 2023-4-4 10:06 编辑

17.编写一个有2个任务的应用程序,每一个任务每次运行显示一个字符。当调度器进行5次调度之后,这些显示的字符会在显示器上构成一个字符串“Hello,μC/OS-II!”
原文链接:https://blog.csdn.net/qq_40400656/article/details/105042722

#include "includes.h"
#define TASK_STK_SIZE 512                                       //任务堆栈长度
OS_STK MyTaskStk[TASK_STK_SIZE];                         //定义任务堆栈区
OS_STK YouTaskStk[TASK_STK_SIZE];                       
INT8U x = 0, y = 0;                                                  //字符显示位置
INT16S key;                                                            //用于退出uCOS_II的键
extern INT8U myTaskTime = 0;
extern INT8U YouTaskTime = 0;
void MyTask(void *pdata);                              //声明任务
void YouTask(void *pdata);                              //声明任务

void main()
{
    OSInit();                                          //初始化uCOS_II
    OS_ENTER_CRITICAL();
    PC_DOSSaveReturn();                      //保存Dos环境
    PC_VectSet(uCOS, OSCtxSw);                //安装uCOS_II中断
    OS_EXIT_CRITICAL();
    OSTaskCreate(
        MyTask,                                                 //创建任务MyTask
        (void *)0,                                                 //给任务传递参数
        &MyTaskStk[TASK_STK_SIZE - 1],             //设置任务堆栈栈顶指针
        0                                                               //任务的优先级别为0
    );
    OSStart();                                                    //启动多任务管理
}

void MyTask(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);                        //设置时钟频率
    OS_ENTER_CRITICAL();
    OSStatInit();                                     //初始化统计任务
    OSTaskCreate(
        YouTask,
        (void *)0,
        &YouTaskStk[TASK_STK_SIZE - 1],
        1
    );
    for(;;)
    {
        if(myTaskTime == 0)
        {
            OSSchedLock();                     //调度器加锁
                 //字符的显示位置
            PC_DispChar(
                20,
                10,
                'H',
                DISP_BGND_BLACK + DISP_FGND_WHITE
            );                                                                                       
            OSTimeDlyHMSM(0, 0, 1, 0);                               //等待1秒
        }
        else if(myTaskTime == 1)
        {
            PC_DispChar(
                21,
                10,
                'e',
                DISP_FGND_WHITE + DISP_BGND_BLACK
            );
            OSTimeDlyHMSM(0, 0, 1, 0);
        }
        else if(myTaskTime == 2)
        {
            PC_DispChar(
                22,
                10,
                'l',
                DISP_BGND_BLACK + DISP_FGND_WHITE
            );
            OSTimeDlyHMSM(0, 0, 1, 0);
        }
        else if(myTaskTime == 3)
        {
            PC_DispChar(
                23,
                10,
                'l',
                DISP_BGND_BLACK + DISP_FGND_WHITE
            );
            OSTimeDlyHMSM(0, 0, 1, 0);
        }
        else if(myTaskTime == 4)
        {
            PC_DispChar(
                24,
                10,
                'o',
                DISP_BGND_BLACK + DISP_FGND_WHITE
            );
            OSTimeDlyHMSM(0, 0, 1, 0);
        }
        else if(myTaskTime == 5)
        {
            PC_DispChar(
                25,
                10,
                ',',
                DISP_BGND_BLACK + DISP_FGND_WHITE
            );
            OSTimeDlyHMSM(0, 0, 1, 0);
        }
        else if(myTaskTime == 6)
        {
            PC_DispChar(
                26,
                10,
                'u',
                DISP_BGND_BLACK + DISP_FGND_WHITE
            );
            OSTimeDlyHMSM(0, 0, 1, 0);
        }
        else if(myTaskTime == 7)
        {
            PC_DispChar(
                27,
                10,
                'C',
                DISP_BGND_BLACK + DISP_FGND_WHITE
            );
            OSTimeDlyHMSM(0, 0, 1, 0);
        }
        else if(myTaskTime == 8)
        {
            PC_DispChar(
                28,
                10,
                '/',
                DISP_BGND_BLACK + DISP_FGND_WHITE
            );
            OSTimeDlyHMSM(0, 0, 1, 0);
        }
        else if(myTaskTime == 9)
        {
            PC_DispChar(
                29,
                10,
                'O',
                DISP_BGND_BLACK + DISP_FGND_WHITE
            );
            OSTimeDlyHMSM(0, 0, 1, 0);
        }

        else if(myTaskTime == 10)
        {
            PC_DispChar(
                31,
                10,
                '-',
                DISP_BGND_BLACK + DISP_FGND_WHITE
            );
            OSSchedUnlock();
        }
        else if(myTaskTime == 11)
        {
            PC_DispChar(
                33,
                10,
                'I',
                DISP_BGND_BLACK + DISP_FGND_WHITE
            );
        }
        if(PC_GetKey(&key) == TRUE)
        {
            if(key == 0x1B)
            {
                PC_DOSReturn();                        //恢复Dos环境
            }
        }
        myTaskTime++;
        OSTimeDlyHMSM(0, 0, 2, 0);
    }
}

void YouTask(void *pdata)
{
#if OS_CRITICAL_METHOD == 3
    OS_CPU_SR cpu_sr
#endif
    pdata = pdata;
    for(;;)
    {
        if(YouTaskTime == 0)
        {
            PC_DispChar(
                30,
                10,
                'S',
                DISP_BGND_BLACK + DISP_FGND_WHITE
            );
        }
        else if(YouTaskTime == 1)
        {
            PC_DispChar(
                32,
                10,
                'I',
                DISP_FGND_WHITE + DISP_BGND_BLACK
            );
        }
        else if(YouTaskTime == 2)
        {
            PC_DispChar(
                34,
                10,
                '!',
                DISP_BGND_BLACK + DISP_FGND_WHITE
            );
        }
        YouTaskTime++;
        OSTimeDlyHMSM(0, 0, 2, 0);
    }
}

程序运行结果打印顺序如下:



1.png



2.png





3.png




百思不得其解,我觉得应该是先打印后面33位的I,再打印前面32位的I啊,但是执行结果并不是,刚好相反。youtask打印32位置应该要在mytask打印33位置之后啊,因为youtask打印30位置后也有2秒的延迟,这是为啥?
  我的理解是:打印29位置后,再打印31位置,31位置那里解锁了,开始调度执行youTASK打印30位置,youTASK延时2秒。那接下来就是mytask2秒延时时间到,再打印33位置啊,然后mytask再延时2秒,操作系统接下来去调度打印32位置啊。为啥32位置抢先打印在33位置前面了?求高手解答。。。









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

使用道具 举报

0

主题

4

帖子

0

精华

新手入门

积分
12
金钱
12
注册时间
2023-4-3
在线时间
7 小时
 楼主| 发表于 2023-4-17 14:26:56 | 显示全部楼层
没有江湖高手来帮忙看看?
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-6-10 17:05

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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