嵌入式实时操作系统μC/OS-II 在MPC5604B 上的移植①

2012-07-09 01:58罗先银吴光强
关键词:堆栈微控制器调用

罗先银, 吴光强

(同济大学汽车学院,上海201804)

随着人们对汽车安全性、环保、节能和舒适性要求的提高,汽车电子技术应用日益广泛.作为汽车电子控制系统的核心,微控制器已经由最初的4位微控制器发展到现在的32位微控制器.半导体技术的发展使得电子控制系统集成度、控制精度提高的同时也降低了成本.MPC56xx系列微控制器是Freescale半导体公司针对日益复杂的汽车电子控制系统推出的基于Power Architecture○R架构的下一代32位微控制器,使用90nm COMS技术制造,具有低成本、低功耗、高性能和高稳定性的优点[1,2].

面对日益复杂的控制系统软件,传统的前后台系统已经不能满足控制系统对多任务和实时性等多方面的要求.相比前后台系统,嵌入式实时内核具有明确的时序,在处理对时间要求苛刻的应用时具有更大的优势,支持多任务处理,同时使得应用程序的设计与开发变得更加容易,提高了开发效率[3,4].相对于市面上其它的实时系统,μC/OS - II具有可移植性、可裁剪、抢占式、高稳定性与高可靠性等诸多优点.

本文结合MPC5604B的特点,对移植过程中设计到的任务切换及堆栈的保存与恢复等核心问题进行了分析,成功的移植了μC/OS-II实时操作系统.

1 MPC5604B与xPC560B评估板

MPC5604B微控制器是Freescale半导体公司针对下一代汽车应用微控制器家族的扩展,具有高达64MHz的工作频率;带有内存保护单元(Memory Protection Unit,MPU),通过系统集成单元管理复位、外部中断、通用I/O及引脚的控制;具有4个LIN总线控制器模块、3个DSPI模块、3个CAN总线控制器模块、56个通道的16位增强型模块化输入输出系统(Enhanced Modular IO Subsystem,eMIOS)、36个通道的10位精度模数转化模块(Analog-to-Digital Converter,ADC);定时器系统包括4个软件定时器模块(System Timer Module,STM),6个外围中断定时器(Periodic Interrupt Timer,PIT),一个实时计数器(Real Time Clock,RTC).除此之外,MPC5604B使用可变长度编码(Variable-Length Encoding,VLE)功能,能帮助将代码减小30%,提高了代码密度,降低了存储器的要求.

本文所用的xPC560B评估板是PEMICRO公司针对MPC56xB系列微控制器开发的硬件平台,整套平台包括了xPC56XXMB母板、MPC56xB最小系统、MPC5604B、PE公司USB-ML-PPCNEXUS开发套件.图1给出了xPC560B评估板外围端口及MPC5604B片内资源.

2 μC/OS-II在MPC5604B上的移植

2.1 μC/OS-II特点及移植要求

μC/OS-II是一款源码开放的实时多任务操作系统,其源码绝大部分是用移植性强的ANSI C写的,与微处理器硬件相关的部分是用汇编语言写的,具有可裁剪、实时性强、可剥夺性、能够方便移植到各种微处理器上的特点.其高稳定性和可靠性适用于实时性要求高,安全性要求苛刻的系统中.

要使μC/OS-II正常运行,处理器必须满足以下要求[3]:

1)处理器的C编译器能够产生可重入型代码;

2)处理器支持中断,并且能够产生定时中断(通常为10~100Hz);

图1 xPC560B评估板及MPC5604B片内资源

图2 μC/OS-II硬件/软件体系结构

3)用C语言就可以开/关中断;

4)处理器能支持一定数量的数据存储硬件堆栈(可能是几千字节);

5)处理器有将堆栈指针以及其他CPU寄存器的内容读出、并存储到堆栈或内存中去的指令.

MPC5604B能够完全满足上述要求,因此可以完成移植工作.

图2给出了μC/OS-II的结构以及与硬件的关系.在移植过程中,通过OS_CFG.H的配置实现与应用相关的系统配置,并裁剪掉不需要使用的系统服务程序代码,通过对OS_CPU.H,OS_CPU_A.ASM,OS_CPU_C.C的修改,实现任务堆栈的保存与恢复、任务切换、时钟节拍中断.

2.2 MPC5604B 异常/中断处理

在移植过程中,需要用到两处中断,一是提供时钟节拍的时钟节拍中断,选择MPC5604B中的周期中断定时器PIT产生的定时中断实现;一是在任务级任务切换时所需要产生的软件中断,调用内核指令sc,产生系统调用异常实现.在MPC5604B中,通过异常向量前缀寄存器和异常向量偏移寄存器统一管理异常处理程序的入口地址,所有外设中断为被识别为4号异常,其全局处理程序入口地址对应于4号异常向量偏移寄存器.全局处理程序通过中断向量表调用相应中断服务程序.图3给出了MPC5604B的异常处理流程.

图3 MPC5604B异常处理流程

2.3 OS_CPU.H 的移植

OS_CPU.H中主要涉及到一些与处理器有关的数据类型、相关常数以及相关语句的宏定义.

因为微处理器有不同的字长,而且不同的编译器的对数据类型的定义也不一样,因此在移植时需要给出正确的数据类型定义.因为MPC5604B是32位微控制器,移植时特别注意OS_STK以及CPU状态寄存器OS_CPU_SR的数据类型的定义:

typedef unsigned long OS_STK;

typedef volatile unsigned long OS_CPU_SR;

为了保证数据的完整性,μC/OS-II在处理临界代码时需要关中断,处理完后再打开中断.系统提供OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()来实现开关中断,并且提供三种方法.在移植中采用第三种方法,并通过相关汇编代码保存和恢复当前处理器的状态值.

堆栈增长方向设置,MPC5604B堆栈增长方向为从上(高地址)往下(低地址)递减.故将OS_STK_GROWTH设为1.

任务级任务切换OS_TASK_SW()是一个宏,是在μC/OS-II从低优先级切换到高优先级时任务级代码调用.此处利用e200z0内核中指令sc来实现中断,通过中断服务程序实现任务的切换.

#define OS_TASK_SW()asm(“sc”);

图4 任务调度流程图

2.4 OS_CPU_C.C 和OS_CPU_A.ASM的移植

在OS_CPU_C.C文件中需要改写10个C函数,其中有9个是必须申明但不需要有源代码的,另外一个函数OSTaskStkInit()是必需的.

任务初始化函数 OSTaskStkInit()由 OSTaskCreate()或OSTaskCreateExt()调用,用来初始化任务堆栈.将堆栈结构初始化成像是刚刚发生过中断一样,所有寄存器都被推入堆栈.根据e200z0内核的特点,设计堆栈由高到低保存着特殊寄存器SPR和32个通用寄存器GPR.其在内存中的映射如表1所示,表1中同时给出了OSTaskStkInit()执行后任务堆栈中的情况.

其中 task,p_arg,ptos为 OSTaskStkInit()传入的参数,msr为初始化时MSR寄存器的值,srr1为初始化时MSR寄存器的值并置位中断允许位.

在MPC5604B中,中断发生时,中断返回地址被保存到SRR0中,MSR寄存器被保存到SRR1中.当使用rfi指令从中断返回时,SRR0寄存器指明了中断返回指令地址.在任务创建后,任务不是直接执行的,而是通过OSSched()函数进行调度.为了使调度简单一致,在初始化时将SRR0和LR均指向任务函数入口.

在移植OS_CPU_A.ASM文件时需要用汇编实现如下3个简单的函数:OSStartHighRdy(),OSCtxSw(),OSIntCtxSw().在移植中,采用C语言中内嵌汇编编程,将这三个函数与时钟节拍中断服务函数OSTickISR()均放在OS_CPU_C.C文件中.

表1 堆栈中寄存器的映射与初始化

2.4.1 修改 OSStartHighRdy()函数

OSStartHighRdy()在启动多任务时用来使就绪态任务中优先级最高的任务开始运行,在OSStart()中调用.下面给出移植到MPC5604B上的源代码.

(1)调用用户定义的OSTaskSwHook()函数;

(2)置位OSRunning,使其为真;

(3)得到最高优先级任务指针,将OSTCBCur设为当前最高优先级任务;

(4)将最高优先级任务堆栈指针放入GPR1中;关中断并从新任务堆栈中恢复处理器所有寄存器的值,EPILOGUE见表2;

(5)执行中断返回指令,跳转到优先级最高的任务.

2.4.2 修改 OSCtxSw()和 OSIntCtxSw()函数

这两个函数均是用来做任务切换的,它们的区别在于OSCtxSw()属于任务级的任务切换函数,在任务中调用OSSched()检查是否有高优先级任务,如果有则调用OS_TASK_SW(),产生中断进入该任务切换函数,而OSIntCtxSw()属于中断级的任务切换函数,在中断服务程序退出前检查是否有更高优先级任务,如果有则调用该任务切换函数.下面给出OSCtxSw()的源代码.

(1)将处理器全部寄存器压入堆栈;

(2)在当前任务的任务控制块中保存当前任务的堆栈指针,PROLOGUE见表2;

(3)调用用户定义的OSTaskSwHook()函数;

(4)得到将要重新开始运行的任务的堆栈指针;

(5)更新全局变量OSTCBCur和OSPrioCur;

(6)将最高优先级任务堆栈指针放入GPR1中,关中断并从新任务堆栈中恢复处理器所有寄存器的值;

(7)执行中断返回指令,跳转到新任务.

由于在进入中断后,已经将处理器寄存器的值保存保存到当前任务的任务堆栈中,所以在执行中断级的任务调度时不需要再次保存处理器寄存器的值,因此OSIntCtxSw()的绝大部分代码与OSCtxSw()一样,只是少了其中的(1)和(2)两步.

2.4.3 OSTickISR()函数

OSTickISR()主要的任务是处理时钟节拍中断,通过调用时钟节拍函数OSTimeTick()为系统提供时钟节拍服务,并在中断退出前OSIntExit()函数检查是否有更高优先级任务处于就绪态,进行中断级任务调度.

移植中采用MPC5604B中的周期中断定时器(PIT)作为时钟中断,将时钟中断频率设置为100次/s,在启动任务中进行初始化并允许其中断.

由于e200z0内核指令没有专门的压栈出栈指令,在移植过程中使用相应的汇编程序来实现处理器全部寄存器的保存和恢复过程,见表2.

3 系统测试

在移植完成后需要对系统进行测试,通过测试来发现多任务间是否能够进行正常的任务切换.测试的方法很多,为了排除测试代码的影响,采取建立两个简单任务,通过开关LED灯来指示任务切换的情况.任务代码如下.

表2 堆栈保存/恢复代码

图4给出了测试任务调度流程.通过Freescale xPC560B EVB硬件平台进行测试,LED0每隔4s改变一次状态,LED1每隔2s改变一次状态,系统按预先设计正常运行,表明移植成功.

4 结论

本文通过分析μC/OS-II内核特点及其多任务切换机制,结合e200z0内核和MPC5604B的特点,成功的将μC/OS-II移植到基于Power Architecture○R架构的32位微控制器MPC5604上,并在移植后进行了测试,验证了移植的可行性.

在MPC5604B上成功移植μC/OS-II以后,可以在此基础上对汽车电子控制系统应用程序进行优化.例如,针对汽车变速器控制单元(TCU)控制程序中的离合器控制、换挡控制、起步控制、信号采集等进行多任务设计,结合MPC5604B高速、高精度和μC/OS-II高实时性、高可靠性的优点,进一步优化TCU控制程序,提高汽车的燃油经济性和舒适性.

[1] MPC5604B/C Microcontroller Product Brief Rev.3[R].Freescale Semiconductor,Inc,2009.10.

[2] MPC5604B/C Microcontroller Reference Manual Rev.8[R].Freescale Semiconductor,Inc,2011.5.

[3] [美]Jean J.Labrosse.邵贝贝,译.嵌入式实时操作系统μC/OS-II(第二版)[M].北京:北京航空航天大学出版社,2003.

[4] 刘凯,张立民,赵小峰,等.μC/OS-II在微处理器LM3S8962上的移植[J].电子设计工程,2011,19(1):47 -50.

[5] [美]Richard Soja,Munir Bannoura.龚光华,宫辉,安鹏,等译.MPC5554/5553微处理器揭秘[M].北京:北京航空航天大学出版社,2010.

[6] Errata to EREF:A Programmer’s Reference Manual for Freescale Book E Processors,Rev.0.2[R].Freescale Semiconductor,Inc ,2006.12.

[7] xPC560B EVB User Manual Rev.1.01[R].P&E Microcomputer Systems,Inc,2008.

猜你喜欢
堆栈微控制器调用
核电项目物项调用管理的应用研究
LabWindows/CVI下基于ActiveX技术的Excel调用
嵌入式软件堆栈溢出的动态检测方案设计*
物联网技术在微控制器实验教学中的应用
基于堆栈自编码降维的武器装备体系效能预测
基于系统调用的恶意软件检测技术研究
Atmel针对新一代物联网应用发布全新32位微控制器
最新STM32设计工具增加对混合信号微控制器的支持
意法半导体(ST)推出世界首款基于ARM Cortex-M7的STM32 F7系列微控制器
利用RFC技术实现SAP系统接口通信