1、基于的实时操作系统基于的实时操作系统 的内核移植的内核移植 摘 要:本文研究了实时操作系统 C/OS-在 ARM 微处理器上的内核移植。首先介绍了实时操作系统 C/OS-和 ARM7 微处理器,在此基础上,分析了内核移植的条件和主要内容,最后对代码移植的正确性进行测试。关键词:ARM;C/OS-;移植 1 引言 嵌入式系统是一个分散的工业,充满了竞争、机遇与创新,没有哪个系列的处理器和操作系统能够垄断全部市场,因此留给各个公司的创新余地很大。研究嵌入式系统,一个必不可少的基础工作就是实现嵌入式操作系统在相关处理器平台上的移植。本文基于目前应用非常广泛的 ARM 处理器体系结构,对C/OS-II
2、 嵌入式实时操作系统内核的移植工作做了分析和介绍,并对代码移植的正确性进行验证。2 C/OS-操作系统简介 C/OS-是一个著名的源代码开放的嵌入式实时操作系统(RTOS),由美国人Jean J.Labrosse 编写出来。C/OS-读作micro controller OS 2,意为微控制器操作系统版本 2。C/OS-结构小巧,适合小型控制系统,具有执行效率高,占用空间小,实时性能优良和可扩展性能强等特点,具有可剥夺实时内核,提供了实时系统所需的基本功能,其中包括任务的调度与管理,时间管理,任务间同步与通信,内存管理和中断服务等功能。C/OS-可用于 8 位、16 位和 32 位单片机或 D
3、SP。良好的持续发展能力、高性能的内核以及友好的用户开发坏境,使其迅速在嵌入式实时操作系统领域占据一席之地。3 ARM7 微处理器简介 ARM(Advanced RISC Machines),是英国 Advanced RISC Machines Limited公司设计开发的通用 32 位 RISC 微处理器体系结构。ARM 处理器因其卓越的性能和显著优点,已成为高性能、低功耗、低成本嵌入式处理器的代名词,成为32 位嵌入式应用领域、全球范围内最广泛使用的处理器。ARM7 系列微处理器采用亚微米制造工艺,是一种低电压、低功耗的 32 位 RISC 处理器,其内核基于ARMV4T(冯诺依曼)体系结
4、构,分为 3 级流水线,最高时钟频率为 66MHz,使用 3V/5V 供电模式,最适合用于对价位和功耗要求较高的消费类应用。ARM7 系列微处理器具有如下特点:具有嵌入式 ICERT 逻辑,调试开发方便;极低的功耗,适合对功耗要求较高的应用,如便携式产品;能够提供 0.9MIPS/MHz 的三级流水线结构;代码密度高并兼容 16 位的 Thumb 指令集;对操作系统的支持广泛,包括 Windows CE、Linux、Palm OS 等;指令系统与 ARM9 系列、ARM9E系列和 ARM10E 系列兼容,便于用户的产品升级换代;主频最高可达 130MIPS,高速的运算处理能力能胜任绝大多数的复
5、杂应用。4 实时操作系统 C/OS-在 ARM 上的内核移植 4.1 移植的条件 处理器的 C 编译器能产生可重入代码;在程序中用 C 语言就可以打开或关闭中断;处理器支持中断,并且能够产生定时中断;处理器能够容纳一定数量的硬件堆栈;处理器有将堆栈指针和其他 CPU 寄存器存储和读出到堆栈(或者内存)的指令。4.2 移植 C/OS-主要包括的内容 重新定义一系列与编译器相关的数据类型。具体定义代码如下:typedef unsigned char BOOLEAN;typedef unsigned char INT8U;/*8 位无符号整数*/typedef signed char INT8S;/
6、*8 位有符号整数*/typedef unsigned short INT16U;/*16 位有符号整数*/typedef signed short INT16S;/*16 位无符号整数*/typedef unsigned long INT32U;/*32 位无符号整数*/typedef signed long INT32S;/*32 位有符号整数*/typedef float FP32;/*单精度浮点数*/typedef double FP64;/*双精度浮点数*/设置一个常量来标识堆栈增长方向。typedef unsigned int OS_STK/*堆栈的单位,堆栈入口宽度为 16 位*
7、/#define OS STK GROWTH 1/*定义堆栈的增长方向,1 表示高地址向低地址增长*/声明用于开关中断和任务切换的宏。具体代码如下:#define OS_ENTER_CRITICAL()ARMEnableInt()/*开启中断*/#define OS_NTER_CRITICAL()ARMDisabIeInt()/*关闭中断*/#define OS_TASK_SW()OSCtxSw()/*任务切换*/用汇编语言编写与处理器相关的函数(OS_CPU.A.ASM)为了方便移植,大部分的 C/OS-代码是用 C 语言写的,但仍需要用 C 和汇编语言写一些与处理器相关的代码,这是因为 C
8、/OS-在读写处理器寄存器时只能通过汇编语言来实现。它包括以下四个子函数:OSStartHighRdy()是运行优先级最高的就绪任务、OSCtxsw()是任务级的任务切换函数、OSIntCtxSw()是中断级的任务切换函数、OSTickISR()是系统时钟节拍中断服务函数 5 用 C 语言编写 6 个与操作系统相关的函数(OS_CPU_C.C)OSTaskInit:OSTaskCreate()和 OSTaskCreateExt()通过调用 OSTaskStkInit()来初始化任务的堆栈结构。在用户建立任务的时候,用户传递任务的地址,pdata 指针,任务的堆栈栈顶和任务的优先级给 OSTas
9、kCreate()和OSTaskCreateExt()。一旦用户初始化了堆栈,OSTaskStkInit()就需要返回堆栈指针所指的地址。OSTaskCreate()和 OSTaskCreateExt()会获得该地址并将它保存到任务控制块(OS_TCB)中。OSTaskCreateHook:当用 OSTaskCreate()和 OSTaskCreateExt()建立任务时就会调用 OSTaskCreateHook()。当 C/OS-设置完自己内部结构以后,会在调用任务调度程序之前调用 OSTaskCreateHook()。当 OSTaskCreateHook()被调用时,会收到指向已建立任务的
10、 OS_TCB 指针,这样可访问所有的结构成员。OSTaskDelHook:当任务被删除时会调用 OSTaskDelHook()。该函数在任务从C/OS-的内部任务链表中解开之前被调用。当它被调用时,会收到指向正被删除任务的 OSJCB 指针,这样可访问所有的结构成员。OSTaskSwHook:当发生任务切换的时候就会调用 OSTaskSwHook()。OSTaskSwHook()可以直接访问 OSTCBCur 和 OSTCBHighRdy,因为它们是全局变量。OSTCBCur 指向被切换出去的任务的 OS_TCB,而 OSTCBHighRdy 指向新任务 OS_TCB。OSTaskStatH
11、ook:OSTaskStatHook()每秒钟都会被 OSTaskStat()调用一次。用户可以用 OSTaskStatHook()来扩展统计功能。OSTimeTickHook:OSTimeTickHook()在每个时钟节拍都会被 OSTaskTick()调用。OSTimeTickHook()是在节拍被 C/OS-真正处理并通知用户的移植实例或应用程序之前被调用的。完成了上述工作以后,C/OS-就可以正常的运行在 ARM 处理器上了 结束语 C/OS-II 作为一个优秀的实时操作系统已经被移植到各种体系结构的微处理器上,而 ARM 体系结构在嵌入式领域也获得了广泛的应用和支持。将 C/OS-II 移植到 ARM 平台上,能够使我们更深入地了解实时操作系统的构造,加快在ARM 平台上的应用和开发,并为更高层次上的扩展和改进打下基础。参考文献 1Jean J,邵贝贝译.Labrosse.嵌入式实时操作系统 C/OS-II.北京 航空航天大学出版社.2003.2田泽.嵌入式系统开发与应用教程.北京:北京航空航天大学出版社,2004.