ucos-ii操作系统复习大纲
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
ucos-ii操作系统复习大纲
一.填空题
1.uC/OS-II是一个简洁、易用的基于优先级的嵌入式【抢占式】多任务实时内核。
2.任务是一个无返回的无穷循环。
uc/os-ii总是运行进入就绪状态的【最高优先级】的任务。
3.因为uc/os-ii总是运行进入就绪状态的最高优先级的任务。
所以,确定哪
个任务优先级最高,下面该哪个任务运行,这个工作就是由【调度器(scheduler)】来完成的。
(
4.【任务级】的调度是由函数OSSched()完成的,而【中断级】的调度
是由函数OSIntExt() 完成。
对于OSSched(),它内部调用的是【OS_TASK_SW()】完成实际的调度;OSIntExt()内部调用的是【 OSCtxSw() 】实现调度。
5.任务切换其实很简单,由如下2步完成:
(1)将被挂起任务的处理器寄存器推入自己的【任务堆栈】。
(2)然后将进入就绪状态的最高优先级的任务的寄存器值从堆栈中恢复到【寄存器】中。
6.任务的5种状态。
【
【睡眠态(task dormat) 】:任务驻留于程序空间(rom或ram)中,暂时没交给ucos-ii处理。
【就绪态(task ready)】:任务一旦建立,这个任务就进入了就绪态。
【运行态(task running)】:调用OSStart()可以启动多任务。
OSStart()函数只能调用一次,一旦调用,系统将运行进入就绪态并且优先级最高的任务。
【等待状态(task waiting)】:正在运行的任务,通过延迟函数或pend(挂起)相关函数后,将进入等待状态。
(
【中断状态(ISR running)】:正在运行的任务是可以被中断的,除非该任务将中断关闭或者ucos-ii将中断关闭。
7.【不可剥夺型】内核要求每个任务自我放弃CPU的所有权。
不可剥夺型调度法也称作合作型多任务,各个任务彼此合作共享一个CPU。
8.当系统响应时间很重要时,要使用【可剥夺型】内核。
最高优先级的任务一旦就绪,总能得到CPU的控制权。
9.使用可剥夺型内核时,应用程序不应直接使用不可重入型函数。
调用不可重入型函数时,要满足互斥条件,这一点可以用【互斥型信号量】来实现。
10.【可重入型】函数可以被一个以上的任务调用,而不必担心数据的破坏。
—
11.可重入型函数任何时候都可以被中断,一段时间以后又可以运行,而相应数据不会丢失。
可重入型函数或者只使用【局部变量】,即变量保存在CPU寄存器中或堆栈中。
如果使用全局变量,则要对全局变量予以【保护】。
12.每个任务都有其优先级。
任务越重要,赋予的优先级应【越高】。
13.μC/OS-Ⅱ初始化是通过调用系统函数【OSIint()】实现的,完成μC/OS-Ⅱ所有的变量和数据结构的初始化。
14.多任务的启动是用户通过调用【OSStart()】实现的。
然而,启动μC/OS-Ⅱ之前,用户至少要建立一个应用【任务】。
$
15. μC/OS-Ⅱ的参数配置文件名为【】。
16.删除任务,是说任务将返回并处于【休眠状态】,并不是说任务的代码被删除了,只是任务的代码不再被µC/OS-Ⅱ调用。
17.µC/OS-Ⅱ要求用户提供【定时中断】来实现延时与超时控制等功能。
18.定时中断也叫做【时钟节拍】,它应该每秒发生10至100次。
《
19. 时钟节拍的实际频率是由用户的应用程序决定的。
时钟节拍的频率越高,系统的负荷就【越重】。
20.µC/OS-II中的信号量由两部分组成:一个是信号量的【计数值】,它是一个
16位的无符号整数(0 到65,535之间);另一个是由等待该信号量的任务组成
的【等待任务表】。
用户要在中将OS_SEM_EN开关量常数置成【1 】,这样µC/OS-II
才能支持信号量。
21. µC/OS-II中表示当前已经创建的任务数全局变量名为:【 OSTaskCtr 】。
21. µC/OS-II中表示当前内核运行的标记全局变量名为:【 OSRunning 】。
…
22.在使用OSTaskCreate创建任务时,若需要TaskData作伪参数传递给任务
Task,并从任务Task中获得传入的字符参数值,请在下面【】填上合适的代
码。
char TaskData=’A’;
OSTaskCreate(Task, 【(void *)& TaskData 】,
&TaskStk[0][TASK_STK_SIZE - 1], 1);
void Task (void *pdata)
{
^
char value = 【 *(char *)pdata 】;
for (;;) {
OSSemPend(RandomSem, 0, &err);
y = (int) (*(char *)pdata - 'A');
OSSemPost(RandomSem); PC_DispChar(10, 25, value, DISP_FGND_WHITE + DISP_BGND_BLUE);
OSTimeDly(1);
}
@
}
23. 在µC/OS-II在任务Task1中使用邮箱函数OSMboxPost()发送字符;而
在Task2中接收OSMboxPost()字符, 请在下面【】填上合适的代码。
void Task1 (void *data)
{
char txmsg;
INT8U err;
·
…
txmsg = 'A';
for (;;) {
OSMboxPost(TxMbox, 【 (void *)&txmsg】); /* Send message to
Task2*/
OSMboxPend(AckMbox, 0, &err);
txmsg++; if (txmsg == 'Z') {
txmsg = 'A';
)
}
}
}
void Task5 (void *data)
{
char *rxmsg;
INT8U err;
~
data = data;
for (;;) {
rxmsg = 【(char *)】OSMboxPend(TxMbox, 0, &err);
PC_DispChar(70, 18, *rxmsg, DISP_FGND_YELLOW + DISP_BGND_BLUE);
OSMboxPost(AckMbox, (void *)1);
}
}
24. 在Task1中使用消息队列OSQPend()函数接收消息“Hello World!”,而
在Task2中使用消息队列OSQPost()函数发送消息“Hello World!”, 请在下
面【】填上合适的代码.
void Task1 (void *pdata)
{
char *msg;
INT8U err;
pdata = pdata;
for (;;) {
-
msg = 【(char *)】OSQPend(MsgQueue, 0, &err);
PC_DispStr(70, 13, msg, DISP_FGND_YELLOW + DISP_BGND_BLUE);
OSTimeDlyHMSM(0, 0, 0, 100);
}
}
void Task2 (void *pdata)
{
]
char msg[20];
pdata = pdata;
strcpy(&msg[0], " Hello World!");
for (;;) {
OSQPost(MsgQueue, 【(void *)】&msg[0]);
OSTimeDlyHMSM(0, 0, 0, 500);
}
}
)
二.名词解释
1.代码的临界段
代码的临界段也称为临界区,指处理时不可分割的代码。
2.资源
任何为任务所占用的实体都可称为资源。
资源可以是输入输出设备;资源也可以是一个变量,一个结构或一个数组等。
—
3.共享资源
可以被一个以上任务使用的资源叫做共享资源。
4.任务
一个任务,也称作一个线程,是一个简单的程序,该程序可以认为CPU完全只属该程序自己。
典型地、每个任务都是一个无限的循环。
5.任务切换
(
指Context Switch,其含义是CPU寄存器内容切换。
当多任务内核决定运行另外的任务时,它保存正在运行任务的当前状态(Context),即CPU寄存器中的全部内容。
6.内核
多任务系统中,内核负责管理各个任务,或者说为每个任务分配CPU时间,并且负责任务之间的通讯。
内核提供的基本服务是任务切换。
7.调度(Scheduler)
内核的主要职责之一,就是要决定该轮到哪个任务运行了。
多数实时内核是基于优先级调度法的。
—
8.可剥夺型内核
最高优先级的任务一旦就绪,总能得到CPU的控制权。
当一个运行着的任务使一个比它优先级高的任务进入了就绪态,当前任务的CPU使用权就被剥夺了,或者说被挂起了,那个高优先级的任务立刻得到了CPU的控制权。
如果是中断服务子程序使一个高优先级的任务进入就绪态,中断完成时,中断了的任务被挂起,优先级高的那个任务开始运行。
三.简答题
1.举例说明µCOS-II可移植型数据类型的定义方式
答:因为不同的微处理器有不同的字长,µC/OS-II的移植文件包括很多类型定义以确保可移植性。
µCOS-II不使用C语言中的short,int,long等数据类型的定义,因为它们与处理器类型有关,隐含着不可移植性。
µC/OS-II代之以移植性强的整数数据类型,这样,既直观又可移植(该数据类型不依赖于编译),举例如下:
…
typedef unsigned char BOOLEAN;
typedef unsigned char INT8U;
typedef signed char INT8S;
typedef unsigned int INT16U;
typedef signed int INT16S;
typedef unsigned long INT32U;
typedef signed long INT32S;
2.|
3.µCOS-II如何定义全局变量
答:众所周知,全局变量应该是得到内存分配且可以被其他模块通过C语言中extern关键字调用的变量。
因此,必须在 .C 和 .H 文件中定义。
这种重复的定义很容易导致错误。
µCOS-II采用的方法只需用在头文件中定义一次。
uC/ 头文件中包括以下定义全局宏定义:
#ifdef OS_GLOBALS
#define OS_EXT
#else
#define OS_EXT extern
#endif
(
OS_EXT INT32U OSIdleCtr;
同时,有中以下定义:
#define OS_GLOBALS
#include “”
当编译器处理时,它使得头文件变成如下所示,因为OS_EXT被设置为空。
INT32U OSIdleCtr;
这样编译器就会将这些全局变量分配在内存中。
当编译器处理其他.C文件时,头文件变成了如下的样子,因为OS_GLOBAL没有定义,所以OS_EXT被定义为extern。
)
extern INT32U OSIdleCtr;
在这种情况下,不产生内存分配,而任何 .C文件都可以使用这些变量。
这样的就只需在 .H 文件中定义一次就可以了。
4.OS_ENTER_CRITICAL() 和 OS_EXIT_CRITICAL()的含义及作用
答:OS_ENTER_CRITICAL() :关中断;
OS_EXIT_CRITICAL():开中断。
关中断和开中断是为了保护临界段代码。
用户的应用代码可以使用这两个宏来开中断和关中断。
很明显,关中断会影响中断延迟,所以要特别小心。
用户还可以用信号量来保护临界段代码。
《
4.基于PC的服务中如何测量PC_DisplayChar()的执行时间
答:
测量PC_DisplayChar()的执行时间的代码如下:
INT16U time; 描述利用μC/OS_Ⅱ 宏调用关中断和开中断处理共享数据的示意性代码程序。
答:
OS_ENTER_CRITICAL();
`
/*在这里处理共享数据*/
OS_EXIT_CRITICAL();
8. 信号量的典型应用包括哪些
答:
信号量(Semaphores) 是一种约定机制,在多任务内核中的典型应用包括:(1)控制共享资源的使用权(满足互斥条件);
(2)标志某事件的发生
(3)。
(4)使两个任务的行为同步
9.对信号量只能实施哪三种操作
答:
一般地说,对信号量只能实施三种操作:
(1)初始化(INITIALIZE),也可称作建立(CREATE);
(2)等信号(WAIT)也可称作挂起(PEND);
(3)给信号(SIGNAL)或发信号(POST)。
/
10.给出μC/OS-Ⅱ中如何用信号量处理共享数据的示意代码
答:
通过获得信号量处理共享数据的示意代码如下:
OS_EVENT *SharedDataSem;
void Function (void)
{
INT8U err;。
OSSemPend(SharedDataSem, 0, &err);
/*共享数据的处理在此进行,(中断是开着的)*/
OSSemPost(SharedDataSem);
}
11.给出初始化和启动μC/OS-Ⅱ的示意代码。
答:
void main (void)
<
{
OSInit(); /* 初始化uC/OS-II */
.
通过调用OSTaskCreate()或OSTaskCreateExt()创建至少一个任务;
.
OSStart(); /* 开始多任务调度!OSStart()永远不会返回 */
}
12.描述建立任务OSTaskCreate()的函数原型。
答:
建立任务OSTaskCreate()的函数原型为:
INT8U OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio)
其中,
task: 任务代码的指针;
pdata: 当任务开始执行时传递给任务的参数的指针;
ptos: 分配给任务的堆栈的栈顶指针;
<
prio: 分配给任务的优先级。
13.任务可以是一个无限的循环,也可以是在一次执行完毕后被删除掉。
请给出示意代码结构。
答:µC/OS-Ⅱ描述的任务示意代码必须是以下两种结构之一:
void YourTask (void *pdata)
{
for (;;) {
;
/* 用户代码 */
调用µC/OS-Ⅱ的服务例程之一:
OSMboxPend();
OSQPend();
OSSemPend();
OSTaskDel(OS_PRIO_SELF);
OSTaskSuspend(OS_PRIO_SELF);
OSTimeDly();
|
OSTimeDlyHMSM();
/* 用户代码 */
}
}
或
void YourTask (void *pdata)
{
/* 用户代码 */
:
OSTaskDel(OS_PRIO_SELF);
}
14.μC/OS-Ⅱ任务管理提供哪些服务
答:μC/OS-Ⅱ任务管理提供的服务包括:
(1)建立任务:OSTaskCreate()或OSTaskCreateExt();
(2)删除任务:OSTaskDel();
(3)请求删除任务:OSTaskDelReq();
*
(4)改变任务的优先级:OSTaskChangePrio();
(5)挂起任务:OSTaskSuspend();
(6)恢复任务:OSTaskResume();
(7)获得有关任务的信息:OSTaskQuery()。
15.μC/OS-Ⅱ时间任务管理提供哪些服务
答:μC/OS-Ⅱ时间任务管理提供的服务包括:
(1)任务延时函数:OSTimeDly()
(2)!
(3)按时分秒延时函数:OSTimeDlyHMSM()
(4)让处在延时期的任务结束延时:OSTimeDlyResume()
(5)设置系统时间:OSTimeGet()
(6)获得系统时间:OSTimeSet()
16. μC/OS-Ⅱ提供的数据共享和任务通讯的方法包括哪些
答:μC/OS-Ⅱ提供的数据共享和任务通讯的方法包括五种方法:
(1)利用宏OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()来关闭中断和打开
中断。
(2)!
(3)利用函数OSSchedLock()和OSSchekUnlock()对µC/OS-II中的任务调度
函数上锁和开锁。
(4)信号量。
(5)邮箱。
(6)消息队列。
17.对于事件控制块进行的一些通用包括哪些操作
答:对于事件控制块进行的一些通用操作包括:
(1)初始化一个事件控制块: OSEventWaitListInit();
"
(2)使一个任务进入就绪态:OSEventTaskRdy();
(3)使一个任务进入等待该事件的状态:OSEventTaskWait();
(4)因为等待超时而使一个任务进入就绪态:OSEventTO()。
18.μC/OS-Ⅱ信号量提供哪些服务
答:μC/OS-Ⅱ信号量提供的服务包括:
(1)建立一个信号量:OSSemCreate();
(2)等待一个信号量:OSSemPend();
^
(3)发送一个信号量:OSSemPost();
(4)无等待地请求一个信号量:OSSemAccept();
(5)查询一个信号量的当前状态:OSSemQuery()。
19.μC/OS-Ⅱ邮箱提供哪些服务
答:μC/OS-Ⅱ邮箱提供的服务包括:
(1)建立一个邮箱:OSMboxCreate();
(2)等待一个邮箱中的消息:OSMboxPend();
!
(3)发送一个消息到邮箱中:OSMboxPost();
(4)无等待地从邮箱中得到一个消息:OSMboxAccept();
(5)查询一个邮箱的状态:OSMboxQuery()
20.μC/OS-Ⅱ消息队列提供哪些服务
答:μC/OS-Ⅱ消息队列提供的服务包括:
(1)建立一个消息队列:OSQCreate();
(2)等待一个消息队列中的消息:OSQPend();
|
(3)向消息队列发送一个消息(FIFO):OSQPost();
(4)向消息队列发送一个消息(LIFO):OSQPostFront();
(5)无等待地从一个消息队列中取得消息:OSQAccept();
(6)清空一个消息队列:OSQFlush();
(7)查询一个消息队列的状态:OSQQuery()。
21.μC/OS-Ⅱ内存管理提供哪些服务
答:μC/OS-Ⅱ内存管理提供的服务包括:
(1)`
(2)建立一个内存分区:OSMemCreate();
(3)分配一个内存块:OSMemGet();
(4)释放一个内存块:OSMemPut();
(5)查询一个内存分区的状态:OSMemQuery()。
22.移植µC/OS-Ⅱ时,要使µC/OS-Ⅱ正常运行,处理器必须满足哪些基本要求
答:要使µC/OS-Ⅱ正常运行,处理器必须满足以下要求:
(1)¥
(2)处理器的C编译器能产生可重入代码。
(3)用C语言就可以打开和关闭中断。
(4)处理器支持中断,并且能产生定时中断(通常在10至100Hz之间)。
(5)处理器支持能够容纳一定量数据(可能是几千字节)的硬件堆栈。
(6)处理器有将堆栈指针和其它CPU寄存器读出和存储到堆栈或内存中的指
令。
"
四.论述题
1.论述μC/OS-Ⅱ控制下的任务状态转换图
答:μC/OS-Ⅱ控制下的任务状态转换图如下图所示。
在任一给定的时刻,任务的状态一定是在这五种状态之一。
(1)睡眠态(DORMANT):指任务驻留在程序空间之中,还没有交给μC/OS-Ⅱ
管理。
一个任务可以通过调用OSTaskDel()返回到睡眠态,或通过调用该函数让另一个任务进入睡眠态。
(2)就绪态(READY):当任务一旦建立,这个任务就进入就绪态准备运行。
把
任务交给μC/OS-Ⅱ是通过调用下述两个函数之一:OSTaskCreate()或OSTaskCreateExt()。
(3)|
(4)运行态(RUN): 调用OSStart()可以启动多任务。
OSStart()函数运行进入
就绪态的优先级最高的任务。
(5)等待状态(WAITING): 正在运行的任务可以通过调用两个函数之一将自
身延迟一段时间,这两个函数是OSTimeDly()或OSTimeDlyHMSM()。
这个任务于是进入等待状态,等待这段时间过去,下一个优先级最高的、并进入了就绪态的任务立刻被赋予了CPU的控制权。
正在运行的任务期待某一事件的发生时也要等待,手段是调用以下3个函数之一:OSSemPend(),OSMboxPend(),或OSQPend()。
调用后任务进入了等待状态(WAITING)。
(6)中断状态(ISR): 正在运行的任务是可以被中断的,除非该任务将中断关
了,或者μC/OS-Ⅱ将中断关了。
被中断了的任务就进入了中断服务态(ISR)。
2. 论述μC/OS-Ⅱ的核心数据结构任务控制块(OS_TCBs)
答:
任务控制块(OS_TCBs)是μC/OS-Ⅱ的核心数据结构,当任务的CPU使用权被剥夺时,μC/OS-Ⅱ用它来保存该任务的状态。
当任务重新得到CPU使用权时,任务控制块能确保任务从当时被中断的那一点丝毫不差地继续执行。
OS_TCBs全部驻留在RAM中。
一旦任务建立了,任务控制块OS_TCBs将被赋值。
µC/OS-II 任务控制块数据结构定义如下:
|
typedef struct os_tcb {
OS_STK *OSTCBStkPtr;
#if OS_TASK_CREATE_EXT_EN
void *OSTCBExtPtr;
OS_STK *OSTCBStkBottom;
INT32U OSTCBStkSize;
INT16U OSTCBOpt;
INT16U OSTCBId;
#
#endif
struct os_tcb *OSTCBNext;
struct os_tcb *OSTCBPrev;
#if (OS_Q_EN && (OS_MAX_QS >= 2)) || OS_MBOX_EN || OS_SEM_EN
OS_EVENT *OSTCBEventPtr;
#endif
#if (OS_Q_EN && (OS_MAX_QS >= 2)) || OS_MBOX_EN
void *OSTCBMsg;
—
#endif
INT16U OSTCBDly;
INT8U OSTCBStat;
INT8U OSTCBPrio;
INT8U OSTCBX;
INT8U OSTCBY;
INT8U OSTCBBitX;
INT8U OSTCBBitY;
:
#if OS_TASK_DEL_EN
BOOLEAN OSTCBDelReq;
#endif
} OS_TCB;
其中:
OSTCBStkPtr是指向当前任务栈顶的指针。
OSTCBExtPtr 指向用户定义的任务控制块扩展。
OSTCBStkBottom是指向任务栈底的指针。
OSTCBStkSize存有栈中可容纳的指针元数目而不是用字节(Byte)表示的栈容量总数。
OSTCBId用于存储任务的识别码。
OSTCBNext和OSTCBPrev用于任务控制块OS_TCBs的双重链接。
OSTCBEventPtr是指向事件控制块的指针。
OSTCBMsg是指向传给任务的消息的指针。
OSTCBStat是任务的状态字。
OSTCBPrio是任务优先级。
OSTCBDelReq是一个布尔量,用于表示该任务是否需要删除。
OSTCBX, OSTCBY, OSTCBBitX和 OSTCBBitY用于加速任务进入就绪态的过程或进入等待事件发生状态的过程。
3.论述事件控制块ECB数据结构
答:µC/OS-II通过中定义的OS_EVENT数据结构来维护一个事件控制块的所有信息。
该事件控制块ECB数据结构的定义如下:
typedef struct {
void *OSEventPtr; /* 指向消息或者消息队列的指针 */
INT8U OSEventTbl[OS_EVENT_TBL_SIZE]; /* 等待任务列表 */
INT16U OSEventCnt; /* 计数器(当事件是信号量时) */
INT8U OSEventType; /* 时间类型 */
INT8U OSEventGrp; /* 等待任务所在的组 */
} OS_EVENT;
其中:
OSEventPtr指针: 只有在所定义的事件是邮箱或者消息队列时才使用。
当所定义的事件是邮箱时,它指向一个消息,而当所定义的事件是消息队列时,它指向一个数据结构.
OSEventTbl[] 和OSEventGrp:两者包含的是系统中处于就绪状态的任务。
OSEventCnt:当事件是一个信号量时,用于信号量的计数器。
OSEventType:定义了事件的具体类型。
4.论述µC/OS-II内存的管理的内存控制块数据结构
答:为了便于内存的管理,在µC/OS-II中使用内存控制块(memory control blocks)的数据结构来跟踪每一个内存分区,系统中的每个内存分区都有它自己的内存控制块。
内存控制块的数据结构定义如下:
typedef struct {
void *OSMemAddr;
void *OSMemFreeList;
INT32U OSMemBlkSize;
INT32U OSMemNBlks;
INT32U OSMemNFree;
} OS_MEM;
其中:
OSMemAddr是指向内存分区起始地址的指针。
OSMemFreeList是指向下一个空闲内存控制块或者下一个空闲的内存块的指针。
OSMemBlkSize是内存分区中内存块的大小,是用户建立该内存分区时指定的。
OSMemNBlks是内存分区中总的内存块数量,也是用户建立该内存分区时指定的。
OSMemNFree是内存分区中当前可以得空闲内存块数量。