ES体系结构的研究及其应用ES 内嵌式存储系统(embedded storage)(10)

2019-09-01 08:37

扬州大学硕士学位论文

根目录 README.txt BLOCKSOURCE SOFTWARE uCOS-II 8051 PROJ1_8051 ?? PROJn_8051 图

5.1 μC/OS-II目录结构

README.txt文件是关于SOFTWARE的说明文件。

SOFTWARE目录是μC/OS-II源代码的起点目录,这个目录是位置无关的。将SOFTWARE拷贝到操作系统的任何磁盘目录中,该目录下的文件都不需要修改,就可以通过编译器的处理。

SOFTWARE下面的2个目录是BLOCK和μC/OS-II,BLOCK目录中包含《嵌入式系统构件》中描述的构件模块,这不是本论文的重点,将另文介绍。μC/OS-II是操作系统相关的代码,包含了μC/OS-II操作系统的源代码和应用程序代码。

μC/OS-II包含2个源代码目录和若干个项目程序目录。 2个源代码目录是:SOURCE和8051。SOURCE中包含平台无关的代码,是μC/OS-II的核心部分。SOURCE目录有11个文件,构成μC/OS-II V2.51的内核:

文件名 OS_CORE.C OS_FLAG.C OS_MBOX.C OS_MEM.C OS_MUTEX.C OS_Q.C OS_SEM.C OS_TASK.C OS_TIME.C uCOS-II.C uCOS-II.H 内容 操作系统核心代码 事件标志代码 邮箱代码 内存管理代码 互斥信号量代码 消息队列代码 信号量代码 任务管理代码 时间管理代码 系统代码汇总文件 系统头文件

8051目录下面有一个唯一的目录Keil,表示这个结构相关的代码是用于Keil C51开发环境的。Keil目录下面包含3个文件 文件名 OS_CPU.H 46

内容 体系结构相关代码的头文件 周全 ES体系结构的研究及其应用

OS_CPU_A.ASM OS_CPU_C.C 体系结构相关代码的汇编源文件 体系结构相关代码的C语言文件

5.3 μC/OS-II结构详解

μC/OS-II的结构,Labrosse先生的《μC/OS-II——源码公开的实时嵌入式操作系统》一书是“实时操作系统”的经典著作,在国内外受到广泛的好评。

下面介绍研究μC/OS-II的方法和过程以及其基本结构。

要想了解一个运行的软件系统,一般可以采用调试手段里的单步执行(Step)来过一遍程序。经过跟踪系统的初始化和运行,可以深入地了解μC/OS-II的运行情况。下面以在Keil C51下调试通过的μC/OS-II应用程序为例,跟着程序指针一起漫游。

5.3.1 μC/OS-II运行过程

系统复位以后,跳转到main函数入口。Main函数首先调用Inin_51函数,对目标系统进行初始化。在这个仿真环境中,需要用到8051的Timer0和Serial。所以要对这两个外围设备进行初始化。对于其他的项目,根据实际要求添加初始化代码。

执行Init_51,写Timer0和Serial的寄存器,同时初始化Serial缓冲区。完成Init_51的初始化以后,调用OSInit函数,执行μC/OS-II操作系统的初始化。

OSInit是一个很大的程序,初始化操作系统的所有变量和结构。

首先,对OSIntNesting、OSLockNesting、OSTaskCtr、OSRunning、OSIdleCtr清零。如果使用“统计”任务(OS_TASK_STAT),那么对OSIdleCtrRun、OSIdleCtrMax、OSStatRdy清零。

接下来对OSCtxSwCtr、OSRdyGrp清零。初始化prdytbl,对所有元素清零。对OSPrioCur、OSPrioHighRdy、OSTCBHighRdy、OSTCBCur、OSTCBList清零。

接下来对OSTCBPrioTbl所有元素清零。初始化空闲TCB列表。如果需要Event,初始化OSEventFreeList。

如果需要Flag,调用OS_FlagInit;如果需要队列(Queue),调用OS_QInit;如果需要Mem,调用OS_MemInit。创建IDLE任务(必须)和STAT任务(可选)。

完成了OSInit函数以后,主程序使用OSTaskCreate或者OSTaskCreateEx来创建任务。μC/OS-II最多支持64个优先级,系统占用8个,用户可创建56个任务。OSTaskCreate接受至少3个参数:任务函数指针、任务堆栈栈顶地址和任务优先级。OSTaskCreate的主要任务是初始化任务堆栈(OSTaskStkInit)和任务TCB块(OS_TCBInit),向任务堆栈保存初始数据,并且将任务堆栈地址保存到TCB中。

完成了初始化和任务创建,就可以运行实时系统了。

OSStart函数启动系统,计算出最高优先级的任务,OSTCBCur向该任务块,调用OSStartHighRdy函数运行该任务。

5.3.2 调度的发生

μC/OS-II有64个优先级,系统占用8个,用户可创建56个任务,不支持时间片轮转。μC/OS-II的原理是尽量让优先级最高的任务处于运行状态。

47

扬州大学硕士学位论文

通过在任何可能引起优先级可能错了,应为进程状态,下同改变的地方执行调度算法。引起优先级改变的有两种情况:

1. 发生中断以后经过统计有2种中断:外部中断和定时中断。

① 发生外部中断,可能是某种资源由不可用变为可用,或者由可用变为不可用。 ② 发生定时中断(就是系统的TICK),时间片到期。操作系统重新计算最高优先级,然后分配时间片。

2. 当前进程主动放弃某种资源

当前进程主动放弃资源有2种情况:进程释放某种信号量和进程释放CPU时间片。 当进程完成对某种资源操作时,会释放该资源。这时,如果有更高优先级的进程在等待该资源,那么它就进入就绪态。这需要重新调度,使该优先级运行。

有时进程会因为无法得到需要的资源、或者调用延时程序使自己挂起。这时会调用OS_Sched。

但永远不会出现进程成功获得了请求的资源而导致系统优先级改变的情况! μC/OS-II系统内核中调用OS_Sched调度函数的地方一共27次:

OS_TASK.C OS_SEM.C OS_MUTEX.C OS_MBOX.C OS_Q.C OS_FLAG.C OS_TIME.C OS_CORE.C 6 3 3 4 5 3 2 1

通过事先计算好数据,简化了运算量,通过精心设计就绪表结构,使得延时可预知。任务的切换是通过模拟一次中断实现的。

5.3.3 体系结构相关代码

了解了μC/OS-II的启动,就不难理解整个操作系统了。从上一节列出的文件列表中可以看出,μC/OS-II包括任务调度、时间管理、内存管理、资源管理(信号量、互斥信号量、邮箱、消息队列和事件标志)四大部分。它没有文件系统、网络接口、输入输出界面。这些部分本来就不属于操作系统内核,只是因为它们是计算机系统不可缺少的部分,才成为操作系统的一个必备部分。

μC/OS-II的移植需要写4个文件:汇编文件(OS_CPU_A.ASM)、处理器相关C文件(OS_CPU.H、OS_CPU_C.C)和配置文件(OS_CFG.H)。配置文件主要与应用相关,不同的系统选择不同的配置,以达到最小冗余度的目的。

5.4 μC/OS-II的移植 5.4.1 结构说明

1. 堆栈的定义

堆栈是一个元素的列表,仅仅从列表的一端访问这个列表。

48

周全 ES体系结构的研究及其应用

2. 堆栈的用途

堆栈有很多用途,在软件设计和硬件设计的很多地方都用到堆栈。例如,编译器的语法分析就是基于堆栈的;堆栈计算机和Forth语言也是基于堆栈的。

在硬件方面,每一种微处理器/微控制器都支持堆栈结构。因为只要支持函数或子程序、中断调用,就必须使用堆栈。

函数的调用过程中,参数的传递和数值的返回也是通过堆栈实现的。函数的本地变量一般保存在堆栈中。

另外,发生硬件中断时,需要保护断点,也需要堆栈的支持。不过,有一些CPU带有返回地址寄存器,例如,ARM的lr寄存器。这时断点地址不需要保存到堆栈中。这种返回地址寄存器的存在仅仅是为了方便,而不是为了取代堆栈的作用,也不可能取代堆栈。当发生函数嵌套的时候,必须将lr寄存器保存到堆栈中,以免上一层函数调用的返回地址丢失。

以上的硬件实现,一部分由微处理器/微控制器的寄存器+栈操作指令+RAM实现。另一部分由指令序列(函数或者宏)实现。

通常,微处理器/微控制器提供一个SP(Stack Pointer)寄存器和栈操作指令(PUSH Rx/POP Rx)来实现对堆栈的支持。

除了堆栈操作指令,其他的一些指令会影响堆栈。例如子程序返回指令RET和中断返回指令RETI将堆栈中保存的返回地址弹出到PC。

3. 堆栈、编译器和操作系统 堆栈概念本身不难理解。实际开发中经常会遇到堆栈相关的问题,是因为使用的开发工具对堆栈进行了复杂的处理。

操作系统,尤其是多任务操作系统,需要可重入函数。另一个重要的问题是函数的重入(reentrant)问题。

可重入函数是指在上一次函数调用返回以前,可以再一次被调用的函数。以下几种情况,需要可重入函数的支持:

① 递归函数

递归函数必须是可重入的。递归函数在自己结束以前,多次调用自己来求解问题。 ② 被中断调用的函数。如果一个函数可能被突发的中断再一次调用,它必须是可重入函数。

③ 并发的进程调用的程序。在多任务系统中,一个函数可能被不同的任务调用,它必须是可重入函数。

可重入函数的调用参数和本地变量都保存在堆栈中,被调用一次,堆栈中增加一份该次调用的上下文(Content),这样如果该函数在返回以前被再一次调用,以前若干次的调用上下文都不会丢失。

对不可重入的函数而言,如果上下文没有或者没有全部被保存到堆栈中,不同的调用将共享上下文。如果出现并发的调用,将发生不可预知的结果!

4. KEIL C51编译器的堆栈处理

Keil C51中的函数是不可重入的,除非显式声明函数为reentrant。根据Keil C51调用协议,可重入函数的调用参数和本地变量保存在虚拟堆栈中。虚拟堆栈可以设置到idata段(C_IBP)、pdata段(C_PBP)和xdata段(C_XBP)。对于small模式,虚拟堆栈设置到idata段。middlel模式设置虚拟堆栈到pdata段。对于Large模式,设置堆栈到xdata段。

对μC/OS-II的移植使用Large模式,虚拟堆栈指针是全局变量?C_XBP。在μC/OS-II中,多进程系统中,必须用到可重入函数。系统在每一次任务切换的过程中,要保存虚拟堆栈指针是全局变量?C_XBP。

49

扬州大学硕士学位论文

这就是在μC/OS-II移植到8051这种体系结构的单片机上时需要考虑的最重要的问题。

KEIL C51是优秀的8051高级语言开发工具。一般定义的函数是不可重入的。扩展关键字reentrant指示函数为可重入函数。KEIL通过模拟栈来实现可重入函数。C51编译器为可重入函数建立一个模拟栈完成参数传递和存放局部变量。模拟栈以全局变量?C_IBP、?C_PBP、?C_XBP作为栈指针,这些变量定义在DATA地址空间。编译时采用存储器模式,模拟栈区可位于内部(IDATA)或者外部(PDATA或XDATA)存储器中。

根据KEIL文档,仿真栈和栈指针在LIB子目录下的启动代码STARTUP.A51文件中声明。必须在该文件中修改一个或者多个仿真堆栈的开始地址。

5. 堆栈设计

如图5.2所示,TCB结构体中OSTCBStkPtr总是指向用户堆栈最低地址,该地址空间内存放用户堆栈长度,它的上方空间存放系统堆栈映像,即:用户堆栈空间大小=系统堆栈空间大小+1。

?? ?? ?? OSTCBStkPtr 长度 SP ?? ?? ?? OSStack OSStkStart 用户堆栈 系统堆栈

图5.2 堆栈结构

SP总是先加1再存数据,因此,SP初始时指向系统堆栈起始地址(OSStack)减1处(OSStkStart)。很明显系统堆栈存储空间大小=SP-OSStkStart。

任务切换时,先保存当前任务堆栈内容。方法是:用SP-OSStkStart得出保存字节数,将其写入用户堆栈最低地址内,以用户堆栈最低地址为起址,以OSStkStart为系统堆栈起址,由系统栈向用户栈拷贝数据,循环SP-OSStkStart次,每次拷贝前先将各自栈指针增1。

其次,恢复最高优先级任务系统堆栈。方法是:获得最高优先级任务用户堆栈最低地址,从中取出“长度”,以最高优先级任务用户堆栈最低地址为首址,以OSStkStart为系统堆栈首址,由用户栈向系统栈拷贝数据,循环“长度”数值指示的次数,每次拷贝前先将各自栈指针增1。

用户堆栈初始化时从下向上依次保存:用户堆栈长度(15),PCL,PCH,PSW,ACC,B,DPL,DPH,R0,R1,R2,R3,R4,R5,R6,R7。不保存SP,任务切换时根据用户堆栈长度计算得出。

OSTaskStkInit函数总是返回用户栈最低地址。

堆栈设计是移植过程中最重要的部分,本文将在下面详细介绍操作系统堆栈设计的原理和要求。

5.4.2 使用KEIL C51建立RTOS

50


ES体系结构的研究及其应用ES 内嵌式存储系统(embedded storage)(10).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:2019年中考英语语法专题讲练: 被动语态 讲解附练习(含解析)

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: