μCOS-II操作系统基础及其移植开发初步.DOC

上传人:天*** 文档编号:905304 上传时间:2018-11-05 格式:DOC 页数:13 大小:102.50KB
下载 相关 举报
μCOS-II操作系统基础及其移植开发初步.DOC_第1页
第1页 / 共13页
μCOS-II操作系统基础及其移植开发初步.DOC_第2页
第2页 / 共13页
μCOS-II操作系统基础及其移植开发初步.DOC_第3页
第3页 / 共13页
μCOS-II操作系统基础及其移植开发初步.DOC_第4页
第4页 / 共13页
μCOS-II操作系统基础及其移植开发初步.DOC_第5页
第5页 / 共13页
点击查看更多>>
资源描述

1、第 2 章 可编程控制器的硬件结构11第六章第六章 COS-II 操作系操作系 统统 基基 础础 及其移植开及其移植开发发 初步初步COS-II 内核作为一种代码公开的嵌入式实时操作系统内核非常有特色,在规模不大的代码内实现了抢占式任务调度和多任务间通信等功能,任务调度算法也很有独特。该内核裁剪到最小状态后编译出来只有 8K 左右,全部内核功能(添加 LWIP 网络协议栈等)也就100K 左右,资源消耗非常小。市面上一些 ARM 微处理器片上所带内存就已经足够一个裁剪合适的内核的简单应用,非常方便产品的开发设计。当前,COS-II 是一个基本完整的嵌入式操作系统解决方案套件,包括 C/TCP-

2、IP(IP 网络协议栈) 、C/FS (文件系统) 、C/GUI (图形界面) 、C/USB (USB 驱动) 、C/FL(Flash 加载器)等部件。但是这些部件不是公开代码的。还有一些比较重要的可能在嵌入式环境中发挥重要重要作用的部件,包括嵌入式数据库、POSIX 兼容性接口、常用设备的驱动模块等。将来这个行业还会产生更多的重要部件需求,在互联网上的开源社区通常能够找到相应的开源代码包,并且可以进行移植。6.1 实时操作系统基本原理与技术本节将主要讲述实时操作系统的基本原理和技术,通过对本章的学习读者可以了解掌握 RTOS(Real Time operation System,实时操作系统

3、)的基本特征、结构体系、重要指标、性能参数等重要理论,为全面掌握 RTOS 打下基础。6.1.1 实时操作系统基本特征根据 IEEE 实时 UNIX 分委会对实时操作系统的定义,实时操作系统的基本特征应表现为以下几个方面: 实时性:对外部事件作出反应的时间必须在限定的时间内,在某些情况下还需要是确定的,可重复实现的,不管当时系统内部状态如何,都是可预测的; 异步并发事件响应能力:异步事件是指无一定时序关键随机发生的事件。如外部设备完成数据传输,实时控制设备出现异常情况等。实际环境中,嵌入式实时系统处理的外部事可编程控制器应用技术与设计实例12件往往不是单一的,这些事件往往同时出现,而且发生的时

4、刻也是随机的,即异步的。实时软件应有能力对这类外部事件组有效地进行处理; 抢占式调度:为确保响应时间,实时操作系统必须允许高优先级的任务一旦准备好,马上抢占低优先级任务的执行。 内存锁定:必须具有将程序或部分程序锁定在内存的能力,锁定在内存的程序减少了为获得该程序而访问磁盘的时间,从而保证了快速的响应时间; 快速启动,出错处理和自动复位功能; 优先级中断和调度机制:必须允许客户定义中断优先级和被度任务的优先级并指定如何中断服务; 连续文件存储机制:通常要求数据存储在连续文件上,以减少存取数据时的查找时间; 同步/互斥机制:提供同步和互斥共享数据使用和执行的手段; 应用程序和操作系统两种软件一体

5、化; 需要独立的开发平台。实时操作系统能对来自外界的作用和信号在限定的时间范围内作出响应。它强调的实时性、可靠性和灵活性。它与实时应用软件相结合成为有机整体,起着核心作用。由它来管理和调度各项工作,为应用软件提供良好的运行环境及开发环境。一般说来,实时操作系统提供系统调用来实现对上层实时应用程序的支持,而操作系统是以库的形式来实现这些支持。应用程序通过链接实时操作系统的库来获得实时支持。6.1.2 实时操作系统关键技术指标评价一个实时操作系统一般可以从进程管理、任务调度、内存管理、任务通信、内存开销、任务切换时间和最大中断禁止时间等技术指标来衡量其优劣。 任务调度算法:RTOS 的实时性和多任

6、务能力在很大程度上取决于它的任务调度算法。从调度策略上来讲,可分为优先级调度策略和时间片轮转调度策略;从调度方式上来讲,可分为可抢占式、不可抢占式和选择可抢占式调度方式;从时间片来看,分固定与可变时间片轮转两种方式。常用的调度算法有:Rate Monotonic(发生率单调)、优先级与发生率成正比(LiuLay 1973)、Lottery Scheduler(彩票调度,WaldInitTimer();While(1) /应用程序代码OSTimeDly(1) ; /可选系统会为每一个任务保留一个堆栈空间。由于系统在任务切换时要恢复上下文并执行一条 reti 指令返回,如果允许任务执行到最后一个花

7、括号,那么很可能会破坏系统的堆栈空间,从而使应用程序的执行带有不确定性。换句话说,程序“跑飞”了。所以,每一个任务必须被写成无限循环的形式。不管是系统强制(通过 ISR) ,还是主动放弃(通过调用 OS API) ,开发者都要使自己的任务能够放弃对 CPU 的使用权。现在来讨论 InitTimer()函数。这个函数应由系统提供,开发者需要在优先级最高的任务内调用它且不能在 for 循环内调用。需要注意的是,这个函数是和所使用的 CPU 相关的,每种系统都有自己的 Timer 初始化程序。在 COS-II 的帮助手册内,作者强调绝不能在 OSInit()或 OSStart()内调用用 Timer

8、 初始化程序,那么会破坏系统的可移植性,同时也会带来性能上的损失。所以,一个折中的办法就是如上所述,在优先级最高的任务内调用,这样可保证当 OSStart()调用系统内部函数OSStartHighRdy()开始多任务后,首先执行的是 Timer 初始化程序。或专门执行一个优先级最高的任务,只做一件事情,那就是执行 Timer 初始化;之后通过调用 OSTaskSuppend()将自己挂起,永远不再执行,不过这样会浪费一个 TCB 空间。对于那些 RAM 内存空间有限的系统来说,应该尽量不用。COS-II 是多任务内核,函数可能会被多个任务调用,因此,还须考虑函数的可重入性。由于每个任务有各自的

9、堆栈,而任务的局部变量是放在当前的任务堆栈中的,所以要保证函数代码的可重入性,只要不使用全局变量即可。利用 COS-II 的消息队列可实现消息驱动程序。在编写任务代码时,先完成任务初始化,然后在消息循环过程中,在某个消息上等待,当其他任务或者中断服务程序返回消息后,根据消息的内容调用相应的函数模块,函数调用后,重新回到消息循环,继续等待消息。可编程控制器应用技术与设计实例166.2.3 COS-II API 介绍任何一个操作系统都会提供大量的 API 供开发者使用,COS-II 亦如此。由于 COS-II 面向的是实时嵌入式系统开发,并不要求大而全,所以内核提供的 API 也就大多与多任务相关

10、。注意有以下几类:任务类,消息类,同步类,时间类及临界区与事件类。下面介绍几个比较重要的 API 函数。1. OSTaskCreate()函数该函数应至少在 main()函数内调用一次,在 OSInit()函数调用之后调用,它的作用就是创建一个任务。该函数有 4 个参数,分别是任务的入口函数,任务的参数,任务的堆栈的首地址和任务的优先级。调用该函数,系统会首先从 TCB 空闲队列内申请一个空的 TCB 指针;然后根据用户给出的参数初始化任务堆栈,并在内部的任务就绪表内标记该任务为就绪状态;最后返回。这样一个任务就创建成功了。2. OSTaskSuspend()函数该函数可将指定的任务挂起。如果

11、挂起的是当前任务,那么还会引发系统执行任务切换先导函数 OSShed()来进行一次任务切换。这个函数只是一个指定任务优先级的参数。事实上在系统内部,优先级除了表示一个任务执行的先后次序外,还起着区分每一个任务的作用。换句话说,优先级也就是任务的 ID。所以 COS-II 不允许出现相同优先级的任务。3. OSTaskResume()函数该函数和 OSTaskSuspend()函数正好相反,它用于将指定的已经挂起的函数恢复为就绪状态。如果恢复任务的优先级高于当前任务,那么还将引发一次任务切换。其参数类似于OSTaskSuspend()函数,用来指定任务的优先级。需要特别说明的是,该函数并不要求和

12、OSTaskSuspend()函数成对出现。4. OS_ENTER_CRITICAL()宏由 OS_CPU.H 文件可知,OS_ENTER_CRITICAL()和下面要谈到的OS_EXIT_CRITICAL()都是宏,它们都与特定的 CPU 相关,一般都被替换为一条或者几条嵌入式汇编代码。由于系统希望向上层开发者隐藏内部实现,故一般都宣称执行此条指令后系统进入临界区。其实,该指令只是进行了关中断操作而已。这样,只要任务不主动放弃CPU 使用权,别的任务就没有占用 CPU 的机会了,相对这个任务而言,它就是独占了,所以说进入临界区了。这个宏应尽量少用,因为他会破坏系统的一些服务,尤其是时间服务,

13、并使系统对外界响应性能降低。5. OS_EXIT_CRITICAL()宏该宏与上面 OS_ENTER_CRITICAL()宏配套使用,在退出临界区时使用。其实它就是重新开中断。需要注意的是,它必须和 OS_ENTER_CRITICAL()宏成对出现,否则会带来意想不到的后果。最坏情况下,系统会崩溃。6. OSTimeDly()函数该函数实现的功能是,先挂起当前任务,然后进行任务切换,在指定的时间到了之后,第 2 章 可编程控制器的硬件结构17将当前任务恢复为就绪状态,但并不一定运行;如果恢复后是优先级最高的就绪任务,那么运行之。简而言之,就是可使任务延时一定时间后再次执行它。或者说,暂时放弃

14、CPU 的使用权。一个任务可以不显示地调用这些可导致放弃 CPU 使用权的 API,但那样多任务性能会大大降低,因为此时仅仅依靠时钟机制在进行任务切换。一个好的任务应在完成一些操作后主动放弃 CPU 的使用权。6.2.4 COS-II 多任务实现机制COS-II 是一种基于优先级的可剥夺型多任务内核,了解它的多任务机制原理,有助于写出更加强壮的代码。其实在单 CPU 情况下,是不存在真正多任务机制的,存在的只是不同的任务轮流使用 CPU,所以本质上还是单任务。但由于 CPU 执行速度非常快,加上任务切换十分频繁切换得很快,所以感觉好像有很多任务同时在运行,这就是所谓的多任务机制。由上述内容不难

15、发现,要实现多任务机制,目标 CPU 必须具有一种在运行期间更改 PC的途径,否则无法做到切换。遗憾的是,目前还有那个 CPU 支持直接设置 PC 指针的汇编指令。但一般 CPU 都允许通过类似 JMP 和 CALL 这样的指令来间接修改 PC,主要是软中断。但在一些 CPU 上,并不存在软中断这个概念,所以,在那些 CPU 上,使用几条 PUSH指令加上一条 CALL 指令来模拟一次软中断发生。COS-II 中,每个任务都有一个任务控制块,这是一个复杂的数据结构。在任务控制块偏移为 0 的地方,存储着一个指针,记录了所属任务的专用堆栈地址。事实上,在COS-II 中,每个任务都有自己的专用堆

16、栈,彼此之间不能侵犯,这点要求开发者在他们的程序中保证。一般的做法是,把它们声明成静态数组而且声明成 OS_STK 类型。当任务有了自己的堆栈时,就可将每一个任务堆栈记录到前面提到的任务控制块偏移为 0 的地方。以后每当发生任务切换时,系统必然会先进入一个中断,这一般是通过软中断或者时钟中断实现的。然后会把当前任务的堆栈地址保存起来,接着恢复要切换的任务的堆栈地址。由于那个任务的堆栈里也一定存的是地址(每当发生任务切换时,系统必然会进入一个中断,而一旦中断,CPU 就会把地址压入栈中) ,这样,就达到了修改 PC 为下一个任务的地址的目的。开发者可善加利用 COS-II 的多任务实现机制,写出

17、更健壮更有效率的代码来。6.3 COS-II 在 STM32F103 处理器上的移植6.3.1 移植条件移植 COS-II 到处理器上必须满足以下条件: 处理器的 C 编译器能产生可重入代码COS-II 是多任务内核,函数可能会被多个任务调用,代码的重入性是保证完成多任可编程控制器应用技术与设计实例18务的基础。可重入代码指的是可被多个任务同时调用,而不会破坏数据的一段代码,或者说代码具有在执行过程中打断后再次被调用的能力。下面列举了两个函数例子,它们的区别在于变量 temp 保存的位置不同。Swap1 函数中temp 作为全局变量存在,swap2 函数中 temp 作为函数的局部变量存在,因

18、此 swap1 函数是不可重入的,而 swap2 函数是可重入的。Swap1 函数代码如下,int temp;void swap1(int * x, int * y)temp = *x;*x= *y;*y= temp;Swap2 函数代码如下,void swap(int * x, int * y)int temp;temp= *x;*x=*y;*y= *temp;此外,除了在 C 程序中使用局部变量外,还需要 C 编译器的支持。使用 MDK Realview开发集成环境,可生成可重入的代码。 用 C 语言可打开和关闭中断ARM 处理器核包含一个 CPSR 寄存器,该寄存器包括一个全局的中断禁止

19、位,控制它便可打开和关闭中断。 处理器支持中断并且能产生定时中断COS-II 是通过处理器产生的定时器中断来实现多任务之间的调度的。 ARM7TDMI 的处理器都支持中断并能产生定时器中断。 处理器支持能够容纳一定量数据的硬件堆栈对于一些只有 10 跟地址线的 8 位控制器,芯片最多可访问 1KB 存储单元,在这样的条件下,移植是比较困难的。 处理器有将堆栈指针和其他 CPU 寄存器读出和存储到堆栈(或内存)的指令COS-II 进行任务调度时,会把当前任务的 CPU 寄存器存放到此任务的堆栈中;然后,再从另一个任务的堆栈中恢复原来的工作寄存器,继续运行另一个任务。所以,寄存器的入栈和出栈是 C

20、OS-II 多任务调度的基础。第 2 章 可编程控制器的硬件结构196.3.2 移植步骤所谓移植,就是使一个实时操作系统能够在某个微处理器平台上或微控制器上运行。由 COS-II 的文件系统可知,在移植过程中,用户所需要关注的就是与处理器相关的代码。这部分包括一个头文件 OS_CPU.H,一个汇编文件 OS_CPU_A.ASM 和一个 C 代码文件OS_CPU_C.C。以下介绍当使用 MDK Realview 编译器时,移植 COS-II 的主要内容。 基本的配置和定义所以需要完成的基本配置和定义全部集中在 OS_CPU.H 头文件中。 定义与编译器相关的数据类型为了保证可移植性,程序中没有直

21、接使用 C 语言中的 short,int 和 long 等数据类型的定义,因为它们与处理器类型有关,隐含着不可移植性;而是自己定义了一套数据类型,如INT16U 表示 16 位无符号整型。对于 ARM 这样的 32 位内核,INT16U 是 unsigned short 型;如果是 16 位的处理器,则是 unsighed int 型。在 STM32F103 处理器上实现的数据类型定义代码如下typedef unsigned char BOOLEAN; typedef unsigned char INT8U; typedef signed char INT8S; typedef unsigne

22、d short INT16U; typedef signed short INT16S;typedef unsigned int INT32U; typedef signed int INT32S; typedef float FP32; typedef double FP64; typedef unsigned int OS_STK;typedef unsigned int OS_CPU_SR; 定义允许和禁止中断宏与所有实时内核一样,COS-II 需要先禁止中断,在访问代码的临界区,并且在访问完毕后,重新允许中断。这就使得 COS-II 能够保护临界段代码免受多任务或中断服务历程 ISR

23、的破坏。中断禁止时间是商业实时内核公司提供的重要指标之一,因为它将影响到用户的系统对实时事件的响应能力。虽然 COS-II 尽量使中断禁止时间达到最短,但是COS-II 的中断禁止时间还主要依赖于处理器结构和编译器产生的代码的质量。通常每个处理器都会提供一定的指令来禁止/允许中断,因此用户的 C 编译器必须有一定的机制来直接从 C 中执行这些操作。COS-II 定义了两个宏来禁止和允许中断:OS_ENTER_CRITICAL()和OS_EXIT_CRITIVAL().在 STM32F103 处理器上实现的代码如下,可编程控制器应用技术与设计实例20#define OS_CRITICAL_MET

24、HOD 3#define OS_ENTER_CRITICAL() cpu_sr = OS_CPU_SR_Save();#define OS_EXIT_CRITICAL() OS_CPU_SR_Restore(cpu_sr);其中,OS_CPU_SR_Save()和 OS_CPU_SR_Restore 用汇编语言定义,代码如下,OS_CPU_SR_SaveMRS R0, PRIMASK ; set prio int mask to mask all (except faults)CPSID IBX LROS_CPU_SR_RestoreMSR PRIMASK, R0BX LR 定义栈的增长方向C

25、OS-II 使用结构常量 OS_STK_GROWTH 来指定堆栈的增长方式: 置 OS_STK_GROWTH 为 0,表示堆栈从下往上长; 置 OS_STK_GROWTH 为 1,表示堆栈从上往下长。虽然 ARM 处理器核对两种方式均支持,但 GCC 的 C 语言编译器仅支持一种方式,即从上往下增长,并且是满递减堆栈。所以 OS_STK_GROWTH 的值为 1,它在 OS_CPU.H 中定义。用户规划好的栈的增长方向后,便定义了符合 OS_STK_GROWTH 的值。STM32F103 处理器上实现定义堆栈增长方向的代码如下,#define OS_STK_GROWTH 1 定义 OS_TAS

26、K_SW()宏OS_TASK_SW()宏是 COS-II 从低优先级任务切换到高优先级任务时被调用的。可采用下面两种方式定义:如果处理器支持软中断,则可使用软中断将中断向量指向OSCtxSW()函数,或者直接调用 OSCtxSw()函数。COS-II 在 STM32F103 处理器上实现 OSCtxSw 的代码如下,该段代码由汇编语言实现。OSCtxSwLDR R4, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch)LDR R5, =NVIC_PENDSVSETSTR R5, R4BX LR 移植汇编语言编写的 4 个与处理器相关的函数 OS_CPU_A.ASM OSStartHighRdy():运行优先级最高的就绪任务OSStartHighRdy()函数是在 OSStart()多任务启动之后,负责从最高优先级任务的TCB 控制块中获得该任务的堆栈指针 SP,并通过 SP 依次将 CPU 现场恢复。这是系统就将控制权交给用户创建的任务进程,直到该任务被阻塞或者被其它更高优先级的任务抢占

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 重点行业资料库 > 1

Copyright © 2018-2021 Wenke99.com All rights reserved

工信部备案号浙ICP备20026746号-2  

公安局备案号:浙公网安备33038302330469号

本站为C2C交文档易平台,即用户上传的文档直接卖给下载用户,本站只是网络服务中间平台,所有原创文档下载所得归上传人所有,若您发现上传作品侵犯了您的权利,请立刻联系网站客服并提供证据,平台将在3个工作日内予以改正。