论文部分内容阅读
摘要:嵌入式操作系统的移植是设计开发的重要一环,文章从全局和细节上分别研究了UCOS-II移植过程中的技术要点,并着重从移植后代码的可靠性、健壮性和通用性等方面进行了研究。
关键词:嵌入式;操作系统移植;UCOS
中图分类号:TP316文献标识码:A文章编号:1006-8937(2012)05-0068-01
由于基于ARM7内核的各种芯片之间有着很大的差异,这些差异主要表现在存储系统不同、片内外设不同、中断源不同等。这就造成了嵌入式操作系统移植的不可避免性,而嵌入式操作系统移植效果的优劣直接影响着目标系统的整体质量。文中采用LPC2000系列ARM7微控制器以及ADS编译器对UCOS-II的移植过程进行了测试研究。
1UC/OS-II的移植步骤
UC/OS-II是一个占先式的实时多任务内核,由ANSI C语言编写,包含小部分汇编代码供不同架构的处理器使用,能够管理64个任务,主要系统功能包括:内存块管理、任务管理、消息队列管理、信号量、互斥信号量、事件标志组、消息邮箱等。从移植UCOS-II的过程来看,逻辑上可分作三大组成部分:与处理器无关的内核代码、与处理器有关的核心代码、与软硬件环境设置有关的配置代码。其中与处理器无关的内核代码主要包括OS_CORE.C、OS_FLAG.C、OS_MBOX.C、OS_MEM.C、OS_MUTEX.C、OS_Q.C、OS_SEM.C、OS_TASK.C、OS_TIME.C、UCOS_II.C、UCOS_II.H,它们主要实现任务管理、信号量、内存管理、消息队列、系统调度等功能;与处理器有关的核心代码主要包括OS_CPU.H、OS_CPU_A.ASM、OS_CPU_C.C,它们主要与操作系统的移植相关;与软硬件环境设置有关的配置代码主要包括OS_CFG.H、INCLUDES.H,它们主要用于剪裁和设置操作系统。以上文件名为UCOS-II的默认设置,无须严格按照上述名称命名文件。
由UCOS-II的逻辑结构可以看出,其移植工作主要集中在与处理器有关的核心代码部分。实际测试中遵循了如下步骤。第一,对OS_CPU.H进行移植,这部分工作主要包括:首先定义与处理器有关的数据类型,如BOOLEAN、INT8U、INT8S等;其次进行与处理器有关的宏定义主要包括OS_ENTER_CRITICAL以及OS_EXIT_CRITICAL;再次编写软中断函数主要包括OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()。第二,对OS_CPU_A.ASM进行移植,依据ADS编译器扩展名规则将文件名改为OS_CPU_A.S,主要工作是编写4个汇编语言函数,名称为OSStartHighRdy()、OSCtxSw()、OSIntCtxSw()、OSTickISR()。USOS-II启动时调用OSStart(),而OSStart()又调用OSStartHighRdy()运行优先级最高的任务。第三,移植OS_CPU.H。在OS_CPU_C.C文件中,需要编写以下10个C函数,名称分别为OSTaskStkInit()、OSTaskCreateHook()、OSTaskDelHook()、OSTaskSwHook()、OSTaskIdleHook()、OSTaskStatHook()、OSTaskTickHook()、OSInitHookBegin()、OSInitHookEnd()、OSTCBInitHook()。任务堆栈初始化函数OSTaskStkInit的定义按照移植时规定的堆栈结构进行,其他九个函数按照设计要求编写,或者为空。
2UCOS-II移植的技术要点
2.1数据类型的处理
在C语言中常用的int、short等数据类型与处理器类型密切相关,这就意味着采用上述类型定义后的程序本身具有不可移植性,为此在代码编写中需要采用移植性强的数据类型进行替换,因此这些数据类型定义也便成了代码移植工作的一部分,当然依编译器的选择不同也会略有差异,在ADS编译器中部分相关参考代码如下:
typedef unsigned char BOOLEAN;
typedef unsigned char INT8U;
typedef signed char INT8S;
typedef unsigned short INT16U;
typedef signed short INT16S;
typedef unsigned int INT32U;
typedef signed int INT32S;
2.2任务与函数调用的封装
ARM7内核具有7中工作模式,带T后缀的具有两套指令集,在提升处理器功能和效率的同时也带来了复杂性。在移植过程中应设法编制接口函数将底层复杂性与操作系统层的管理和应用隔离开,为了达到这个目的可以采用软件终端SWI(software interruption),而且在ADS编译器中也提供了相应的支持,即__swi关键字。采用该关键字声明一个莫须有的函数,调用时则在该处插入SWI指令,且可以设定中断功能编号,以及完成参数传递等。比如:
__swi(0x00) void OS_TASK_SW(void)/*任务切换函数*/
__swi(0x00) void _ OSStartHighRdy(void) /*运行顶级优先任务*/
__swi(0x00) void _ OS_ENTER_CRITICAL (void) /*关中*/
__swi(0x00)void_OS_EXIT_CRITICAL(void)/*开中*/
2.3中断服务的切换
如果在OS_CPU.H做过相应的声明,采用OS_TASK_SW函数切换任务,则函数OSCtxSw是可以省略的,所以通常情况下OSCtxSw并不是移植初期需要关注的要点。前文提到基于ARM7的不同芯片之间的中断系统存在差异,这就要求移植后的操作系统要保证目标机的中断系统稳定运行保障系统的可靠性。而在中断服务程序中切换任务时需要调用函数OSIntCtxSw,因此OS_CPU_A.S的移植要点在与保证OSIntCtxSw准确性,其代码主要任务包括保护现场、将当前任务堆栈指针保存到对应的任务控制块TCB(task control block)、获取新任务的堆栈指针等。OS_CPU_A.S中的__ OSStartHighRdy()与之存在调用关系,OSStartHighRdy()须在OS_CPU_C.C中定义。部分相关代码如下:
OSIntCtxSw_OSHR
获取新任务堆栈指针
LDR R4,[R6]
ADD SP,R4,#68;
LDR LR,[SP, #-8]
MSR CPSR_c,#(NoInt|SVC32Mode);切换至管理模式
MOV SP,R4;设置堆栈指针
LDMFD SP!,{R4, R5};CPSR,关中次数
恢复新任务的关中计数器
LDR R3,=IECounter;为关中计数器分配寄存器
STR R4,[R3]
MSR SPSR_cxsf,R5;恢复CPSR
LDMFD SP!,{R0-R12, LR, PC }^;运行新任务
关中计数器为全局变量,不同的任务由各自的关中计数器,在任务切换时分别堆栈互不影响,从而隔离了任务切换时可能造成的相互影响。
3结语
嵌入式操作系统的移植往往是影响全局且复杂性较强的工作。这类系统的移植也必然要建立在移植者对整体软硬件系统有深入准确的掌握基础之上。文中针对UCOS-II结合ARM7内核处理器以及ADS编译器测试并总结了移植的步骤和部分技术要点,此类工作需要丰富的实践和理论研究才能日臻完善。文中所论有很多不足之处和不全面的地方,需要在日后的实践中不断更正总结。
参考文献:
[1] 武国平,史仪凯.ARM7处理器Bootloader的设计与实现[J].
微处理机,2010,(5).
[2] 周立功.ARM嵌入式系统基础教程[M].北京:北京航空航
天大学出版社,2006.
[3] 宁杰城,王春,周新志.ARM7内核上的uC/OS—II嵌入式系
统移植[J].中国测试技术,2005,(2).
关键词:嵌入式;操作系统移植;UCOS
中图分类号:TP316文献标识码:A文章编号:1006-8937(2012)05-0068-01
由于基于ARM7内核的各种芯片之间有着很大的差异,这些差异主要表现在存储系统不同、片内外设不同、中断源不同等。这就造成了嵌入式操作系统移植的不可避免性,而嵌入式操作系统移植效果的优劣直接影响着目标系统的整体质量。文中采用LPC2000系列ARM7微控制器以及ADS编译器对UCOS-II的移植过程进行了测试研究。
1UC/OS-II的移植步骤
UC/OS-II是一个占先式的实时多任务内核,由ANSI C语言编写,包含小部分汇编代码供不同架构的处理器使用,能够管理64个任务,主要系统功能包括:内存块管理、任务管理、消息队列管理、信号量、互斥信号量、事件标志组、消息邮箱等。从移植UCOS-II的过程来看,逻辑上可分作三大组成部分:与处理器无关的内核代码、与处理器有关的核心代码、与软硬件环境设置有关的配置代码。其中与处理器无关的内核代码主要包括OS_CORE.C、OS_FLAG.C、OS_MBOX.C、OS_MEM.C、OS_MUTEX.C、OS_Q.C、OS_SEM.C、OS_TASK.C、OS_TIME.C、UCOS_II.C、UCOS_II.H,它们主要实现任务管理、信号量、内存管理、消息队列、系统调度等功能;与处理器有关的核心代码主要包括OS_CPU.H、OS_CPU_A.ASM、OS_CPU_C.C,它们主要与操作系统的移植相关;与软硬件环境设置有关的配置代码主要包括OS_CFG.H、INCLUDES.H,它们主要用于剪裁和设置操作系统。以上文件名为UCOS-II的默认设置,无须严格按照上述名称命名文件。
由UCOS-II的逻辑结构可以看出,其移植工作主要集中在与处理器有关的核心代码部分。实际测试中遵循了如下步骤。第一,对OS_CPU.H进行移植,这部分工作主要包括:首先定义与处理器有关的数据类型,如BOOLEAN、INT8U、INT8S等;其次进行与处理器有关的宏定义主要包括OS_ENTER_CRITICAL以及OS_EXIT_CRITICAL;再次编写软中断函数主要包括OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()。第二,对OS_CPU_A.ASM进行移植,依据ADS编译器扩展名规则将文件名改为OS_CPU_A.S,主要工作是编写4个汇编语言函数,名称为OSStartHighRdy()、OSCtxSw()、OSIntCtxSw()、OSTickISR()。USOS-II启动时调用OSStart(),而OSStart()又调用OSStartHighRdy()运行优先级最高的任务。第三,移植OS_CPU.H。在OS_CPU_C.C文件中,需要编写以下10个C函数,名称分别为OSTaskStkInit()、OSTaskCreateHook()、OSTaskDelHook()、OSTaskSwHook()、OSTaskIdleHook()、OSTaskStatHook()、OSTaskTickHook()、OSInitHookBegin()、OSInitHookEnd()、OSTCBInitHook()。任务堆栈初始化函数OSTaskStkInit的定义按照移植时规定的堆栈结构进行,其他九个函数按照设计要求编写,或者为空。
2UCOS-II移植的技术要点
2.1数据类型的处理
在C语言中常用的int、short等数据类型与处理器类型密切相关,这就意味着采用上述类型定义后的程序本身具有不可移植性,为此在代码编写中需要采用移植性强的数据类型进行替换,因此这些数据类型定义也便成了代码移植工作的一部分,当然依编译器的选择不同也会略有差异,在ADS编译器中部分相关参考代码如下:
typedef unsigned char BOOLEAN;
typedef unsigned char INT8U;
typedef signed char INT8S;
typedef unsigned short INT16U;
typedef signed short INT16S;
typedef unsigned int INT32U;
typedef signed int INT32S;
2.2任务与函数调用的封装
ARM7内核具有7中工作模式,带T后缀的具有两套指令集,在提升处理器功能和效率的同时也带来了复杂性。在移植过程中应设法编制接口函数将底层复杂性与操作系统层的管理和应用隔离开,为了达到这个目的可以采用软件终端SWI(software interruption),而且在ADS编译器中也提供了相应的支持,即__swi关键字。采用该关键字声明一个莫须有的函数,调用时则在该处插入SWI指令,且可以设定中断功能编号,以及完成参数传递等。比如:
__swi(0x00) void OS_TASK_SW(void)/*任务切换函数*/
__swi(0x00) void _ OSStartHighRdy(void) /*运行顶级优先任务*/
__swi(0x00) void _ OS_ENTER_CRITICAL (void) /*关中*/
__swi(0x00)void_OS_EXIT_CRITICAL(void)/*开中*/
2.3中断服务的切换
如果在OS_CPU.H做过相应的声明,采用OS_TASK_SW函数切换任务,则函数OSCtxSw是可以省略的,所以通常情况下OSCtxSw并不是移植初期需要关注的要点。前文提到基于ARM7的不同芯片之间的中断系统存在差异,这就要求移植后的操作系统要保证目标机的中断系统稳定运行保障系统的可靠性。而在中断服务程序中切换任务时需要调用函数OSIntCtxSw,因此OS_CPU_A.S的移植要点在与保证OSIntCtxSw准确性,其代码主要任务包括保护现场、将当前任务堆栈指针保存到对应的任务控制块TCB(task control block)、获取新任务的堆栈指针等。OS_CPU_A.S中的__ OSStartHighRdy()与之存在调用关系,OSStartHighRdy()须在OS_CPU_C.C中定义。部分相关代码如下:
OSIntCtxSw_OSHR
获取新任务堆栈指针
LDR R4,[R6]
ADD SP,R4,#68;
LDR LR,[SP, #-8]
MSR CPSR_c,#(NoInt|SVC32Mode);切换至管理模式
MOV SP,R4;设置堆栈指针
LDMFD SP!,{R4, R5};CPSR,关中次数
恢复新任务的关中计数器
LDR R3,=IECounter;为关中计数器分配寄存器
STR R4,[R3]
MSR SPSR_cxsf,R5;恢复CPSR
LDMFD SP!,{R0-R12, LR, PC }^;运行新任务
关中计数器为全局变量,不同的任务由各自的关中计数器,在任务切换时分别堆栈互不影响,从而隔离了任务切换时可能造成的相互影响。
3结语
嵌入式操作系统的移植往往是影响全局且复杂性较强的工作。这类系统的移植也必然要建立在移植者对整体软硬件系统有深入准确的掌握基础之上。文中针对UCOS-II结合ARM7内核处理器以及ADS编译器测试并总结了移植的步骤和部分技术要点,此类工作需要丰富的实践和理论研究才能日臻完善。文中所论有很多不足之处和不全面的地方,需要在日后的实践中不断更正总结。
参考文献:
[1] 武国平,史仪凯.ARM7处理器Bootloader的设计与实现[J].
微处理机,2010,(5).
[2] 周立功.ARM嵌入式系统基础教程[M].北京:北京航空航
天大学出版社,2006.
[3] 宁杰城,王春,周新志.ARM7内核上的uC/OS—II嵌入式系
统移植[J].中国测试技术,2005,(2).