μCOS-II在ARM7上的移植

时间:2022-10-26 01:37:53

摘要: 本文介绍了μCOS-II的概况和ARM体系结构中与移植工作相关的一些概念,并在此基础上分析了基于ARM的移植工作。

关键词:μCOS-II嵌入式实时操作系统;ARM;移植

中图分类号:TP311.54文献标识码:A文章编号:1009-3044(2007)05-11316-02

1 引言

随着微电子技术、通信技术的发展,嵌入式系统设计及其应用在后PC时代对人类生活产生了巨大的影响。随着网络技术的发展,嵌入式技术必将继续改变人们未来的生活方式。在嵌入式研发中,一个重要的基础工作就是实现嵌入式实时操作系统在相关处理器平台上的移植。本文基于目前国内应用非常广泛的ARM处理器体系结构,对μCOS-II嵌入式实时操作系统内核的移植作出分析和介绍,并在LPC2210处理器上得到了实现。

2 μCOS-II概述

1992年,美国人Jean J. Labrosse编写了实时多任务内核μCOS,μCOS-II是基于μCOS的,二者的内核一样,只是μCOS-II提供了更多的功能。经过10多年的发展,μCOS已经被移植到包括x86、ARM、PowerPC、MIPS等40多种处理器架构上,移植上的处理器还在不断增加。自1992年以来已经有数百个商业应用。另外,2000年7月,μCOS-II在一个航空项目中得到了美国联邦航空管理局的认证,该认证表明μCOS-II具有足够的安全性和稳定性,能够用于与人性命攸关的、安全性条件极为苛刻的系统。

3 ARM体系结构编程

ARM是精简指令集计算机(RSCI),其设计实现了外形非常小但是性能高的结构。ARM处理器结构简单使ARM的内核非常小,这样使器件的功耗也非常低。下面主要介绍ARM7中与μCOS-II迁移有关的知识。

3.1 处理器状态

当ARM微处理器执行32位的ARM指令集时,工作在ARM状态;当ARM微处理器执行16位的Thumb指令集时,工作在Thumb状态。在程序的执行过程中,微处理器可以随时在两种工作状态之间切换,并且,处理器工作状态的转变不影响处理器的工作模式和相应寄存器中的内容。为了最大限度地支持芯片的特性,任务应当可以使用任意一个指令集并可自由切换,而且不同的任何应当可以使用不同的指令集,移植的代码已经实现了这一点。

3.2 处理器模式

ARM体系结构支持7种处理器模式:用户模式、快速中断模式、外部中断模式、管理模式、数据访问终止模式、系统模式和未定义指令终止模式。除用户模式外,其余的所有6种模式称之为非用户模式,或特权模式。ARM内部寄存器和一些片内外设在硬件设计上只允许(或可选为)特权模式下访问。此外,特权模式可以自由地切换处理器模式,而用户模式不能直接切换到别的模式。

除了用户模式和系统模式外的5种处理器模式称为异常模式,它们是快速中断模式、外部中断模式、管理模式、数据访问终止模式和未定义指令终止模式。它们除了可以通过程序切换进入外,也可以由特定的异常进入。当特定的异常出现时,处理器进入相应的模式。每种模式都有某些附加的寄存器,以避免异常退出时,用户模式的状态不可靠。

至于系统模式除了它是特权模式外,其他与用户模式一样,因而可选的给μCOS-II任务使用的模式只有用户模式和系统模式。为了尽量减少任务代码错误对整个系统的影响,缺省的任务模式定义未用户模式,可选为系统模式,同时提供接口,使任务可以在这两种模式之间切换。

3.3 寄存器组织

ARM微处理器共有37个32位的寄存器,其中31个为通用寄存器,6个为状态寄存器。但是这些寄存器不能被同时访问,具体哪些寄存器是可编程访问的,取决于微处理器的工作状态及具体的运行模式。但在任何时候,通用寄存器R14R0、程序计数器PC、一个或两个状态寄存器都是可访问的。表1所示为ARM状态下,各模式可访问的寄存器。

表1 ARM状态各模式下的寄存器

4 μCOS-II的移植

μCOS-II中要移植的部分见表1-3所示。根据μCOS-II的要求,移植μCOS-II到一个新的体系机构上需要提供2个或3个文件:OS_CPU.H(C语言头文件)、OS_CPU_C.C(C程序源文件)及OS_CPU_A.ASM(汇编程序源文件)。其中OS_CPU_A.ASM在某些情况下不需要,及其罕见。不需要OS_CPU_A.ASM的必须满足以下苛刻条件:

(1)可以直接使用C语言开关中断;

(2)可以直接使用C语言编写中断服务程序;

(3)可以直接使用C语言操作堆栈指针;

(4)可以直接使用C语言保存CPU的所有寄存器。

同时支持以上4点的C语言编译器几乎不存在,即使存在,移植代码往往也会使用部分汇编语言来提高移植代码的效率。由表2可以看出,移植μCOS-II需要在OS_CPU.H包含几个类型的定义和几个常数的定义;在OS_CPU_C.C 和OS_CPU_A.ASM中包含几个函数的定义和时钟节拍中断服务程序的代码。实际上,还有一个includes.h文件需要关注,因为每一个应用都包含独特的includes.h文件。

表2 μCOS-II需要移植的代码

根据Jean J. Labrosse对μCOS-II移植的要求,本移植也包括OS_CUP.h、OS_CPU_C.c和OS_CPU_A.s三个文件。将OS_CUP_A.asm更名为OS_CPU_A.s是遵照ADS 编译器的惯例。实际上,还有一个文件很重要,就是IRQ.inc,它定义了一个汇编宏,是μCOS-II为ARM7通用的中断服务程序的汇编与函数接口代码。时钟节拍中断服务程序也没有移植,因为其与芯片和应用都强烈相关,需要用户自己编写,不过可以通过IRQ.S简化用户代码的编写。

4.1 编写OS_CUP.h

4.1.1 数据类型定义

数据类型的修改与所使用的编译器相关,不同的编译器使用不同的字节长度表示同一数据类型,比如int,同样在x86平台,GNU的gcc编译器为4bytes,而MS VC++则为2byte。根据ADS编译器的要求,这些代码定义如下:

4.1.2 使用软件中断SWI作底层接口

为了使底层接口函数与处理器状态无关,同时在任务调用相应的函数不需要知道函数的位置,本移植使用软件中断指令SWI作为底层接口,使用不同的功能号区分不同的函数。软件中断功能号如表3所示:

表3 软件中断功能

用软件中断作为操作系统的底层接口就需要在C语言中使用SWI指令。在ADS中,有一个关键字__swi,用它声明一个不存在的函数,则调用这个函数就在调用这个函数的地方插入一条SWI指令,并且可以制定功能号。同时,这个函数也可以有参数和返回值,其传递规则与一般函数一样,其代码如下:

4.1.3 定义堆栈增长方向

虽然ARM处理器可以支持堆栈向上增长,也可以支持堆栈向下增长,但是ADS的C语言编译器仅支持一种方式,即从上往下增长。所以定义如下:

#define OS_STK_GROWTH 1

4.2 编写OS_CPU_C.c文件

本文件要求编写10个简单的C函数:

唯一必要的函数是OSTaskStkInit(),其他9个函数必须声明,但是并不一定要包含任何代码。

4.2.1 OSTaskStkInit()

该函数初始化任务的堆栈,而任务的堆栈结构跟CPU的体系机构、编译器有密切关系。本移植的堆栈结构如图1所示。根据图示,很容易写出OSTaskStkInit()的代码,如程序清单1-2。

程序清单1-2 函数OSTaskStkInt()代码

4.2.2 软件中断异样SWI服务程序C语言部分软件中断的C语言处理函数代码比较简单,函数原型为void SWI_Exception(int SWI_Num,int *regs);参数SWI_Num为功能号,而Regs为指向堆栈中保存寄存器的值的位置。程序通过一个switch语句把各个功能分割开,各个功能相对对立。

OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()

μCOS-II使用宏OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()分别关中断和开中断。在ARM处理器核中关中断和开中断时,通过改变程序状态寄存器CPSR中的相应位来实现。3. OSStartHighRdy μCOS-II的启动多任务环境的函数是OSStart(),用户在调用OSStart()之前,必须已经建立了一个或更多任务。OSStart()最终调用函数OSStartHighRdy()运行多任务启动前优先级最高的任务,OSStartHighRdy()的代码如下:

程序清单1-3 OSStartHighRdy()的代码

void OSStartHighRdy(void){

_OSStartHighRdy();}

4.3 编写OS_CPU_A.S

4.3.1 软件中断的汇编接口

该接口即实现了中断功能号0、1,同时也把C语言中断联系起来。代码如程序清单1-4所示:

程序清单1-4 软件中断的汇编部分

4.3.2 OSCtxSw()

任务级的上下文切换,当任务被阻塞而主动请求CPU调度时被执行,由于此时的任务切换在非异常模式下进行,因此有别于中断级别的任务切换。它的工作是先将当前的任务的CPU现场保存到该任务堆栈中。然后获得最高优先级任务的堆栈指针,从该堆栈中恢复此任务的CPU现场,使之继续执行。这样就完成一次任务的切换。

4.3.3 OSIntCtxSw()

中断级的任务切换,在时钟中断ISR中发现有高优先级任务等待时钟信号的到来,则在中断退出后并不是返回被中断的任务,而是直接调度就绪的高优先级任务执行。从而能够尽快让高优先级的任务得到响应,保证系统的实时性能。其基本原理于任务的切换相同。但是由于进入中断时已经保存了被中断的CPU现场,因此不用做类似的操作,只需对堆栈指针做相应调整。

4.3.4 时钟中断服务程序

其主要任务是处理时钟中断。示例代码如下:

void ISR(void)

{OS_ENTER_CRITICAL();

清除中断源;

通知中断控制器中断结束;

OS_EXIT_CRITICAL();

用户处理代码;}

4.4 结束

μCOS-II作为一个优秀的实时操作系统已经被移植到许多体系结构的处理器上,而ARM体系结构在嵌入式领域的应用越来越广泛。将μCOS-II移植到ARM平台,不仅可以加深对实时系统的理解,同时也是进行产品开发的重要基础。

参考文献:

[1]邵贝贝译.嵌入式实时操作系统μC/OS-II[M].

[2]周立功编.ARM微控制器基础与实践[M].

[3]ARM公司.ARM Developer Suite version1.2 Developer Guide.

本文中所涉及到的图表、注解、公式等内容请以PDF格式阅读原文。

上一篇:基于XML的电子病历信息集成的研究 下一篇:基于Web数据库的考务管理平台方案