1、C-OS II 在 NiosII 软核处理器上的移植姓名: 学号: 班级: 电信 0803 关键字: C/OS-II Nios 嵌入式实时操作系统 引 言C/OS-II 是一种源代码公开、结构小巧、具有可剥夺实时内核的实时操作系统。 其内核提供任务调度与管理、时间管理、任务间同步与通信、内存管理和中断服务等功能。C/OS-II 适合于小型控制系统,具有执行效率高、占用空间小、实时性能优良和可扩展性强等特点,加之它稳定、可靠,现已被广泛应用在航空、医疗器械、工业控制等领域。Nios 嵌入式处理器是 Altera 公司推出的一个 32/16 位精简指令集软核处理器。在 Altera 公司推出的软件
2、 SOPC中加载 Nios 核和相应的外围接口以及各种自定义指令,利用 FPGA 设计软件进行综合,下载到 FPGA 中就可以方便地实现一个具有特定功能的嵌入式处理器。 这种设计思路增加了系统设计的灵活性, 可以大大缩短产品研发和上市的时间。C/OS-II 和 Nios 相结合,可以构成一种基于可配置的软核处理器的嵌入式开发平台,该平台软、硬件均可按照用户需求进行剪裁配置, 最大程度地提供了系统设计的灵活性,具有重要的应用价值。1 C/OS-II 简介C/OS-II 并非一个完整的实时操作系统,它只是一个基于优先级的抢占式实时内核。 在很多其它实时操作系统中,程序开发人员利用操作系统提供的 A
3、PI 函数进行应用程序的开发,而 C/OS-II 则有所不同。要想在C/OS-II 内核上进行应用程序的开发,需要程序开发人员在实时内核的基础上建立自己的实时操作系统。 和其它嵌入式操作系统一样,C/OS-II 也不具有通用性,用户要在目标处理器上创建一个多任务的实时嵌入式系统,首先要将操作系统移植到目标处理器上,然后在移植好的操作系统平台上开发应用系统。2 C/OS-II 的移植所谓移植,就是使 C/OS-II 实时内核能够在其它的微处理器或微控制器上运行。在移植时,要从硬件和软件两方面进行考虑。硬件方面主要考虑目标处理器。虽然 C/OS-II 大部分源代码是用 C 语言编写, 但是完成和处
4、理器有关的一些操作时, 还是必须用汇编语言来实现的。 寄存器的读、 写只能通过汇编语言的存储和加载指令来实现。 要使 C/OS-II 能够正常工作,目标处理器必须满足以下要求:处理器的 C 编译器能产生可重入代码;用 C 语言可以开、关中断;处理器支持中断,并且能够产生定时中断(通常在10100Hz 之间 );处理器能够支持容纳一定量数据的硬件堆栈;处理器有将堆栈指针和其它寄存器读出和存储到堆栈或内存中的指令。软件方面主要分为四个部分:实时操作系统内核、与处理器相关部分、与应用相关部分以及用户应用系统。下面将结合 Nios 的移植过程进行具体阐述。3 Nios 处理器Nios 嵌入式处理器是
5、Altera 公司推出的一个用户可配置的 16 位或 32 位精简指令集软核处理器。Nios 处理器可以配置成最多支持 64 个中断,包括外部硬件中断、内部中断以及 TRAP(调试中断)。Nios 处理器可以配置使用 32 位内部定时器,通过用软件控制写入几个控制寄存器的内容来获得定时工作, 与一般的定时器工作原理相同,可以产生定时中断。Nios 处理器可以外接存储 80 2004.9学习园地 LEARNING GARDEN器,以使用的 APEX20KE 开发板为例,外接了 512KB 的SRAM 资源,可以提供足够的数据硬件堆栈。 Nios 处理器有自己的汇编语言指令集, 可以完成各种算术和
6、逻辑运算、数据传送、流程控制以及按位操作。Nios SDKshell 采用 GNU 编译器,支持 C/C+的编译、连接,可以产生重入代码,允许在 C 语言中嵌入汇编语言。由以上分析可知,Nios 处理器完全满足 C/OS-II 移植的处理器要求。更为有意义的是,Nios 属于软核可配置处理器,允许用户根据需要进行剪裁和配置。 相对于其它硬核处理器而言,Nios 从硬件方面增加了系统的灵活性。图 1 给出了一个 32 位 Nios 处理器的配置实例,命名为 Nioscpu,后续的 C/OS-II 移植工作就在 Nioscpu上面进行。硬件设备采用的是 Alte ra 公司的 APEX20KENi
7、os 开发板,FPGA 设计软件为 QuartusII3.0,Nios 版本为 3.10。Nioscpu 系统中包括内部 ROM、外部扩展的 SRAM、Flash、串行通信口 UART、内部定时器、外设接口 7 段数码管、发光二极管以及按键开关等。4 移植工作C/OS-II 移植的软件部分需要完成以下几个部分工作。4.1 与编译器有关的代码在不同的处理器中有不同的字长, 所以必须定义一系列数据类型以确保移植的正确性。在 C/OS-II 中,不使用 C 的 short、int 和 lon g 等数据类型,这些都是和编译器相关的。在 Nios 处理器中,各种数据类型定义如下。typedef uns
8、igned char BOOLEAN;typedef unsigned char INT8U; /*无符号 8 位整数 */typedef signed char INT8S; /*有符号 8 位整数*/typedef unsigned short INT16U; /*无符号 16 位整数*/typedef signed short INT16S; /*有符号 16 位整数*/typedef unsigned long INT32U; /*无符号 32 位整数*/typedef signed long INT32S; /*有符号 32 位整数*/typedef float FP32; /*单精
9、度浮点数*/typedef doubleFP64; /*双精度浮点数*/C/OS-II 需要先禁止中断访问代码的临界区,并且在访问完毕后重新允许中断。C/OS-II 定义了两个宏OS_ENTER_CRITICAL()和 OS_EXIT_CRITICAL()来禁止和允许中断。此外,还需要定义堆栈增长方向以及系统软中断。对于 Nios 处理器,允许在 C 语言中嵌入汇编语言,实现方法如下。#define OS_ENTER_CRITICAL() asm( “PFX 8 n WRCTL %g0;” )/*关中断*/#define OS_EXIT_CRITICAL() asm( “PFX 9 n WRC
10、TL %g0;” )/*开中断*/#define OS_STK_GROWTH 1 /* 堆栈增长方向由高到低 */#define OS_TASK_SW() asm( “TRAP 21” );/* 系统软中断定义 */4.2 4 个汇编语言函数这部分需要对处理器的寄存器进行操作, 所以必须用汇编语言来编写。C/OS-II 的移植要求用户编写 4 个简单的汇编语言函数:OSSt artHighRdy(),OSCt xSw(),OSIntCt xSw(),OSTickISR()。OSStartHighRdy()在多任务系统启动函数 OSSta rt()中调用。 主要功能是将就绪表中最高优先级任务的栈
11、指针加载到 SP 中,并强制中断返回。这样就绪的最高优先级任务就如同从中断处理返回到运行态一样, 使得整个系统得以运转。OSCtxSw()在任务级任务切换函数中调用。 任务级的切换问题是通过发软中断命令或依靠处理器执行陷阱指令来完成的,而 ISR 的向量地址必须指向 OSCtxSw()。OSIn tCtxSw()通过调用 OSIn tCtxSw()来从 ISR 中执行切换功能。具体完成的任务是调整堆栈指针,保存当前任务的 SP,载入就绪最高优先级任务的 SP,恢复就绪最高优先级任务的环境变量,中断返回,从而完成中断级任务切换。OSTickISR()是系统时钟节拍中断服务函数。这是一图 1 32
12、 位 Nios 处理器配置实例 81 Mi crocont rol lers & Emb edded Systems 2004.9学习园地 LEARNING GARDEN个周期性中断,为内核提供时钟节拍,频率越高系统负荷越重。 其周期的大小决定了内核所能给应用系统提供的最小时间间隔服务,一般只限于 ms 级,对于要求更加苛刻的任务需要用户自己建立中断来解决。有关 4 个函数具体功能更详细的阐述,请参考文献1。由于 Nios 支持 C 语言中嵌入汇编,也可以将这 4 个函数的定义放入 O S _ C P U _ C . C 中,从而省去了OS_CPU_A.S 文件。4.3 6 个与操作系统有关的
13、函数这 6 个函数是:OSTaskStkInit()、OSTaskCreatHook()、OSTaskDelHook()、OSTaskSwHook() 、OSTaskStatHook()和OSTaskTickHook()。在 6 个函数中只需对 OSTaskStkInit()编写代码,后 5 个函数必须声明, 但是内部可以没有代码。OSTa s kCr e a t e ( )和 OSTa skCre a t eExt ( )通过调用OSTaskSt kInit()来初始化任务的堆栈结构, 使得建立好的进入就绪态任务的堆栈与系统发生中断并将环境变量保存完毕时的栈结构一致, 从而可以利用中断返回指
14、令使就绪的任务运转起来。Nios 处理器的堆栈方向是地址由高到低的。4.4 与应用相关的代码这部分是用户根据自己的应用系统来定制合适的内核服务功能,包括两个文件:OS_CFG.H 和 INCLUDES.H。OS_CFG.H 用来配置内核,用户根据需要对内核进行定制,设置系统的基本情况;INCLUDES.H 为系统头文件, 包括了整个实时系统所需要的内核以及用户的头文件。5 内核测试做完以上工作后,需要对移植的内核进行测试。测试一个 C/OS-II 实时内核并不复杂,就是让这个实时内核在自己的目标板上跑起来。开始时,可以运行一些简单的任务和时钟节拍中断任务, 如果调试成功就可以在上面添加应用程序
15、。下面在 Altera 公司的 APEX20KE Nios开发板上对移植工作进行测试。A PE X2 0 KE Ni o s 开发板上的 FP GA 芯片为APEX20KE200EFC484-2X。该开发板还提供了 FPGA 配置芯片、调试串口、LED 及 7 段数码管等其它外设。首先将上面剪裁好的 Nioscpu 进行综合后下载到 FPGA 芯片中去,然后编写测试程序,在 Nios SDK she ll 环境下对整个内核的文件以及用户文件进行编译, 最后生成可执行文件并下载到开发板上运行。测试程序创建了 3 个任务 A、B、C,优先级分别为10、20、30。任务 A 每 1s 显示 1 次“
16、1111”,任务 B 每 2s显示一次“2222”,任务 C 为计数显示,每 4 秒显示一次,计数值从 0 开始每次加 1。图 2 给出了程序运行结果。初始化过程任务 A、B、C 各显示一次,在接下去的过程中,显示 2 次 A 后显示 1 次 B,显示 4 次 A 和 2 次 B 后显示 1 次 C,结果显然正确。图 2 测试程序运行结果至此,C/OS-II 内核已经成功移植到了 Nios 处理器上,一个基于 Nios 嵌入式处理器和 C/OS-II 嵌入式实时内核的平台已经搭建成功。由于 Nios 和 C/OS-II 都允许用户按照需求进行配置, 这一平台提供了最大的灵活性, 用户可以非常方便地在这样的平台上进行各种应用程序地开发。6 结 论本文在介绍了 C/OS-II 实时操作系统和 Nios 嵌入式处理器的基础上,重点阐述 C/OS-II 在 Nios 上进行移植的过程,最后使用 Nios 开发板对移植进行了测试。