嵌入式实时操作系统(任哲)第三章习题解答

1.什么是可剥夺形内核?

概念:最高优先级的任务一旦就绪,总能获得处理器的使用权。一般当系统响应很重要时使用。

过程:(1)当任务A运行时发生中断,进入中断服务程序,使更高优先级任务B就绪。

​ (2)中断服务执行完毕,返回,任务B优先级较高,获得运行。

​ (3)直到任务B结束,任务A才获得运行。

2.一个应用程序为什么一定要使用空闲任务?

在多任务系统运行时,系统经常会在某个时间内无用户任务而处于空闲状态,为了使CPU在此时有事可做,提供空闲任务。空闲任务是无法被删除的。

3.统计任务是必须的吗?

用户应用程序可以根据实际需要来选择是否使用统计任务。每秒计算一次CPU在单位时间内被使用的时间,并把计算结果以百分比的形式存放在变量OSCPUsage中,以便应用程序通过访问它来了解CPU的利用率。

4.什么叫做任务的优先级?用什么来描述任务的优先级?

当有多个任务需要运行时,操作系统必须在这些待运行任务中选择一个来运行,因为操作系统只有一个CPU。既然是选择,就需要一个规则。根据嵌入式系统的特点,uc/os-II采用了按优先级抢占式规则。即系统中的每个任务都按照其任务的重要性分配有一个唯一的优先级别,优先级高的任务先运行,优先级低的任务后运行。

每个优先级都用一个整数数字来表示,即 0、1、2...63。数字越小,优先级越高。

5. U C / O S − I I UC/OS-II UC/OSII中任务有哪五种状态?

等待状态、就绪状态、运行状态、睡眠状态和中断服务状态。

6.任务控制块记录了任务的哪些信息?

任务的堆栈指针、任务的当前状态、任务的优先级别等等。

7.什么是空任务控制块链表?什么是任务控制块链表?

空任务控制块链表:所有任务控制块还没有分配给任务。

任务控制块链表:所有任务控制块已经分配给任务。

8.数组 O S T C B T b l OSTCBTbl OSTCBTbl有什么用途?

所有的任务控制块 T C B TCB TCB 都是存放在任务控制块列表数组 OSTCBTbl[]中,系统通过任务控制块优先级表 OSTCBPrioTbl[],查询到任务控制块的地址。

9.正在运行任务的任务控制块指针存放在哪个指针变量中?

OSTCBCur

10.变量 O S R d y G r p OSRdyGrp OSRdyGrp有什么用?

为了便于对就绪表的查找, μ c / o s − I I {\mu}c/os-II μc/osII又定义了一个数据类型为 INT8U的变量 OSRdyGrp,并使该变量的每一位都对应 OSRdyTbl[]的一个任务组,如果某任务组中有任务就绪,则在变量 OSRdyGrp里把该任务组所对应的位置为1,否则置为0。

11.讲述在任务就绪表中查找具有最高优先级别的就绪任务的过程。

可以把优先级别看成是一个6位的2进制数,这样就可以用高3位 ( D 5 D 4 D 3 ) (D_5D_4D_3) (D5D4D3)来指明变量 OSRdyGrp的具体数据位,并用来确定就绪表数组元素的下标;用低3位 ( D 2 D 1 D 0 ) (D_2D_1D_0) (D2D1D0)来指明该数组元素具体数据位。

12.试对例3-8与例3-9两个应用程序的结果进行比较和分析。

MyTask挂起时该任务不会被执行,而在加锁时会一直执行该任务。

13.编写一个有3个任务的应用程序,每个任务均会在显示器上显示一个字符,并让3个任务具有不同的等待时间,观察应用程序运行中任务被调度的情况。

#include "includes.h"
#define TASK_STK_SIZE 512  //任务堆栈长度
OS_STK MyTaskStk[TASK_STK_SIZE]; //定义任务堆栈区
OS_STK YouTaskStk[TASK_STK_SIZE];
OS_STK HeTaskStk[TASK_STK_SIZE];
INT16S key;              //用于退出uc/os-II的键
INT8U x = 0, y = 0;      //字符显示位置
void MyTask(void *data); //声明一个任务
void YouTask(void *data);
void HeTask(void *data);
void main(void)
{
    char *s_M = "M";   //定义要显示的字符
    OSInit();          //初始化uc/OS-II
    PC_DOSSaveReturn(); //保存Dos环境
    PC_VectSet(uCOS, OSCtxSw); //安装uc/OS-II任务切换中断向量
    OSTaskCreate(
        MyTask,
        s_M,
        &MyTaskStk[TASK_STK_SIZE - 1],
        0
    );
    OSStart();
}

void MyTask(void *pdata)
{
    char *s_Y = "Y";
#if OS_CRITICAL_METHOD == 3
    OS_CPU_SR cpu_sr;
#endif
    pdata = pdata;
    OS_ENTER_CRITICAL();
    PC_VectSet(0x08, OSTickISR); //安装uc/OS-II时钟中断向量
    PC_SetTickRate(OS_TICKS_PER_SEC); // 设置uc/OS-II时钟频率
    OS_EXIT_CRITICAL();
    OSStatInit();
    OSTaskCreate(
        YouTask,
        s_Y,
        &YouTaskStk[TASK_STK_SIZE - 1],
        2  //优先级别较低
    );
    for(;;)
    {
        if(x > 50)
        {
            x = 0;
            y += 2;
        }  //坐标移动
        PC_DispChar(
            x, y,
            *(char *)pdata,
            DISP_BGND_BLACK + DISP_FGND_WHITE
        );
        x += 1;
        if(PC_GetKey(&key) == TRUE)
        {
            if(key == 0x1B)
            {
                PC_DOSReturn();
            }
        }
        OSTimeDlyHMSM(0, 0, 1, 0);
    }
}


void YouTask(void *pdata)
{
    char *s_T = "T";
#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_EXIT_CRITICAL();
    OSTaskCreate(
        HeTask,
        s_T,
        &HeTaskStk[TASK_STK_SIZE - 1],
        1
    );
    for(;;)
    {
        if(x > 50)
        {
            x = 0;
            y += 2;
        }
        PC_DispChar(
            x, y,
            *(char *)pdata,
            DISP_BGND_BLACK + DISP_FGND_WHITE
        );
        x += 1;
        OSTimeDlyHMSM(0, 0, 1, 0);
    }
}

void HeTask(void *pdata)
{
# if OS_CRITICAL_METHOD == 3
    OS_CPU_SR cpu_sr;
# endif
    pdata = pdata;
    for(;;)
    {
        if(x > 50)
        {
            x = 0;
            y += 2;
        }
        PC_DispChar(
            x, y,
            *(char *)pdata,
            DISP_BGND_BLACK + DISP_FGND_WHITE
        );
        x += 1;
        OSTimeDlyHMSM(0, 0, 1, 0);
    }
}

要设置不同的等待时间,只需要修改 OSTimeDlyHMSM() 中的参数即可。

14.编写一个有三个任务的应用程序,每个任务均会在显示器上显示一个字符,并让1个任务查询另外2个任务的信息,并在显示器上显示出来。

#include "includes.h"
#define TASK_STK_SIZE 512
// typedef unsigned int OS_STK; 属于栈类型
OS_STK MyTaskStk[TASK_STK_SIZE];
OS_STK YouTaskStk[TASK_STK_SIZE];
OS_STK HisTaskStk[TASK_STK_SIZE];
// typedef unsigned char INT8U; 8位无符号数
INT8U x = 0, y = 0;
INT16S key;
void MyTask(void *pdata);
void YouTask(void *pdata);
void HisTask(void *pdata);

void main()
{
    char *s_M = "M";
    /*s_M 实际为地址,保存的是字符串首地址*/
    /* ' ' 引起的一个字符代表一个整数
       " " 引起的字符串代表的是一个指向
           无名数组起始字符的指针       */
    OSInit();
    PC_DOSSaveReturn(); // 保存DOS环境
    PC_VectSet(uCOS, OSCtxSw); // 安装中断向量
    OSTaskCreate(
        MyTask,
        s_M,
        &MyTaskStk[TASK_STK_SIZE - 1],
        0
    );
    OSStart();
}

void MyTask(void *pdata)
{
    char *s_Y = "Y";
    OS_TCB YouTaskData;
    INT8U YouErr;
    OS_TCB HisTaskData;
    INT8U HisErr;
#if OS_CRITICAL_METHOD == 3
    OS_CPU_SR
#endif
    pdata = pdata;
    OS_ENTER_CRITICAL();
    PC_VectSet(0x08, OSTickISR);
    PC_SetTickRate(OS_TICKS_PER_SEC);
    OS_EXIT_CRITICAL();
    OSStatInit(); // 统计任务
    OSTaskCreate(
        YouTask,
        s_Y,
        &YouTaskStk[TASK_STK_SIZE - 1],
        2
    );
    for(;;)
    {
        YouErr = OSTaskQuery(2, &YouTaskData);
        HisErr = OSTaskQuery(3, &HisTaskData);
        // INT8U  OSTaskQuery (INT8U prio, OS_TCB *pdata)
        // Return value:
        // OS_PRIO_INVALID;OS_PRIO_ERR;OS_NO_ERR;
        /*******************************************************
         * A variable of type OS_TCB is filled in when calling *
         * OSTaskQuery() to get information about a task       *
         * *****************************************************/
        if(x > 50)
        {
            x = 0;
            y += 2;
        }
        PC_DispStr(
            x,
            y,
            (char *)pdata,
            DISP_BGND_BLACK + DISP_FGND_WHITE
        );
        // void PC_DispStr(INT8U x, INT8U y, INT8U *s, INT8U color)
        if(YouErr == OS_NO_ERR)
        {
            printf("Query for YouTask:Prio of YouTask:%d\t\n", YouTaskData.OSTCBPrio);
        }
        if(HisErr == OS_NO_ERR)
        {
            printf("Query for HisTask:Prio of HisTask:%d\t\n", HisTaskData.OSTCBPrio);
        }
        x += 2;
        if(PC_GetKey(&key) == TRUE)
        {
            if(key == 0x1B)
            {
                PC_DOSReturn();
            }
        }
        OSTimeDlyHMSM(0, 0, 2, 0);
    }
}

void YouTask(void *pdata)
{
    char *s_H = "H";
#if OS_CRITICAL_METHOD == 3
    OS_CPU_SR cpu_sr
#endif
    pdata = pdata;
    OSTaskCreate(
        HisTask,
        s_H,
        &HisTaskStk[TASK_STK_SIZE - 1],
        3
    );
    for(;;)
    {
        if(x > 50)
        {
            x = 0;
            y += 2;
        }
        PC_DispChar(
            x,
            y,
            *(char *)pdata,
            // The instruction *(char *)pdata
            // gives typecasting data located at
            // pdata to character data.
            // If we don't using typecasting,
            // we end up having unexpected behavior.
            DISP_FGND_WHITE + DISP_BGND_BLACK
        );
        // void PC_DispChar(INT8U x, INT8U y, INT8U c, INT8U color)
        x += 2;
        OSTimeDlyHMSM(0, 0, 2, 0);
    }
}

void HisTask(void *pdata)
{
#if OS_CRITICAL_METHOD == 3
    OS_CPU_SR cpu_sr
#endif
    pdata = pdata;
    for(;;)
    {
        if(x > 50)
        {
            x = 0;
            y += 2;
        }
        PC_DispChar(
            x,
            y,
            *(char *)pdata,
            DISP_BGND_BLACK + DISP_FGND_WHITE
        );
        x += 2;
        OSTimeDlyHMSM(0, 0, 2, 0);
    }
}

15.编写一个有3个任务的应用程序,并让其中2个任务在你认为合适的时候删除自己

#include "includes.h"
#define TASK_STK_SIZE 512
OS_STK MyTaskStk[TASK_STK_SIZE];
OS_STK YouTaskStk[TASK_STK_SIZE];
OS_STK HisTaskStk[TASK_STK_SIZE];
INT8U x = 0, y = 0;
INT16S key;
void MyTask(void *pdata);
void YouTask(void *pdata);
void HisTask(void *pdata);

void main(void)
{
    char *s_M = "M";
    OSInit();
    OS_ENTER_CRITICAL();
    PC_DOSSaveReturn();
    PC_VectSet(uCOS, OSCtxSw);
    OS_EXIT_CRITICAL();
    OSTaskCreate(
        MyTask,
        s_M,
        &MyTaskStk[TASK_STK_SIZE - 1],
        0
    );
    OSStart();
}

void MyTask(void *pdata)
{
    char *s_Y = "Y";
    char *s1 = "Ready to delete YouTask";
    char *s2 = "Ready to delete HisTask";
#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,
        s_Y,
        &YouTaskStk[TASK_STK_SIZE - 1],
        1
    );
    for(;;)
    {
        if(x > 15)
        {
            while(OSTaskDelReq(1) != OS_TASK_NOT_EXIST)
            {
                PC_DispStr(
                    20,
                    10,
                    s1,
                    DISP_BGND_BLACK + DISP_FGND_WHITE
                );
                OSTimeDly(1);
            }
        }
        if(y > 1)
        {
            while(OSTaskDelReq(2) != OS_TASK_NOT_EXIST)
            {
                PC_DispStr(
                    20,
                    14,
                    s2,
                    DISP_FGND_WHITE + DISP_BGND_BLACK
                );
                OSTimeDly(1);
            }
        }
        if(x > 50)
        {
            x = 0;
            y += 2;
        }
        PC_DispChar(
            x,
            y,
            *(char *)pdata,
            DISP_FGND_WHITE + DISP_BGND_BLACK
        );
        if(PC_GetKey(&key) == TRUE)
        {
            if(key == 0x1B)
            {
                PC_DOSReturn();
            }
        }
        x += 2;
        OSTimeDlyHMSM(0, 0, 2, 0);
    }
}

void YouTask(void *pdata)
{
    char *s_H = "H";
#if OS_CRITICAL_METHOD == 3
    OS_CPU_SR cpu_sr
#endif
    pdata = pdata;
    OSTaskCreate(
        HisTask,
        s_H,
        &HisTaskStk[TASK_STK_SIZE - 1],
        2
    );
    for(;;)
    {
        if(OSTaskDelReq(OS_PRIO_SELF) == OS_TASK_DEL_REQ)
        {
            OSTimeDlyHMSM(0, 0, 4, 0);
            PC_DispStr(
                20,
                12,
                "YouTask has been deleted",
                DISP_BGND_BLACK + DISP_FGND_WHITE
            );
            OSTaskDel(OS_PRIO_SELF);
        }
        if(x > 50)
        {
            x = 0;
            y += 2;
        }
        PC_DispChar(
            x,
            y,
            *(char *)pdata,
            DISP_FGND_WHITE + DISP_BGND_BLACK
        );
        x += 2;
        OSTimeDlyHMSM(0, 0, 2, 0);
    }
}

void HisTask(void *pdata)
{
#if OS_CRITICAL_METHOD == 3
    OS_CPU_SR cpu_sr
#endif
    pdata = pdata;
    for(;;)
    {
        if(OSTaskDelReq(OS_PRIO_SELF) == OS_TASK_DEL_REQ)
        {
            OSTimeDlyHMSM(0, 0, 4, 0);
            PC_DispStr(
                20,
                16,
                "HisTask has been deleted",
                DISP_BGND_BLACK + DISP_FGND_WHITE
            );
            OSTaskDel(OS_PRIO_SELF);
        }
        if(x > 50)
        {
            x = 0;
            y += 2;
        }
        PC_DispChar(
            x,
            y,
            *(char *)pdata,
            DISP_BGND_BLACK + DISP_FGND_WHITE
        );
        x += 2;
        OSTimeDlyHMSM(0, 0, 2, 0);
    }
}

16.编写一个有3个任务的应用程序,在调度器每进行一次任务切换后,在显示器上显示正在运行任务的任务控制块指针。

#include "includes.h"
#define TASK_STK_SIZE 512
OS_STK MyTaskStk[TASK_STK_SIZE];
OS_STK YouTaskStk[TASK_STK_SIZE];
OS_STK HisTaskStk[TASK_STK_SIZE];
INT8U x = 0, y = 0, z = 8;
INT16S key;
void MyTask(void *pdata);
void YouTask(void *pdata);
void HisTask(void *pdata);

void main(void)
{
    char *s_M = "M";
    OSInit();
    OS_ENTER_CRITICAL();
    PC_DOSSaveReturn();
    PC_VectSet(uCOS, OSCtxSw);
    OS_EXIT_CRITICAL();
    OSTaskCreate(
        MyTask,
        s_M,
        &MyTaskStk[TASK_STK_SIZE - 1],
        0
    );
    OSStart();
}

void MyTask(void *pdata)
{
    char *s_Y = "Y";
#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,
        s_Y,
        &YouTaskStk[TASK_STK_SIZE - 1],
        1
    );
    for(;;)
    {
        if(OSTCBCur->OSTCBPrio == 0)
        {
            PC_DispStr(
                25,
                z,
                "OSTCBCur->MyTask",
                DISP_BGND_BLACK + DISP_FGND_WHITE
            );
            printf("%d\t", OSTCBCur->OSTCBPrio);

        }
        if(x > 50)
        {
            x = 0;
            y += 2;
        }
        PC_DispChar(
            x,
            y,
            *(char *)pdata,
            DISP_FGND_WHITE + DISP_BGND_BLACK
        );
        if(PC_GetKey(&key) == TRUE)
        {
            if(key == 0x1B)
            {
                PC_DOSReturn();
            }
        }
        x += 2;
        z += 1;
        OSTimeDlyHMSM(0, 0, 2, 0);
    }
}

void YouTask(void *pdata)
{
    char *s_H = "H";
#if OS_CRITICAL_METHOD == 3
    OS_CPU_SR cpu_sr
#endif
    pdata = pdata;
    OSTaskCreate(
        HisTask,
        s_H,
        &HisTaskStk[TASK_STK_SIZE - 1],
        2
    );
    for(;;)
    {
        if(OSTCBCur->OSTCBPrio < 3)
        {
            PC_DispStr(
                25,
                z,
                "OSTCBCur->YouTask",
                DISP_BGND_BLACK + DISP_FGND_WHITE
            );
            printf("%d\t", OSTCBCur->OSTCBPrio);
        }
        if(x > 50)
        {
            x = 0;
            y += 2;
        }
        PC_DispChar(
            x,
            y,
            *(char *)pdata,
            DISP_FGND_WHITE + DISP_BGND_BLACK
        );
        x += 2;
        z += 1;
        OSTimeDlyHMSM(0, 0, 2, 0);
    }
}

void HisTask(void *pdata)
{
#if OS_CRITICAL_METHOD == 3
    OS_CPU_SR cpu_sr
#endif
    pdata = pdata;
    for(;;)
    {
        if(OSTCBCur->OSTCBPrio == 2)
        {
            PC_DispStr(
                25,
                z,
                "OSTCBCur->HisTask",
                DISP_BGND_BLACK + DISP_FGND_WHITE
            );
            printf("%d\t", OSTCBCur->OSTCBPrio);

        }
        if(x > 50)
        {
            x = 0;
            y += 2;
        }
        PC_DispChar(
            x,
            y,
            *(char *)pdata,
            DISP_BGND_BLACK + DISP_FGND_WHITE
        );
        x += 2;
        z += 1;
        OSTimeDlyHMSM(0, 0, 2, 0);
    }
}

17.编写一个有2个任务的应用程序,每一个任务每次运行显示一个字符。当调度器进行5次调度之后,这些显示的字符会在显示器上构成一个字符串“ H e l l o , μ C / O S − I I Hello,{\mu}C/OS-II Hello,μC/OSII!”。

#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;
extern INT8U myTaskTime = 0;
extern INT8U YouTaskTime = 0;
void MyTask(void *pdata);
void YouTask(void *pdata);

void main()
{
    OSInit();
    OS_ENTER_CRITICAL();
    PC_DOSSaveReturn();
    PC_VectSet(uCOS, OSCtxSw);
    OS_EXIT_CRITICAL();
    OSTaskCreate(
        MyTask,
        (void *)0,
        &MyTaskStk[TASK_STK_SIZE - 1],
        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);
        }
        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();
            }
        }
        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);
    }
}

精简版:

#include "includes.h"
#define TASK_STK_SIZE 512
OS_STK MyTaskStk[TASK_STK_SIZE];
OS_STK YouTaskStk[TASK_STK_SIZE];
INT8U x = 1, i;
INT16S key;
extern INT8U myTaskTime = 0;
extern INT8U YouTaskTime = 0;
void MyTask(void *pdata);
void YouTask(void *pdata);

void main()
{
    OSInit();
    OS_ENTER_CRITICAL();
    PC_DOSSaveReturn();
    PC_VectSet(uCOS, OSCtxSw);
    OS_EXIT_CRITICAL();
    OSTaskCreate(
        MyTask,
        (void *)0,
        &MyTaskStk[TASK_STK_SIZE - 1],
        0
    );
    OSStart();
}

void MyTask(void *pdata)
{
    char s[20] = "Hello,uC/O-I";
#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(;;)
    {
        for(i = 0; i < 10; i++)
        {
            if(myTaskTime == 0)
            {
                OSSchedLock();
            }
            if(myTaskTime == 10)
            {
                OSSchedUnlock();
            }
            PC_DispChar(20 + i, 10, s[i], DISP_BGND_BLACK + DISP_FGND_WHITE);
            myTaskTime++;
            OSTimeDlyHMSM(0, 0, 1, 0);
        }
        PC_DispChar(20 + i + 1, 10, s[i], DISP_FGND_WHITE + DISP_BGND_BLACK);
        PC_DispChar(20 + i + 3, 10, s[i + 1], DISP_FGND_WHITE + DISP_BGND_BLACK);
        if(PC_GetKey(&key) == TRUE)
        {
            if(key == 0x1B)
            {
                PC_DOSReturn();
            }
        }
        myTaskTime++;
        OSTimeDlyHMSM(0, 0, 2, 0);
    }
}

void YouTask(void *pdata)
{
    INT8U index = 0;
    char s[] = "SI!";
#if OS_CRITICAL_METHOD == 3
    OS_CPU_SR cpu_sr
#endif
    pdata = pdata;
    for(;;)
    {
        PC_DispChar(
            29 + x,
            10,
            s[index],
            DISP_BGND_BLACK + DISP_FGND_WHITE
        );
        x += 2;
        if(index < 3)
        {
            index++;
        }
        OSTimeDlyHMSM(0, 0, 2, 0);
    }
}
  • 25
    点赞
  • 89
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
嵌入实时操作系统uc/os-ii是一款常用于单片机和嵌入系统的操作系统。其原理基于事件驱动,采用优先级调度策略,具有快速响应和可靠性高的特点。 在uc/os-ii中,任务是程序的基本执行单位。每个任务都有自己的优先级和任务控制块(TCB)来存储任务的状态信息。任务的切换是通过调度器根据优先级来实现的,优先级高的任务会被优先执行。 uc/os-ii还提供了一系列的内核服务,包括任务管理、时间管理、事件管理、信号量管理等。任务管理主要负责任务的创建、删除和切换,时间管理用于定时操作和延时等待,事件管理用于任务间的同步与通信,信号量管理则用于提供资源和互斥访问。 应用方面,uc/os-ii在嵌入系统中广泛应用于实时任务的处理。例如,可以将传感器数据读取作为一个任务,数据处理和决策作为另一个任务,控制指令输出作为第三个任务。通过uc/os-ii来管理这些任务,可以保证数据的准确性和实时性。 此外,uc/os-ii还可以应用于物联网设备、智能家居、工业自动化等领域。例如,在物联网设备中,可以使用uc/os-ii来实现设备的状态监测、数据传输和远程控制等功能。 总之,uc/os-ii是一款功能强大的嵌入实时操作系统,能够提供可靠的任务管理和事件处理机制,广泛应用于各种嵌入系统中,提高系统的可靠性和实时性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值