μC/OS-Ⅱ实时操作系统的移植方法探讨

时间:2022-10-09 10:54:13

μC/OS-Ⅱ实时操作系统的移植方法探讨

摘要:μC/OS-Ⅱ由于其源代码开放、稳定、可靠的特点,在嵌入式开发中得到了广泛应用。该文针对其移植开发,探讨了这一过程中所采用的步骤、一般方法和技巧。

关键词:μC/OS-Ⅱ;嵌入式系统;移植

中图分类号:TP316文献标识码:A文章编号:1009-3044(2008)29-0493-02

Methods on Transplantation of μC/OS-II

XU Jing-feng

(Base Course Department,Nanjing Institute of Politics,Nanjing 210003,China)

Abstract: μC/OS-II has been widely used in the embedded system development for its feature of stability, reliability and open source. This paper focuses on the developing steps and general methods in the transplantation of the real time operating system.

Key words: μC/OS-II; embedded system; transplantation

μC/OS-Ⅱ是一个抢占式的实时多任务操作系统,具有高稳定性和高可靠性,可固化、可剪裁。此外,μC/OS-Ⅱ的一大鲜明特点就是源代码公开,便于移植和维护。在实际的项目开发过程中,可以针对项目所采用的芯片或开发工具,根据自己的需要进行移植。

本文将以在TMS320C6711 DSP上的移植过程为例,具体分析μC/OS-Ⅱ在嵌入式开发平台上进行移植的一般方法和技巧。

1 深入了解所采用的系统核心

在选定了系统平台和开发工具之后,进行μC/OS-Ⅱ的移植时,一定要深入了解系统的核心细节。首先要了解的是中断处理机制,如何开启、屏蔽中断,可否保存前一次中断状态等。其次,芯片是否有软中断或是陷阱指令,又是如何触发的。另外,还需关注系统对于存储器的使用机制,诸如内存的地址空间,堆栈的增长方向,有无批量压栈的指令等。在本例中,使用的是TMS320C6711 DSP。这是TI公司6000系列中的一款浮点型号,由于其时钟频率非常高,且采用了超常指令字(VLIW)结构、类RISC指令集、多级流水等技术,所以运算性能相当强大,在通信设备、图像处理、医疗仪器等方面都有着广泛的应用。

具体到C6711,其中断有3种类型,即复位、不可屏蔽中断(NMI)和可屏蔽中断(INT4-INT15)。可屏蔽中断由CSR寄存器控制全局使能,此外也可用IER寄存器分别置位使能。由于在C6711中没有软中断机制,所以μC/OS-II的任务切换需要编写一个专门的函数实现。此外,由于C6711没有专门的中断返回指令、批量压栈指令,相应的任务切换代码均需编程完成。因为采用了类RISC核心,所以C6711的内核结构中,只有A0-A15和B0-B15这两组32bit的通用寄存器。

2 分析所采用的开发工具的特点

无论使用的系统核心是什么,C语言开发工具对于μC/OS-Ⅱ是必不可少的,在本项目中,我们采用TI的C语言开发工具CCS for C6000。为此,在动手前一定要针对具体的开发工具搞清具体的技术细节,以便方便移植工作。

例如开启C编译器的“汇编代码列表(list)”功能,编译器会为每个C语言源文件生成其对应的汇编代码文件。通过比较C代码与生成的ASM代码,我们可以了解该开发工具对于寄存器、堆栈、中断向量等使用的特点,以便做到心中有数。

3 编写移植代码

在深入了解了系统核心与开发工具的基础上,真正编写移植代码的工作就相对比较简单了。μC/OS-Ⅱ自身的代码绝大部分都是用ANSI C编写的,而且代码的层次结构十分干净利落,与平台相关的移植代码都存在于OS_CPU_A.ASM、OS_CPU_C.C以及OS_CPU.H这三个文件当中。在移植的时候,结合前面两个步骤中已掌握的信息,就可以实施了。

但是,由于系统核心、开发工具的千差万别,在实际项目中,一般都会有一些处理方法上的不同,需要特别注意。以C6711的移植为例:

1) 中断的开启和屏蔽的两个宏定义为:

#define OS_ENTER_CRITICAL() Disable_int()

#define OS_EXIT_CRITICAL() Enable_int()

Disable_int和Enable_int是用汇编语言编写的两个函数。在这里使用了控制状态寄存器(CSR)的一个特性――CSR中除了控制全局中断的GIE位之外,还有一个PGIE位,可用于保存之前的GIE状态。因此在Disable_int中要先将GIE的值写入PGIE,然后再将GIE写0,屏蔽中断。而在Enable_int中则从PGIE读出值,写入GIE,从而回复到之前的中断设置。这样,就可以避免使用这两个宏而意外改变了系统的中断状态。此外,也没有使用堆栈或局部变量,比原作者推荐的方法要好。

2) 任务的切换:

前文说过,C6711中没有软中断机制,所以任务的切换需要用汇编语言自行编写一个函数_OSCtxSw来实现:

#define OS_TASK_SW() OSCtxSw()

在C6711中需要入栈保护的寄存器包括A0-A15、B0-B15、CSR、IER、IRP和AMR,这些再加上当前的程序地址构成一个存储帧,需要入栈保存。

_OSCtxSw函数中,需要像发生了一次中断那样,将上述存储帧入栈,然后获取被激活任务的TCB指针,将其存储帧的内容弹出,从而完成任务切换。需要特别注意的是,在这里OS_TASK_SW是作为函数调用的,所以如前文所述,调用时的当前程序地址是保存在B3寄存器中的,这也就是任务重新激活时的返回地址。

3) 中断的编写:

在CCS中如果用“interrupt”关键字声明函数,在编译时,会自动将该函数中使用到的寄存器进行入栈、出栈保护。但是,这会导致各种中断发生时,出入栈的内容各不相同。这对于μC/OS-II是会引起严重错误的。因为μC/OS-II要求中断发生时的入栈操作使用和发生任务切换时完全一样的存储帧结构。因此,在移植时、基于μC/OS-II进行开发时,都不应当使用“interrupt”关键字,而应用如下结构编写中断函数:

void OSTickISR (void)

{

DSP_C6x_Save(); //服务函数,入栈

OSIntEnter();

if (OSIntNesting==1)

{

OSTCBCur->OSTCBStkPtr=(OS_STK*) DSP_C6x_GetCurrentSP(); //服务函数

} //获取当前SP的值,若允许中断嵌套则在此处开中断

OSTimeTick();

OSIntExit();

DSP_C6x_Resume(); //服务函数,出栈

}

DSP_C6x_Save和DSP_C6x_Resume是两个服务函数,分别完成中断的出、入栈操作。它们与OS_TASK_SW函数的区别在于:中断发生时的当前程序地址是自动保存在IRP寄存器的,应将其作为任务返回地址,而不再是B3。此外,DSP_C6x_Resume是一个永远不会返回的函数,在将所有内容出栈后,它就直接跳转回到中断发生前的程序地址处,继续执行。

4 进行移植的测试

在编写完了所有的移植代码之后,就可以编写几个简单的任务程序进行测试了,大体上可以分三个步骤来进行,相关资料比较详尽,这里就不多作赘述了。

5 针对项目的开发平台,封装服务函数

最后这个步骤,往往是容易被忽视的,但对于保持项目代码的简洁、易维护有很重要的意义。μC/OS-Ⅱ的原作者强烈建议将源代码分路径进行存储。例如本文例子中的所有源代码就应按如下路径结构存储:

\uCOS-II

├─SOURCE //平台无关代码

│OS_CORE.C

│......

├─TI_C6711 //系统核心

├─CCS //开发工具

│OS_CPU.H

│OS_CPU_A.ASM

│OS_CPU_C.C

├─DSP_C6x_Service //服务函数

│DSP_C6x_ Service.H

│DSP_C6x_ Service.ASM

─ TEST //具体的开发项目代码

OS_CFG.H

INCLUDES.H

TEST.C......

如上,DSP_C6x_Service中的服务函数,类似于原作者提供的80x86版本中的PC.C和PC.H文件。在本文的例子中,服务函数则包括了上文提及的中断相关函数,以及系统初始化函数DSP_C6x_SystemInit()和时钟初始化函数DSP_C6x_TimerInit()等。而具体的开发项目代码,则可以分别在“/TI_C6711”路径下新建自己的目录,就如同移植测试的“TEST”项目,而无需再关注μC/OS-Ⅱ的源代码和服务函数。如此,就可以避免不必要的编译错误,也便于开发项目的维护。

参考文献:

[1] 拉伯罗斯.嵌入式实时操作系统μC/OS-Ⅱ[M].2版,邵贝贝,译.北京:北京航空航天大学出版社,2005.

[2] Voss M,Ben Ismail T.Towards a theory for hardware-software codesign[C].Proc of the Int Workshop on Hardware-Software Codesign,1994.

上一篇:工业化与信息化的融合加速计算机应用服务业发... 下一篇:基于ArcGIS Geodatabase实现配电网拓扑分析