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

上传人:小小飞 文档编号:26384 上传时间:2018-10-29 格式:DOC 页数:31 大小:382.51KB
返回 下载 相关 举报
ARM 嵌入式操作系统移植 论文27927.doc_第1页
第1页 / 共31页
ARM 嵌入式操作系统移植 论文27927.doc_第2页
第2页 / 共31页
ARM 嵌入式操作系统移植 论文27927.doc_第3页
第3页 / 共31页
ARM 嵌入式操作系统移植 论文27927.doc_第4页
第4页 / 共31页
ARM 嵌入式操作系统移植 论文27927.doc_第5页
第5页 / 共31页
点击查看更多>>
资源描述

《ARM 嵌入式操作系统移植 论文27927.doc》由会员分享,可在线阅读,更多相关《ARM 嵌入式操作系统移植 论文27927.doc(31页珍藏版)》请在三一文库上搜索。

1、ARM 嵌入式操作系统移植 摘 要 随 着 ARM 技 术 的 广 泛 应 用 , 建 立 基于 ARM 构架的嵌入式操作系统已成为当前研究 的热点。本课题的研究内容就是利用移植技术将 uC/ OS - II 移植到 ARM 系统。将 uC/ OS - II 移植到 ARM 系统之后,可以充分结合两者的优势。 uC/OS - II 的文件系统结构 包括核心代码部分、设置代码部分、与处理器相关的移植代码部分。核心代码部分包括 7 个源代码文件和 1 个头文件 . 功能分别是内核管理、事件管理、消息队列管理、存储管 理、消息管理、信号量处理、任务调度和定时管理. 设置代码部分包括 2 个头文件,用

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 Abstract Along with the extensive application of ARM t

3、echnology 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 s

4、ystem 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 ma

5、nagement, 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

6、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

7、operating system porting uc/os-II 目 录 引 言 1 1 UC /OS- II 简介 .2 1.1 UC /OS- II 的工作流程 .2 1.2 UC /OS- II 的体系结构 .3 1.3 UC/OS-II 工作原理 4 2 UC/OS 内核调度 .5 2.1 UC/OS-II 内核结构 5 2.2 任务控制块(OS_TCB) .6 2.3 就绪表(READYLIST) .7 2.4 任务状态 .8 2.5 任务转换 .10 2.6 任务调度分析 .10 2.7 UC/OS-II 的初始化 12 3 UC/ OS - II 的移植 13 3.1 OS C

8、PU. H 的移植 13 3.2 OS CPU. C 的移植 14 3.3 OS CPU A. S 的移植 14 3.4 硬件平台 .15 4 在嵌入式系统上的实现 17 4.1 开/关中断的实现 .17 4.2 OSSTARTHIGHRDY 的实现 .18 4.3 任务级上下文切换的实现 .18 4.4 中断级上下文切换的实现 .19 5 多任务应用程序 21 结 束 语 23 参 考 文 献 24 致 谢 25 附录 26 引 言 在开发嵌入式系统时,一般选择基于 ARM 和 uC/ OS - II 的嵌入式开发平台,因为 ARM 微处理器具有处理速度快、超低功耗、价格低廉、应用前景广泛等

9、优点. 将 uC/ OS - II 移植到 ARM 系统之后,可以充分结合两者的优势. 如果一个程序在一个环境里能工 作,我们经常希望能将它移植到另一个编译系统、处理器或者操作系统上,这就是移植技 术.移植技术可以使一种特定的技术在更加广泛的范围使用,使软件使用更加灵活,不局限 于某一条件.uC/OS - II 是由 Jean J. Labrosse 先生编写的完整的可移植、固化、裁剪 的占先式实时多任务内核.uC/ OS - II 的源代码完全开放,这是其他商业实时内核无法 比拟的. 它是针对嵌入式应用设计的,在设计之初就充分考虑了可移植性,它的大部分源 代码都是用高可移植性的 ANSIC

10、编写的.与硬件相关部分用汇编语言编写, 使之 可供不 同构架的微处理器使用。只要有标准的 AN SI C 交叉编译器, 有汇编器、链接器等软件 工具, 就可以将 C /OS- II 嵌入到开发的产品中。 uC/ OS - II 可以移植到从 8 位到 64 位的不同类型、不同规模的嵌入式系统,并能在大部分的 8 位、16 位、32 位、甚至 64 位的微处理器和 DSP 上运行 . 由于 uC/ OS - II 是一个实时操作系统,所以如果将它嵌入 到 ARM 处理器上,就能够进一步简化 ARM 系统的开发。 uC /OS- II 是面向中小型嵌入式系统, 具有执行效 率高、占用空间小、实时性

11、能优 良和可扩展性强等特 点, 包含全部功能模块的内核大约为 10kB。如果经过 裁减只保留 核心代码, 则可压缩到 3kB 左右。严格地 说, uC /OS- II 只是一个实时操作系统内核, 它仅仅包 含了任务调度、任务管理、时间管理、内存管理和任务 间的通信和同步等基 本功能, 没有提供输入输出管理、文件系统、网络等额外的服务。 嵌入式技术发展至今已经进入到了嵌入式 Internet 的阶段,越来越多的嵌入式设备 实现了通过以太网技术接入互联网。将嵌入式设备接入以太网的关键是在嵌入式设备上 实现嵌入式 TCP/IP 协议。相比普通的 TCP/IP 协议,嵌入式 TCP/IP 协议具有代码

12、精简、 很好的可裁减性和很强的移植性等特点。嵌入式系统是先进的计算机技术、半导体技术、 电子技术、和各个行业的具体应用相结合的产物,它是以计算机应用为中心、以计算机 技术为基础,软硬件可裁减的专用计算机系统。在嵌入式系统中使用操作系统(嵌入式 操作系统)已是大势所趋,目前嵌入式操作系统的种类繁多,但 uc/os-II 以其源代码开 放、价格便宜、可移植性强等特点,被广泛使用。 1 uC /OS- II简介 C/OS-II 是一种可移植的,可植入 ROM 的,可裁剪的,抢占式的,实时多任务操作 系统内核。它被广泛应用于微处理器、微控制器和数字信号处理器。 C/OS-II 的前身是 C/OS,最早

13、出自于 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 具有执行效率高、占用空间小、实时性能

14、优良和可扩展性强等特点, 最小内核可编译至 2KB 。C/OS-II 已经移植到了几乎所有知名的 CPU 上。 严格地说 uC/OS-II 只是一个实时操作系统内核,它仅仅包含了任务调度,任务管理, 时间管理,内存管理和任务间的通信和同步等基本功能。没有提供输入输出管理,文件 系统,网络等额外的服务。但由于 uC/OS-II 良好的可扩展性和源码开放,这些非必须的 功能完全可以由用户自己根据需要分别实现。 uC/OS-II 目标是实现一个基于优先级调度的抢占式的实时内核,并在这个内核之上提供 最基本的系统服务,如信号量,邮箱,消息队列,内存管理,中断管理等。 1.1 uC /OS- II的工作

15、流程 uC /OS- II 的工作流程如图 1.1 所示: 首先进行操作系统初始化, 主要完成任务控 制块 ( TCB )初始化; 然后就可以开始创建新任务、初始化任务堆栈区; 最后调用 OSSTART( )函数 , 启动多任务调度。在多任务调度开 始后, 启动时钟节拍源开始计时。 此节拍源为系统提 供周期性的时钟中断信号、实现延时和超时确认。当 时钟中断来临 时, 系统把当前正在执行的任务挂起, 保护现场, 进行中断处理, 判断有无任务延时到 期。若 有, 则使该任务进入就绪态, 并对所有进入就绪态的任 务的优先级进行比较, 通过任务切换去执行最高优先 级的任务。若没有别的任务进入就绪态,

16、则恢复现场 继 续执行原任务。另一种调度方式是任务级的调度, 即通过发软中断命令或依靠处理器在 任务执行中调 度。如任务要等待信号量或一个正在执行的任务被挂 起时, 就需要在此 任务中调度, 找出目前处于就绪态的 优先级最高的任务去执行。当没有任何任务进入就 绪 态时, 就去执行空任务。 图 1.1 uC /OS- II 的工作流程图 1.2 uC /OS- II的体系结构 对 uC /OS - II 的移植实际上就是对 与处理器有关的代码进行重写或修改。移植工 作包括 以下几部分内容:用# define 设置 1 个常量的值 ( OS _CPU. H 文件中 );声明 10 个数据类型 (

17、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 定义的与处

18、理器相 关的常量和类型定义, 与 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 在正常运行时

19、任务间的切换,即对当前任务堆栈的保存 和对高优先级任务堆栈的弹出, 使最高优先级任务获取 CPU 的控制权。 (3) OSIntCtxSw( )是在中断服务程序中执行任务切换。 (4) OSTickISR( )是系统时钟的中断服务程序,该程序执行频率为 10 100 H z, 主 要功能是检查是否有由于延时而被挂起的任务成为就绪任务。如果有,就调用 OSIntCtxSw( )进行任务切换,从而运行高优先级的任务;因为 uC /OS- II 在每一个节拍 都要检查有没有更高优先级的任务在等待执行,若有,就要进行任务切换。所以,时钟节拍 率越高,系统的额外负荷就越重 OS_CPU.C 中要求编写

20、6 个与操作系统相关的函数: OSTaskStkInit( ), OSTaskCreateHook( ),OSTaskDelHook( ), OSTaskStatHook( ) 及 OSTmieTickHook( )。其中,唯一必须移植的是任务堆栈 初始化函 OSTaskStkInit( ),这 个函数在任务创建时被调用,负责初始化任务的堆栈结构并返回新堆栈的指针。 1.3 uC/OS-II工作原理 uC/OS-II 是一种基于优先级的可抢先的硬实时内核。 在 uC/OS-II 里,每个任务都有一个任务控制块(Task Control Block),这是一个比较 复杂的数据结构。在任务控制块的

21、偏移为 0 的地方,存储着一个指针,它记录了所属任务 的专用堆栈地址。 在 uC/OS-II 内,每个任务都有自己的专用堆栈,彼此之间不能侵犯。这点要求程序员 再他们的程序中保证。一般的做法是把他们申明成静态数组。而且要申明成 OS_STK 类型。 当任务有了自己的堆栈,那么就可以将每一个任务堆栈在那里记录到前面谈到的任务 控制快偏移为 0 的地方。 以后每当发生任务切换,系统必然会先进入一个中断,这一般是通过软中断或者时钟 中断实现。然后系统会先把当前任务的堆栈地址保存起来,仅接着恢复要切换的任务的堆 栈地址。由于哪个任务的堆栈里一定也存的是地址(还记得我们前面说过的,每当发生任 务切换,系

22、统必然会先进入一个中断,而一旦中断 CPU 就会把地址压入堆栈),这样,就达 到了修改 PC 为下一个任务的地址的目的。 2 uC/OS内核调度 在多任务系统中,内核是负责管理各个任务,或者说是为每个任务分配 CPU 时间, 同时负责任务之间的通讯。内核所提供的基本服务是任务切换。之所以使用实时内核可 以大大简化应用系统的设计,是因为实时内核允许将应用分成若干个任务,由实时内核 来管理它们。内核本身也增加了应用程序的额外负荷,代码空间增加 ROM 的用量,内核 本身的数据结构增加了 RAM 的用量。但更主要的是,每个任务要有自己的栈空间,这一 块吃起内存来是相当厉害的。内核本身对 CPU 的占

23、用时间一般在 2 到 5 个百分点之间。 UC/OS-II 内核调度特点: 1.只支持基于优先级的抢占式调度算法,不支持时间片轮训; 2.64 个优先级,只能创建 64 个任务,用户只能创建 56 个任务; 3.每个任务优先级都不相同; 4.不支持优先级逆转; 5.READY 队列通过内存映射表实现快速查询。效率非常高; 6.支持时钟节拍; 7.支持信号量,消息队列,事件控制块,事件标志组,消息邮箱任务通讯机制; 8.支持中断嵌套,中断嵌套层数可达 255 层,中断使用当前任务的堆栈保存上下文; 9.每个任务有自己的堆栈,堆栈大小用户自己设定; 10.支持动态修改任务优先级; 11.任务 TC

24、B 为静态数组,建立任务只是从中获得一个 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

25、-II 提供的系统服务进行通信,以 配合实现应用系统的功能。上图中应用代码部分主要是设计人员设计的业务代码。 基于 uC/OS-II 操作系统进行应用系统时,设计任务的主要任务是将系统合理划分成 多个任务,并由 RTOS 进行调度,任务之间使用 uC/OS-II 提供的系统服务进行通信,以 配合实现应用系统的功能。上图中应用代码部分主要是设计人员设计的业务代码。 与前后台系统一样,基于 uC/OS-II 的多任务系统也有一个 main 主函数,main 函数 由编译器所带的 C 启动程序调用。在 main 主函数中主要实现 uC/OS-II 的初始化 OSInit()、 任务创建、一些任务通信

26、方法的创建、uC/OS-II 的多任务启动 OSStart()等常规操作。 另外,还有一些应用程序相关的初始化操作,例如:硬件初始化、数据结构初始化等。 在使用 uC/OS-II 提供的任何功能之前,必须先调用 OSInit()函数进行初始化。在 main 主函数中调用 OSStart()启动多任务之前,至少要先建立一个任务。否则应用程序会崩溃。 OSInit()初始化 uC/OS-II 所有的变量和数据结构,并建立空闲任务 OS_TaskIdle(), 这个任务总是处于就绪态。 2.2任务控制块(OS_TCB) 任务控制块(TCB)是一个数据结构 OS_TCB,一旦一个任务创建,就有一个和它

27、关联 应用软件 (用户代码) uC/OS-II 内核文件 (与处理器类型无关的代码) OS_CORE.C OS_TASK.C OS_FLAG.C OS_TIME.C OS_MBOX.C uCOS-II.C OS_MEM.C uCOS-II.H OS_MUTEX.C OS_SEM.C OS_Q.C uC/OS-II 配置文件 (与应用程序有关) OS_CFG.H INCLUDES.H 移植 uC/OS-II (与处理器类型有关的代码) OS_CPU.H OS_CPU_C.C OS_CPU_A.ASM CPU 定时器 图 2.1 uC/OS-II 的文件结构 软件 硬件 的 TCB 被赋值。当任务

28、的 CPU 使用权被剥夺时,它用来保存该任务的状态。这样,当任 务重新获得 CPU 使用权时,可以从 TCB 中获取任务切换前的信息,准确的继续运行。 任务控制块包含了许多任务信息,主要有: .OSTCBStkPtr 指向当前任务堆栈栈顶的指针。uC/OS-II 允许每个任务有自己的堆栈, 每个任务堆栈的大小可以不一样。 .OSTCBNext 和.OSTCBPrev 指向 OS_TCB 双向链表的前、后连接。 .OSTCBEventPtr 指向事件控制块的指针; .OSTCBDly 保存任务的延时节拍数,或允许等待事件发生的最多节拍数。 .OSTCBPrio 任务的优先级; 文件 OS_CFG

29、.H 中定义的最多任务数 OS_MAX_TASKS 决定了分配给用户程序的任务控 制块的数目。所有的任务控制块都放在任务控制块数组 OSTCBTbl 中。uC/OS-II 初始 化时,所有 OS_TCB 都被链接成单向空任务链表。任务一旦建立,就将链表开头的 OS_TCB 赋给该任务。一旦任务被删除,OS_TCB 就还给空任务链表。任务建立时,函数 OS_TCBInit()初始化任务控制块。 2.3 就绪表(ReadyList) UC/OS-II 采用内存映射的方式来实现 READY 队列的加入,查找,删除功能,效率非 常高。但是也因此只能支持 64 个任务,每个任务都有自己的优先级,不能和其

30、他任务优 先级向同。 每个任务的就绪态标志都放入就绪表中的,就绪表中有两个变量 OSRdyGrp 和 OSRdyTbl.在 OSRdyGrp 中,任务按优先级分组,8 个任务为一组。OSRdyGrp 中的每一 位表示 8 组任务中每一组中是否有进入就绪态的任务。任务进入就绪态时,就绪表 OSRdyTbl中的相应元素的相应位也置位。就绪表 OSRdyTbl数组的大小取决于 OS_LOWEST_PRIO(见文件 OS_CFG.H) 。 为确定下次该哪个优先级的任务运行了,内核调度器总是将 OS_LOWEST_PRIO 在就绪 表中相应字节的相应位置是按以下规则给出的: 当 OSRdyTbli中的任

31、何一位是 1 时,OSRdyGrp 的第 i 位置 1.i 从 0 到 7.使任务进 入就绪态 OSRdyGrp|=OSMapTblprio3; OSRdyTblprio3|=OSMapTblprio 任务优先级的低三位用于确定任务在总就绪表 OSRdyTbl中的所在位。接下去的三 位用于确定是在 OSRdyTbl数组的第几个元素。OSMapTbl是在 ROM 中的(见文件 OS_CORE.C)屏蔽字,用于限制 OSRdyTbl数组的元素下标在 0 到 7 之间,如果一个任务 被删除了,则用程序清单 3.6 中的代码做求反处理。 程序清单 L3.6 从就绪表中删除一个任务 if(OSRdyTb

32、lprio3 以上代码将就绪任务表数组 OSRdyTbl中相应元素的相应位清零,而对于 OSRdyGrp,只 有当被删除任务所在任务组中全组任务一个都没有进入就绪态时,才将相应位清零。也 就是说 OSRdyTblprio3所有的位都是零时,OSRdyGrp 的相应位才清零。为了找到那 个进入就绪态的优先级最高的任务,并不需要从 OSRdyTbl0开始扫描整个就绪任务表, 只需要查另外一张表,即优先级判定表 OSUnMapTbl。OSRdyTbl中每个字节的 8 位代表 这一组的 8 个任务哪些进入就绪态了,低位的优先级高于高位。利用这个字节为下标来 查 OSUnMapTbl 这张表,返回的字节

33、就是该组任务中就绪态任务中优先级最高的那个任务 所在的位置。这个返回值在 0 到 7 之间。确定进入就绪态的优先级最高的任务是用以下 代码完成的。 找出进入就绪态的优先级最高的任务 y=OSUnMapTblOSRdyGrp; x=OSUnMapTblOSRdyTbly; prio=(y 图 3.2 堆栈增长方向 3.2 OS CPU. C 的移植 OS CPU. C 的移植包括任务堆栈初始化和相应函数的实现.在这里,共有 6 个函数: OSTaskStkInit(),OSSTaskCreateHook(),OSTaskDelHook(),OS2TaskSwHook(),OSTaskSta tH

34、ook(),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 文件的移植需要对处理器的寄存器进

35、行操作,所以必须用汇编语言来编 写. 这个文件的实现集中体现了所要移植到处理器的体系结构和 uC/ OS - II 的移植原 理.它包括 4 个子函数:OSStartHighRdy() ,OSCtxSw(),OSIntCtxSw(),OSTick2ISR().其 中难点在于 OSIntCtxSw()和 OSTickISR() 函数的实现,因为这两个函数的实现与移植者 的移植思路以及相关硬件定时器、中断寄存器的设置有关.在实际的移植工作中,这两处 也是比较容易出错的地方. OSIntCtxSw( )函数由 OSIntExit( )函数调用,而 OSIntExit () 函数又由 OSTickIS

36、R() 调用. OSIntCtxSw()函数最重要的作用就是它完成在中断 ISR 中直接进行 任务切换,从而提高了实时响应的速度. 它发生的时机是在 ISR 执行到 OSIntExit()时, 如果发现有高优先级的任务因为等待 time tick 的到来获得了执行等:uC/ OS - II 在 ARM 系统上的移植与实现的条件,就可以马上被调度执行,而不用返回被中断的那个任务之 后再进行任务切换.实现 OSIntCtxSw()的方法大致也有两种情况:一是通过调整 SP 堆栈指 针的方法,根据所用的编译器对于函数嵌套的处理,通过精确计算出所需要调整的 SP 位置 来使得进入中断时所作的保护现场的

37、工作可以被重用.二是设置需要切换标志位的方法, 在 OSIntCtxSw()里面不发生切换,而是设置一个需要切换的标志,等函数嵌套从进入 OSIntExit()=OS ENTER CRITI2CAL()=OSIntCtxSw()=OS EXIT CRITICAL()=OSIntExit ()退出后,再根据标志位来判断是否需要进行中断级的任务切换. 其次是对 OSTickISR()修改.OSTickISR()首先在被中断任务堆栈中保存 CPU 寄存器的 值,然后调 OSIntEnter().随后调用 OSTimeTick(),检查所有处于延时等待状态的任务,判 断是否有延时结束就绪的任务.最后调

38、用 OSIntExit().如果在中断中(或其他嵌套的中断) 有更高优先级的任务就绪,并且当前中断为中断嵌套的最后一层,OSIntExit()将进行任务 调度.如果进行了任务调度,OSIntExit()将不再返回调用者,而是用新任务的堆栈中的寄 存器数值恢复 CPU 现场,然后实现任务切换.如果当前中断不是中断嵌套的最后一层,或中 断中没有改变任务的就绪状态, OSIntExit()将返回调用者 OSTickISR(),OSTickISR()返 回被中断的任务.最后就是退出临界区和进入临界区函数.进入临界区时,必须关闭中断, ARMDisableInt()函数实现.在退出临界区的时候恢复原来的

39、中断状态,通过 ARMEnableInt()函数来实现.至于进行任务级上下文切换,则是由汇编子程序 OSCtxSw 实 现. 3.4 硬件平台 研发人员在构建系统选择硬件时,当缺乏完整或精确的信息时,就成为复杂且困难 的工作。硬件成本是一个主要考虑的内容。当考虑成本时,我们需要考虑产品的整个成 本,而不仅是 cpu 的成本。因为好的 cpu 一旦加上总线逻辑和延时电路,并使之与外设 一起工作,那么这个硬件系统可能会变成非常昂贵的产品。如果你正在寻找嵌入式软件 系统,那么应首先确定硬件平台,即确定微处理器 cpu 的型号。 AT89S51 是一个低功耗,高性能 CMOS 8 位单片机,片内含 4

40、k Bytes ISP(In-system programmable)的可反复擦写 1000 次的 Flash 只读程序存储器,器件采用 ATMEL 公司的 高密度、非易失性存储技术制造,兼容标准 MCS-51 指令系统及 80C51 引脚结构,芯片内 集成了通用 8 位中央处理器和 ISP Flash 存储单元, AT89S51 在众多嵌入式控制应用系统 中得到广泛应用。 主要性能特点有: 1、4k Bytes Flash 片内程序存储器; 2、128 bytes 的随机存取数据存储器(RAM) ; 3、32 个外部双向输入/输出(I/O)口; 4、5 个中断优先级、2 层中断嵌套中断; 5

41、、6 个中断源; 6、2 个 16 位可编程定时器/计数器; 7、2 个全双工串行通信口; 8、看门狗(WDT)电路; 9、片内振荡器和时钟电路; 10、与 MCS-51 兼容; 11、全静态工作:0Hz-33MHz; 12、三级程序存储器保密锁定; 13、可编程串行通道; 14、低功耗的闲置和掉电模式。 图 3.3 PDIP 封装的 AT89S51 管脚图 4 在嵌入式系统上的实现 C/OS-II 的移植条件是:只要该处理器有堆栈,有 CPU 内部寄存器入栈、出栈指令; 使用的 C 编译器支持内嵌汇编(inline assembly)或者该 C 语言可扩展,可连接汇编 模块,使得关中断、开中

42、断能在 C 语言程序中实现。MC9328MX1 符合其移植条件。uC/OS- II 的移植集中在 3 个文件,os_cpu.h,os_cup_a.s, os_cpu_c.c。其中 os_cpu.h 主要包 含编译器相关的数据类型的定义、堆栈类型的定义以及几个宏定义和函数说明。而 os_cpu_c.c 中则包含与移植有关的 C 函数,包括堆栈 的初始化函数和一些钩子(hook) 函数的实现。os_cpu_a.s 中则包含与移植有关的汇编语言函数,包括开/关中断、上下 文切换、时钟中断服务程序等。移植中关键的功能模块实现如下文所述。 4.1 开/关中断的实现 uC/OS-II 和其它所有的实时内核

43、一样,在访问操作系统的临界区之前必须关闭中 断,访问之后开中断。这可以保证 uC/OS-II 的临界区代码不会被多个任务或中断服务 程序同时访问,避免造成共享数据(uC/OS-II 的全局变量)的不一致性。开/关中断有3 种实现方法,最简单的方法是仅用该内核提供的关中断指令实现宏 ENTER_CRITICAL_SECTION(), 仅用开中断指令实现宏 EXIT_CRITICAL_SECTION()。这种 方法可以减少中断延迟时间,但它可能存在一点小问题,就是如果程序在调用 ENTER_CRITICAL_SECTION()之前,中断已经被禁止,那么在调用 EXIT_CRITICAL_SECTO

44、IN()之后,中断被允许,这可能不是程序所期望的。这种简单的实 现方法对某些情况不适用。 在大部分情况下,第1种实现方法可以满足应用的要求,用以下的汇编子程序可以实 现关中断: EnterCritical STMFD SP!,R0, LR MRS R0, CPSR ORR R0, R0, #I_BIT:OR:F_BIT MSR CPSR_c, R0 LDMFD SP!, R0, PC 用类似的方法可以实现开中断。 4.2 OSStartHighRdy 的实现 操作系统初始化后,开始执行系统内第 1 个最高优先级的任务。对于第 1 个执行的 任务,不需要进行上下文保存,只需恢复任务上下文即可。第

45、 1 个任务的执行是通过调 用汇编子程序 OSStartHighRd 实现的。此子程序首先调用钩子函数 OSTaskSwHook(),完 成用户扩展的操作系统功能,然后将 OSRunning 的值置为真,表示开始任务的执行,从 而保证任务切换操作的正确执行。紧接着从具有最高优先级的任务控制块中取得任务的 堆栈指针,初始化堆栈指针寄存器 SP。然后恢复 CPSR,恢复其它的寄存器,开始执行最 高优先级的任务。 程序如下: OSStartHighRdy; Call OSTaskSwHook() BL OSTaskSwHook Set OSRunning to TRUE MOV R0,#1 LDR

46、R1,=OSRunning STRB R0,R1 Get stack ptr for task to resume LDR R1,=OSTCBHighRdy LDR R1,R1 LDR SP,R1,#0 ; OSTCBStkPtr is at +0 Restore saved context Save current task context STMFD SP!, R14; Save task PC STMFD SP!, R0-R12, R14 ; Save LR and other registers MRS R0, CPSR; Save current CPSR STMFD SP!, R0

47、 CmnCtxSw; Store stack ptr of task (lives in OSTCBCur-OSTCBStkPtr) LDR R1,=OSTCBCur LDR R1,R1 STR SP,R1,#0; OSTCBStkPtr is at +0; Call user definable OSTaskSwHook() BL OSTaskSwHook; Set current task to new task LDR R2,=OSTCBHighRdy LDR R3,=OSTCBCur LDR R4,=OSPrioHighRdy LDR R5,=OSPrioCur LDR R0,R2 L

48、DRB R1,R4 STR R0,R3 STRB R1,R5; Get stack ptr for task to resume (lives in OSTCBHighRdy-OSTCBStkPtr) LDR SP,R0,#0; OSTCBStkPtr is at +0; Restore saved context Switch to IRQ mode with IRQ disabled ADD SP, SP, #4*15 ; Adjust stack pointer of IRQ mode MOV R12, SP; Save the SP to transfer it to SYS mode

49、 MSR CPSR_c, #ARM_MODE_SYS:OR:I_BIT ; Switch to SYS mode with IRQ disabled ADD SP, SP, #8; Adjust stack because of stacking of OSIntExit LDMFD SP!, R14; Pop LR_SYS LDMDB R12!, R0; R12 contains the initial address of system mode STMFD SP!, R0 ; Store return address PC STMFD SP!, R14; Store LR_SYS MOV R14, R12 ; Transfer stack pointer of IRQ LDMDB R14!, R0-R12 STMFD SP!, R0-R12 ; Store R0-R12 LDMDB R14!, R0 STMFD SP!, R0 ; Store SPSR B CmnCtxSw 5 多任务应用程序 实时多任务操作系统(RTOS)是嵌入式应

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 其他


经营许可证编号:宁ICP备18001539号-1