欢迎来到三一办公! | 帮助中心 三一办公31ppt.com(应用文档模板下载平台)
三一办公
全部分类
  • 办公文档>
  • PPT模板>
  • 建筑/施工/环境>
  • 毕业设计>
  • 工程图纸>
  • 教育教学>
  • 素材源码>
  • 生活休闲>
  • 临时分类>
  • ImageVerifierCode 换一换
    首页 三一办公 > 资源分类 > DOC文档下载  

    ARM 嵌入式操作系统移植 论文08852.doc

    • 资源ID:2392377       资源大小:367.50KB        全文页数:33页
    • 资源格式: DOC        下载积分:8金币
    快捷下载 游客一键下载
    会员登录下载
    三方登录下载: 微信开放平台登录 QQ登录  
    下载资源需要8金币
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    ARM 嵌入式操作系统移植 论文08852.doc

    摘 要随着ARM技术的广泛应用,建立基于ARM构架的嵌入式操作系统已成为当前研究的热点。本课题的研究内容就是利用移植技术将uC/ OS - II 移植到ARM 系统。将uC/ OS - II 移植到ARM 系统之后,可以充分结合两者的优势。uC/OS - II 的文件系统结构包括核心代码部分、设置代码部分、与处理器相关的移植代码部分。核心代码部分包括7 个源代码文件和1 个头文件. 功能分别是内核管理、事件管理、消息队列管理、存储管理、消息管理、信号量处理、任务调度和定时管理. 设置代码部分包括2 个头文件,用来配置事件控制块的数目以及是否包含消息管理相关代码. 而与处理器相关的移植代码部分则是进行移植过程中需要更改的部分,包括1 个头文件OS CPU. H ,1 个汇编文件OS CPU A. S 和1 个C 代码文件.实际上将uC/ OS - II 移植到ARM 处理器上,需要完成的工作主要是以下三个与体系结构相关的文件:OS CPU. H ,OS CPU. C 以及OS CPU A. S。关键词: ARM 嵌入式操作系统 移植 uc/os-II AbstractAlong with the extensive application of ARM technology based on ARM architecture, the embedded operating system has become a hotspot of current researches. The research content is the use of transplanting uC/ OS - II transplanted into ARM system. UC/ OS - II transplanted into ARM system, can combine the advantages of the two. UC/OS - II file system structure includes part of the core code, set the code portion, a processor associated with transplant code section. Part of the core code includes 7source code files and the1 header files. Function are core management, event management, message queue management, storage management, message management, signal processing, task scheduling and time management. Setting code portion includes the first 2 documents, used to configure event control block numbers and whether it contains message management code and a processor associated with transplant code is part of the transplant process need to change parts, including the1 header files OS CPU. H,1OS CPU A. files S and 1C code files. The actual admiral uC/ OS - II transferred to the ARM processor, work to be finished basically is the following three architecture dependent file: OS CPU. H, OS CPU. C and OS CPU A. S.Keyword: ARM embedded operating system porting uc/os-II目 录引 言11 UC /OS- II简介21.1 uC /OS- II的工作流程21.2 uC /OS- II的体系结构31.3 uC/OS-II工作原理42 UC/OS内核调度52.1 uC/OS-II内核结构52.2任务控制块(OS_TCB)62.3 就绪表(ReadyList)72.4 任务状态82.5 任务转换102.6 任务调度分析102.7 UC/OS-II的初始化123 UC/ OS - II 的移植133.1 OS CPU. H 的移植133.2 OS CPU. C 的移植143.3 OS CPU A. S 的移植143.4 硬件平台154 在嵌入式系统上的实现174.1 开/关中断的实现174.2 OSStartHighRdy 的实现184.3 任务级上下文切换的实现184.4 中断级上下文切换的实现195 多任务应用程序21结 束 语23参 考 文 献24致 谢25附录26引 言在开发嵌入式系统时,一般选择基于ARM 和uC/ OS - II 的嵌入式开发平台,因为ARM 微处理器具有处理速度快、超低功耗、价格低廉、应用前景广泛等优点. 将uC/ OS - II 移植到ARM系统之后,可以充分结合两者的优势. 如果一个程序在一个环境里能工作,我们经常希望能将它移植到另一个编译系统、处理器或者操作系统上,这就是移植技术.移植技术可以使一种特定的技术在更加广泛的范围使用,使软件使用更加灵活,不局限于某一条件.uC/OS - II 是由Jean J. Labrosse 先生编写的完整的可移植、固化、裁剪的占先式实时多任务内核.uC/ OS - II 的源代码完全开放,这是其他商业实时内核无法比拟的. 它是针对嵌入式应用设计的,在设计之初就充分考虑了可移植性,它的大部分源代码都是用高可移植性的ANSIC 编写的.与硬件相关部分用汇编语言编写, 使之 可供不同构架的微处理器使用。只要有标准的 AN SI C 交叉编译器, 有汇编器、链接器等软件工具, 就可以将 C /OS- II嵌入到开发的产品中。uC/ OS - II可以移植到从8 位到64 位的不同类型、不同规模的嵌入式系统,并能在大部分的8 位、16 位、32 位、甚至64 位的微处理器和DSP 上运行. 由于uC/ OS - II是一个实时操作系统,所以如果将它嵌入到ARM处理器上,就能够进一步简化ARM系统的开发。uC /OS- II是面向中小型嵌入式系统, 具有执行效 率高、占用空间小、实时性能优良和可扩展性强等特 点, 包含全部功能模块的内核大约为 10kB。如果经过 裁减只保留核心代码, 则可压缩到 3kB 左右。严格地 说, uC /OS- II只是一个实时操作系统内核, 它仅仅包 含了任务调度、任务管理、时间管理、内存管理和任务 间的通信和同步等基本功能, 没有提供输入输出管理、文件系统、网络等额外的服务。嵌入式技术发展至今已经进入到了嵌入式Internet的阶段,越来越多的嵌入式设备实现了通过以太网技术接入互联网。将嵌入式设备接入以太网的关键是在嵌入式设备上实现嵌入式TCP/IP协议。相比普通的TCP/IP协议,嵌入式TCP/IP协议具有代码精简、很好的可裁减性和很强的移植性等特点。嵌入式系统是先进的计算机技术、半导体技术、电子技术、和各个行业的具体应用相结合的产物,它是以计算机应用为中心、以计算机技术为基础,软硬件可裁减的专用计算机系统。在嵌入式系统中使用操作系统(嵌入式操作系统)已是大势所趋,目前嵌入式操作系统的种类繁多,但uc/os-II以其源代码开放、价格便宜、可移植性强等特点,被广泛使用。1 uC /OS- II简介C/OS-II是一种可移植的,可植入ROM的,可裁剪的,抢占式的,实时多任务操作系统内核。它被广泛应用于微处理器、微控制器和数字信号处理器。 C/OS-II 的前身是C/OS,最早出自于1992 年美国嵌入式系统专家Jean J.Labrosse 在嵌入式系统编程杂志的5 月和6 月刊上刊登的文章连载,并把C/OS 的源码发布在该杂志的B B S 上。 C/OS 和C/OS-II 是专门为计算机的嵌入式应用设计的, 绝大部分代码是用C语言编写的。CPU 硬件相关部分是用汇编语言编写的、总量约200行的汇编语言部分被压缩到最低限度,为的是便于移植到任何一种其它的CPU 上。用户只要有标准的ANSI 的C交叉编译器,有汇编器、连接器等软件工具,就可以将C/OS-II嵌入到开发的产品中。C/OS-II 具有执行效率高、占用空间小、实时性能优良和可扩展性强等特点, 最小内核可编译至 2KB 。C/OS-II 已经移植到了几乎所有知名的CPU 上。 严格地说uC/OS-II只是一个实时操作系统内核,它仅仅包含了任务调度,任务管理,时间管理,内存管理和任务间的通信和同步等基本功能。没有提供输入输出管理,文件系统,网络等额外的服务。但由于uC/OS-II良好的可扩展性和源码开放,这些非必须的功能完全可以由用户自己根据需要分别实现。 uC/OS-II目标是实现一个基于优先级调度的抢占式的实时内核,并在这个内核之上提供最基本的系统服务,如信号量,邮箱,消息队列,内存管理,中断管理等。1.1 uC /OS- II的工作流程uC /OS- II的工作流程如图1.1所示: 首先进行操作系统初始化, 主要完成任务控制块 ( TCB )初始化; 然后就可以开始创建新任务、初始化任务堆栈区; 最后调用 OSSTART( )函数, 启动多任务调度。在多任务调度开 始后, 启动时钟节拍源开始计时。此节拍源为系统提 供周期性的时钟中断信号、实现延时和超时确认。当 时钟中断来临时, 系统把当前正在执行的任务挂起, 保护现场, 进行中断处理, 判断有无任务延时到期。若 有, 则使该任务进入就绪态, 并对所有进入就绪态的任 务的优先级进行比较, 通过任务切换去执行最高优先 级的任务。若没有别的任务进入就绪态, 则恢复现场 继续执行原任务。另一种调度方式是任务级的调度, 即通过发软中断命令或依靠处理器在任务执行中调 度。如任务要等待信号量或一个正在执行的任务被挂 起时, 就需要在此任务中调度, 找出目前处于就绪态的 优先级最高的任务去执行。当没有任何任务进入就绪 态时, 就去执行空任务。图1.1 uC /OS- II的工作流程图1.2 uC /OS- II的体系结构对 uC /OS - II的移植实际上就是对 与处理器有关的代码进行重写或修改。移植工作包括 以下几部分内容:用# define设置 1个常量的值 ( OS _CPU. H 文件中 );声明 10个数据类型 ( OS_CPU. H 文件中 ); 用# define声明 3个宏 ( OS_CPU. H 文件中 );用 C 语言编写 6个简单的函数 ( OS _CPU. C 文件中 );编写 4个汇编语言函数 ( OS _CPU. A SM 文件中 )。虽然 uC /OS - II的大部分代码是用 C 语言编写但还存在一些与处理器相关的汇编语言代码, 从而实 现对处理器寄存器的访问以及堆栈的操作。 uC/OS-II操作系统的移植主要是对 OS _CPU. H, OS _CPU. ASM, OS_CPU. C等 3个源程序的编写。OS_CPU. H 中包括了用# define定义的与处理器相 关的常量和类型定义, 与 uC /OS - II所定义的变量类 型相一 致; 定义允许 和禁止中断宏 OS _ ENTER _ CR IT ICAL( )和 OS_EX IT_CRITICAL( ) 来保护临界段代 码免受多任务或中断服务例程的破坏。定义栈的增长 方向, GCC 的 C语言编译器仅支持从上往下增长, 并且 必须是满递减堆栈, OS_STK _GROWTH 的值定义为 1。OS_CPU. ASM中要求编写 4个简单的汇编函数: (1) OSStartHighRdy( )作用是运行最高优先级的就绪任务。(2) OSCtxSw( )是实现 CPU 在正常运行时任务间的切换,即对当前任务堆栈的保存和对高优先级任务堆栈的弹出, 使最高优先级任务获取CPU 的控制权。(3) OSIntCtxSw( )是在中断服务程序中执行任务切换。(4) OSTickISR( )是系统时钟的中断服务程序,该程序执行频率为10 100 H z, 主要功能是检查是否有由于延时而被挂起的任务成为就绪任务。如果有,就调用OSIntCtxSw( )进行任务切换,从而运行高优先级的任务;因为uC /OS- II在每一个节拍都要检查有没有更高优先级的任务在等待执行,若有,就要进行任务切换。所以,时钟节拍率越高,系统的额外负荷就越重OS_CPU.C中要求编写6个与操作系统相关的函数: OSTaskStkInit( ), OSTaskCreateHook( ),OSTaskDelHook( ), OSTaskStatHook( ) 及OSTmieTickHook( )。其中,唯一必须移植的是任务堆栈 初始化函OSTaskStkInit( ),这个函数在任务创建时被调用,负责初始化任务的堆栈结构并返回新堆栈的指针。1.3 uC/OS-II工作原理uC/OS-II是一种基于优先级的可抢先的硬实时内核。在uC/OS-II里,每个任务都有一个任务控制块(Task Control Block),这是一个比较复杂的数据结构。在任务控制块的偏移为0的地方,存储着一个指针,它记录了所属任务的专用堆栈地址。在uC/OS-II内,每个任务都有自己的专用堆栈,彼此之间不能侵犯。这点要求程序员再他们的程序中保证。一般的做法是把他们申明成静态数组。而且要申明成OS_STK类型。当任务有了自己的堆栈,那么就可以将每一个任务堆栈在那里记录到前面谈到的任务控制快偏移为0的地方。以后每当发生任务切换,系统必然会先进入一个中断,这一般是通过软中断或者时钟中断实现。然后系统会先把当前任务的堆栈地址保存起来,仅接着恢复要切换的任务的堆栈地址。由于哪个任务的堆栈里一定也存的是地址(还记得我们前面说过的,每当发生任务切换,系统必然会先进入一个中断,而一旦中断CPU就会把地址压入堆栈),这样,就达到了修改PC为下一个任务的地址的目的。2 uC/OS内核调度在多任务系统中,内核是负责管理各个任务,或者说是为每个任务分配CPU时间,同时负责任务之间的通讯。内核所提供的基本服务是任务切换。之所以使用实时内核可以大大简化应用系统的设计,是因为实时内核允许将应用分成若干个任务,由实时内核来管理它们。内核本身也增加了应用程序的额外负荷,代码空间增加ROM的用量,内核本身的数据结构增加了RAM的用量。但更主要的是,每个任务要有自己的栈空间,这一块吃起内存来是相当厉害的。内核本身对CPU的占用时间一般在2到5个百分点之间。UC/OS-II内核调度特点:1.只支持基于优先级的抢占式调度算法,不支持时间片轮训;2.64个优先级,只能创建64个任务,用户只能创建56个任务;3.每个任务优先级都不相同;4.不支持优先级逆转;5.READY队列通过内存映射表实现快速查询。效率非常高;6.支持时钟节拍; 7.支持信号量,消息队列,事件控制块,事件标志组,消息邮箱任务通讯机制;8.支持中断嵌套,中断嵌套层数可达255层,中断使用当前任务的堆栈保存上下文; 9.每个任务有自己的堆栈,堆栈大小用户自己设定;10.支持动态修改任务优先级;11.任务TCB为静态数组,建立任务只是从中获得一个TCB,不用动态分配,释放内存; 12.任务堆栈为用户静态或者动态创建,在任务创建外完成,任务创建本身不进行动态内存分配;13.任务的总个数(OS_MAX_TASKS)由用户决定;14.0优先级最高,63优先级最低;15.有一个优先级最低的空闲任务,在没有用户任务运行的时候运行。2.1 uC/OS-II内核结构1、uC/OS-II是以源代码形式提供的实时操作系统内核,其包含的文件结构如下:基于uC/OS-II操作系统进行应用系统时,设计任务的主要任务是将系统合理划分成多个任务,并由RTOS进行调度,任务之间使用uC/OS-II提供的系统服务进行通信,以配合实现应用系统的功能。上图中应用代码部分主要是设计人员设计的业务代码。应用软件(用户代码)uC/OS-II内核文件(与处理器类型无关的代码)OS_CORE.C OS_TASK.COS_FLAG.C OS_TIME.COS_MBOX.C uCOS-II.COS_MEM.C uCOS-II.HOS_MUTEX.C OS_SEM.COS_Q.CuC/OS-II 配置文件(与应用程序有关)OS_CFG.HINCLUDES.H移植uC/OS-II(与处理器类型有关的代码)OS_CPU.H OS_CPU_C.COS_CPU_A.ASM CPU 定时器图2.1 uC/OS-II 的文件结构软件硬件基于uC/OS-II操作系统进行应用系统时,设计任务的主要任务是将系统合理划分成多个任务,并由RTOS进行调度,任务之间使用uC/OS-II提供的系统服务进行通信,以配合实现应用系统的功能。上图中应用代码部分主要是设计人员设计的业务代码。与前后台系统一样,基于uC/OS-II的多任务系统也有一个main主函数,main函数由编译器所带的C启动程序调用。在main主函数中主要实现uC/OS-II的初始化OSInit()、任务创建、一些任务通信方法的创建、uC/OS-II的多任务启动OSStart()等常规操作。另外,还有一些应用程序相关的初始化操作,例如:硬件初始化、数据结构初始化等。 在使用uC/OS-II提供的任何功能之前,必须先调用OSInit()函数进行初始化。在main主函数中调用OSStart()启动多任务之前,至少要先建立一个任务。否则应用程序会崩溃。OSInit()初始化uC/OS-II所有的变量和数据结构,并建立空闲任务OS_TaskIdle(),这个任务总是处于就绪态。2.2任务控制块(OS_TCB)任务控制块(TCB)是一个数据结构OS_TCB,一旦一个任务创建,就有一个和它关联的TCB被赋值。当任务的CPU使用权被剥夺时,它用来保存该任务的状态。这样,当任务重新获得CPU使用权时,可以从TCB中获取任务切换前的信息,准确的继续运行。任务控制块包含了许多任务信息,主要有:.OSTCBStkPtr 指向当前任务堆栈栈顶的指针。uC/OS-II允许每个任务有自己的堆栈,每个任务堆栈的大小可以不一样。.OSTCBNext 和.OSTCBPrev 指向OS_TCB双向链表的前、后连接。.OSTCBEventPtr 指向事件控制块的指针;.OSTCBDly 保存任务的延时节拍数,或允许等待事件发生的最多节拍数。.OSTCBPrio 任务的优先级;文件OS_CFG.H中定义的最多任务数OS_MAX_TASKS决定了分配给用户程序的任务控制块的数目。所有的任务控制块都放在任务控制块数组OSTCBTbl 中。uC/OS-II初始化时,所有OS_TCB都被链接成单向空任务链表。任务一旦建立,就将链表开头的OS_TCB赋给该任务。一旦任务被删除,OS_TCB就还给空任务链表。任务建立时,函数OS_TCBInit()初始化任务控制块。2.3 就绪表(ReadyList)UC/OS-II采用内存映射的方式来实现READY队列的加入,查找,删除功能,效率非常高。但是也因此只能支持64个任务,每个任务都有自己的优先级,不能和其他任务优先级向同。每个任务的就绪态标志都放入就绪表中的,就绪表中有两个变量OSRdyGrp和OSRdyTbl.在OSRdyGrp中,任务按优先级分组,8个任务为一组。OSRdyGrp中的每一位表示8组任务中每一组中是否有进入就绪态的任务。任务进入就绪态时,就绪表OSRdyTbl中的相应元素的相应位也置位。就绪表OSRdyTbl数组的大小取决于OS_LOWEST_PRIO(见文件OS_CFG.H)。为确定下次该哪个优先级的任务运行了,内核调度器总是将OS_LOWEST_PRIO在就绪表中相应字节的相应位置是按以下规则给出的: 当OSRdyTbli中的任何一位是1时,OSRdyGrp的第i位置1.i从0到7.使任务进入就绪态OSRdyGrp|=OSMapTblprio>>3;OSRdyTblprio>>3|=OSMapTblprio&0x07;任务优先级的低三位用于确定任务在总就绪表OSRdyTbl中的所在位。接下去的三位用于确定是在OSRdyTbl数组的第几个元素。OSMapTbl是在ROM中的(见文件OS_CORE.C)屏蔽字,用于限制OSRdyTbl数组的元素下标在0到7之间,如果一个任务被删除了,则用程序清单3.6中的代码做求反处理。程序清单L3.6从就绪表中删除一个任务if(OSRdyTblprio>>3&=OSMapTblprio&0x07)=0)OSRdyGrp&=OSMapTblprio>>3;以上代码将就绪任务表数组OSRdyTbl中相应元素的相应位清零,而对于OSRdyGrp,只有当被删除任务所在任务组中全组任务一个都没有进入就绪态时,才将相应位清零。也就是说OSRdyTblprio>>3所有的位都是零时,OSRdyGrp的相应位才清零。为了找到那个进入就绪态的优先级最高的任务,并不需要从OSRdyTbl0开始扫描整个就绪任务表,只需要查另外一张表,即优先级判定表OSUnMapTbl。OSRdyTbl中每个字节的8位代表这一组的8个任务哪些进入就绪态了,低位的优先级高于高位。利用这个字节为下标来查OSUnMapTbl这张表,返回的字节就是该组任务中就绪态任务中优先级最高的那个任务所在的位置。这个返回值在0到7之间。确定进入就绪态的优先级最高的任务是用以下代码完成的。找出进入就绪态的优先级最高的任务y=OSUnMapTblOSRdyGrp;x=OSUnMapTblOSRdyTbly;prio=(y<<3)+x;例如,如果OSRdyGrp的值为二进制01101000,查OSUnMapTblOSRdyGrp得到的值是3,它相应于OSRdyGrp中的第3位bit3,这里假设最右边的一位是第0位bit0.类似地,如果OSRdyTbl3的值是二进制11100100,则OSUnMapTblOSRdyTbc3的值是2,即第2位。于是任务的优先级Prio就等于26(3*8+2)。利用这个优先级的值。查任务控制块优先级表OSTCBPrioTbl,得到指向相应任务的任务控制块OS_TCB的工作就完成了。2.4 任务状态UC/OS-II主要有五种任务状态,睡眠态就是挂起态,阻塞态和延时态这里统一为等待状态。增加了一个被中断状态。UC/OS-总是建立一个空闲任务,这个任务在没有其它任务进入就绪态时投入运行。这个空闲任务OSTaskIdle()永远设为最低优先级空闲任务OSTaskIdle()什么也不做,只是在不停地给一个32位的名叫OSIdleCtr的计数器加1,统计任务使用这个计数器以确定现行应用软件实际消耗的CPU时间。空闲任务不可能被应用软件删除。睡眠态(DORMANT)指任务驻留在程序空间之中,还没有交给C/OS-管理,把任务交给C/OS-是通过调用下述两个函数之一:OSTaskCreate()或OSTaskCreateExt()。当任务一旦建立,这个任务就进入就绪态准备运行。任务的建立可以是在多任务运行开始之前,也可以是动态地被一个运行着的任务建立。如果一个任务是被另一个任务建立的,而这个任务的优先级高于建立它的那个任务,则这个刚刚建立的任务将立即得到CPU的控制权。一个任务可以通过调用OSTaskDel()返回到睡眠态,或通过调用该函数让另一个任务进入睡眠态。调用OSStart()可以启动多任务。OSStart()函数运行进入就绪态的优先级最高的任务。就绪的任务只有当所有优先级高于这个任务的任务转为等待状态,或者是被删除了,才能进入运行态。正在运行的任务可以通过调用两个函数之一将自身延迟一段时间,这两个函数是OSTimeDly()或OSTimeDlyHMSM()。这个任务于是进入等待状态,等待这段时间过去,下一个优先级最高的、并进入了就绪态的任务立刻被赋予了CPU的控制权。等待的时间过去以后,系统服务函数OSTimeTick()使延迟了的任务进入就绪态。正在运行的任务期待某一事件的发生时也要等待,手段是调用以下3个函数之一:OSSemPend(),OSMboxPend(),或OSQPend()。调用后任务进入了等待状态(WAITING)。当任务因等待事件被挂起(Pend),下一个优先级最高的任务立即得到了CPU的控制权。当事件发生了,被挂起的任务进入就绪态。事件发生的报告可能来自另一个任务,也可能来自中断服务子程序。正在运行的任务是可以被中断的,除非该任务将中断关了,或者C/OS-将中断关了。被中断了的任务就进入了中断服务态(ISR)。响应中断时,正在执行的任务被挂起,中断服务子程序控制了CPU的使用权。中断服务子程序可能会报告一个或多个事件的发生,而使一个或多个任务进入就绪态。在这种情况下,从中断服务子程序返回之前,C/OS-要判定,被中断的任务是否还是就绪态任务中优先级最高的。如果中断服务子程序使一个优先级更高的任务进入了就绪态,则新进入就绪态的这个优先级更高的任务将得以运行,否则原来被中断了的任务才能继续运行。当所有的任务都在等待事件发生或等待延迟时间结束,C/OS-执行空闲任务(idletask),执行OSTaskIdle()函数。2.5 任务转换当多任务内核决定运行另外的任务时,它保存正在运行任务的当前状态(Context),即CPU寄存器中的全部内容。这些内容保存在任务的当前状况保存区(Task'sContextStoragearea),也就是任务自己的栈区之中。入栈工作完成以后,就是把下一个将要运行的任务的当前状况从该任务的栈中重新装入CPU的寄存器,并开始下一个任务的运行。这个过程叫做任务切换。任务切换过程增加了应用程序的额外负荷。CPU的内部寄存器越多,额外负荷就越重。做任务切换所需要的时间取决于CPU有多少寄存器要入栈。实时内核的性能不应该以每秒钟能做多少次任务切换来评价。uC/OS-II控制下的任务状态转换图如下:图2.2 uC/OS-II的任务状态转换图2.6 任务调度分析C/OS-提供最简单的实时内核任务调度,算法简单,因此也只支持优先级抢占任务调度,不支持时间片轮训调度算法,不支持优先级逆转。C/OS-总是运行进入就绪态任务中优先级最高的那一个。确定哪个任务优先级最高,下面该哪个任务运行了的工作是由调度器(Scheduler)完成的。任务级的调度是由函数OSSched()完成的。中断级的调度是由另一个函数OSIntExt()完成的,这个函数将在以后描述。C/OS-任务调度所花的时间是常数,与应用程序中建立的任务数无关。变量的比较,在8位和一些16位微处理器中这种比较相对较慢。而在C/OS-中是两个整数的比较。并且,除非用户实际需要做任务切换,在查任务控制块优先级表OSTCBPrioTbl时,不需要用指针变量来查OSTCBHighRdy.综合这两项改进,即用整数比较代替指针的比较和当需要任务切换时再查表,使得C/OS-比C/OS在8位和一些16位微处理器上要更快一些。为实现任务切换,OSTCBHighRdy必须指向优先级最高的那个任务控制块OS_TCB,这是通过将以OSPrioHighRdy为下标的OSTCBPrioTbl数组中的那个元素赋给OSTCBHighRdy来实现的L3.8(4).最后宏调用OS_TASK_SW()来完成实际上的任务切换L3.8(6). 任务切换很简单,由以下两步完成,将被挂起任务的微处理器寄存器推入堆栈,然后将较高优先级的任务的寄存器值从栈中恢复到寄存器中。在C/OS-中,就绪任务的栈结构总是看起来跟刚刚发生过中断一样,所有微处理器的寄存器都保存在栈中。换句话说,C/OS-运行就绪态的任务所要做的一切,只是恢复所有的CPU寄存器并运行中断返回指令。为了做任务切换,运行OS_TASK_SW(),人为模仿了一次中断。多数微处理器有软中断指令或者陷阱指令TRAP来实现上述操作。中断服务子程序或陷阱处理(Traphardler),也称作事故处理(exceptionhandler),必须提供中断向量给汇编语言函数OSCtxSw()。OSCtxSw()除了需要OS_TCBHighRdy指向即将被挂起的任务,还需要让当前任务控制块OSTCBCur指向即将被挂起的任务。OSSched()的所有代码都属临界段代码。在寻找进入就绪态的优先级最高的任务过程中,为防止中断服务子程序把一个或几个任务的就绪位置位,中断是被关掉的。为缩短切换时间,OSSched()全部代码都可以用汇编语言写。为增加可读性,可移植性和将汇编语言代码最少化,OSSched()是用C写的任务切换的相关函数:与CPU体系相关,汇编完成。1.OSStartHighRdy()执行优先级最高的任务2.OSCtxSw()完成任务的上下文切换3.OSIntCtxSw()中断后的上下文切换4.OSTickISR()中断服务程序启动2.7 UC/OS-II的初始化OSInit()建立空闲任务idletask,这个任务总是处于就绪态的。空闲任务OSTaskIdle()的优先级总是设成最低。这两个任务的任务控制块(OS_TCBs)是用双向链表链接在一起的。OSTCBList指向这个链表的起始处。当建立一个任务时,这个任务总是被放在这个链表的起始处。换句话说,OSTCBList总是指向最后建立的那个任务。链的终点指向空字符NULL(也就是零)。 因为这两个任务都处在就绪态,在就绪任务表OSRdyTbl中的相应位是设为1的。还有,因为这两个任务的相应位是在OSRdyTbl的同一行上,即属同一组,故OSRdyGrp中只有1位是设为1的。 C/OS-还初始化了4个空数据结构缓冲区。每个缓冲区都是单向链表,允许C/OS-从缓冲区中迅速得到或释放一个缓冲区中的元素。控制块OS_TCB的数目也就自动确定了。当然,包括足够的任务控制块分配给统计任务和空闲任务。3 uC/ OS - II 的移植uC/OS - II 的文件系统结构包括核心代码部分、设置代码部分、与处理器相关的移植代码部分. 结构如图3.1所示.其中最上边的软件应用层是uC/ OS - II 上的代码.功能分别是内核管理、事件管理、消息队列管理、存储管理、消息管理、信号量处理、任务调度和定时管理. 设置代码部分包括2个头文件,用来配置事件控制块的数目以及是否包含消息管理相关代码. 而与处理器相关的移植代码部分则是进行移植过程中需要更改的部分,包括1 个头文件OS CPU. H ,1个汇编文件OS CPU A. S 和1个OS CPU.C代码文件.实际上将uC/ OS - II 移植到ARM处理器上,需要完成的工作主要是以下三个与体系结构相关的文件:OS CPU. H ,OS CPU. C 以及OS CPU A. S。图3。1 uC/ OS - II 文件体系结构3.1 OS CPU. H的移植文件OS CPU. H 中包括了用# define语句定义的与处理器相关的常数、宏以及类型. 移植时主要修改的内容有:与编译器相关的数据类型的设定;用#define 语句定义2 个宏开关中断;根据堆栈的方向定义OS STK GROWTH等.在将uC/OS-II移植到ARM 处理器上时,首先进行基本配置和数据类型定义. 重新定义数据类型是为了增加代码的可移植性,因为不同的编译器所提供的同一数据类型的数据长度并不相同,例如int型,在有的编译器中是16位,而在另外一些编译器中则是32位.所以,为了便于移植,需要重新定义数据类型,如INT32U代表无符号32位整型.typedefunsigned int INT8U ,就是定义一个8 位的无符号整型数据类型.其次就是对ARM 处理器相关宏进行定义,如ARM处理器中的退出临界区和进入临界区的宏定义,退出临界区宏定义: #define OS EXIT CRITICAL() ARMDisableInt()/ 关中断,进入临界区宏定义# define OS ENTER CRITICAL() AR2MEnableInt()/ 开中断. 最后就是堆栈增长方向的设定. 当进行函数调用时,入口参数和返回地址一般都会保存在当前任务的堆栈中,编译器的编译选项和由此生成的堆栈指令就会决定堆栈的增长方向,定义为# define OS STK GROWTH 1.740)this.width=740" border=undefined>图3.2 堆栈增长方向3.2 OS CPU. C 的移植OS CPU. C 的移植包括任务堆栈初始化和相应函数的实现.在这里,共有6个函数:OSTaskStkInit(),OSSTaskCreateHook(),OSTaskDelHook(),OS2TaskSwHook(),OSTaskStatHook(),OSTimeTickHook().其中后面的5个HOOK函数又称为钩子函数,主要是用来对uC/OS-II 进行功能扩展.这些函数为用户定义函数,由操作系统调用相应的HOOK函数去执行,在一般情况下,他们都没有代码,所以实现为空函数即可.而函数OSTaskStkInit()对堆栈进行初始化,在ARM系统中,任务堆栈空间由高到低为PC,LR,R12,R11,R1,R0,CPSR,SPSR.在进行堆栈初始化以后,OSTaskStkInit()返回新的堆栈栈顶指针.3.3 OS CPU A. S 的移植OS CPU A. S文件的移植需要对处理器的寄存器进行操作,所以必须用汇编语言来编写. 这个文件的实现集中体现了所要移植到处理器的体系结构和uC/ OS - II 的移植原理.它包括4个子函数:OSStartHighRdy() ,OSCtxSw(),OSIntCtxSw(),OSTick2ISR().其中难点在于OSIntCtxSw()和OSTickISR() 函数的实现,因为这两个函数的实现与移植者的移植思路以及相关硬件定时器、中断寄存器的设置有关.在实际的移植工作中,这两处也是比较容易出错的地方.OSIntCtxSw( )函数由OSIntE

    注意事项

    本文(ARM 嵌入式操作系统移植 论文08852.doc)为本站会员(laozhun)主动上传,三一办公仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三一办公(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    备案号:宁ICP备20000045号-2

    经营许可证:宁B2-20210002

    宁公网安备 64010402000987号

    三一办公
    收起
    展开