100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > 嵌入式实时操作系统(任哲)第三章习题解答

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

时间:2019-10-10 09:17:47

相关推荐

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

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.UC/OS−IIUC/OS-IIUC/OS−II中任务有哪五种状态?

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

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

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

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

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

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

8.数组 OSTCBTblOSTCBTblOSTCBTbl有什么用途?

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

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

OSTCBCur

10.变量OSRdyGrpOSRdyGrpOSRdyGrp有什么用?

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

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

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

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-IIPC_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 == 3OS_CPU_SR cpu_sr;#endifpdata = 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 == 3OS_CPU_SR cpu_sr;#endifpdata = 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 == 3OS_CPU_SR cpu_sr;# endifpdata = 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 == 3OS_CPU_SR#endifpdata = 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 == 3OS_CPU_SR cpu_sr#endifpdata = 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 == 3OS_CPU_SR cpu_sr#endifpdata = 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 512OS_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 == 3OS_CPU_SR cpu_sr#endifpdata = 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 == 3OS_CPU_SR cpu_sr#endifpdata = 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 == 3OS_CPU_SR cpu_sr#endifpdata = 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 512OS_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 == 3OS_CPU_SR cpu_sr#endifpdata = 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 == 3OS_CPU_SR cpu_sr#endifpdata = 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 == 3OS_CPU_SR cpu_sr#endifpdata = 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次调度之后,这些显示的字符会在显示器上构成一个字符串“ Hello,μC/OS−IIHello,{\mu}C/OS-IIHello,μC/OS−II!”。

#include "includes.h"#define TASK_STK_SIZE 512OS_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 == 3OS_CPU_SR cpu_sr#endifpdata = 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 == 3OS_CPU_SR cpu_sr#endifpdata = 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 512OS_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 == 3OS_CPU_SR cpu_sr#endifpdata = 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 == 3OS_CPU_SR cpu_sr#endifpdata = 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);}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。