APP下载

嵌入式实时操作系统μC/OS-Ⅱ在LPC1788上的移植及应用

2012-07-13薛晴

电子设计工程 2012年15期
关键词:堆栈内核寄存器

薛晴

(北京邮电大学 信息与通信工程学院,北京100876)

μC/OS-II系统是一款源码公开的,针对嵌入式系统的实时内核操作系统,与其它实时操作系统如Vxworks,Linux和Windows CE等相比,它比较适用于小型控制系统,同时具有执行效率高、占用空间小、实时性能优良和可扩展性强等优点[4]。

LPC1788是恩智浦公司于2011年底推出的业界首款采用ARM®CortexTM-M3技术的微控制器,目前已批量上市。120 MHz的LPC178x系列拥有512 kB闪存、96 kB SRAM和4 kB EEPROM。32位外部存储控制器支持SDRAM、NOR和SRAM器件,提供4种芯片选择[2]。其先进的低功耗工艺,特别适用于消费电子、工业控制、安防、通讯系统,以及需要高速计算的数据采集系统领域。

由于该款微处理器上市时间较短,目前还没有μC/OS-II操作系统应用于该款微处理器的移植代码。文中详细探讨了在IAR6.3集成开发环境下,如何在LPC1788处理器上移植μC/OS-II操作系统的过程与实现步骤,该移植与开发过程已成功地在LPC1788目标板上进行了运行测试。

1 μC/OS-Ⅱ内核结构及工作原理

1.1. μC/OS-Ⅱ系统结构

图1说明了μC/OS-II的软硬件体系结构。应用程序处于整个系统的顶层,每个任务都可以认为自己独占了CPU,因而可以设计成一个无限循环。μC/OS-II与处理器无关的代码,提供了μC/OS-II的系统服务,应用程序可以使用这些API函数进行内存管理、任务间通信及创建、删除任务。其中,μC/OS-II内核最核心的作用就是对任务的管理。

图1 μC/OS-II的系统总体结构图Fig.1 Structure diagram of μC/OS-II system

1.2 μC/OS-Ⅱ内核基本工作原理

μC/OS—II的任务拥有自己的代码和堆栈空间 (保存该任务的寄存器、返回地址和临时参数),一般都是空函数,不会返回任何值。任务执行一次后,设置延时参数OSTCBDly。表明在经过OSTCBDly个时钟周期后再次运行,然后任务进行切换.使其他任务运行。

μC/OS-Ⅱ下的任务有 5种状态:睡眠态、就绪态、运行态、等待状态、中断服务态。调度就是决定该轮到哪个任务运行了,从而使一就绪的任务切换到运行态,这是内核的主要职责之一。μC/OS-Ⅱ是基于优先级调度算法的:也就是让处于就绪态、优先级最高的任务先运行。

2 μC/OS-Ⅱ在LPC1788上的移植

由图 1可知,μC/OS-Ⅱ的接口文件是 OS_CPU.H,OS_CPU_C.C和OS_CPU_A.ASM,移植的主要任务是改写这3个文件的代码,使μC/OS-Ⅱ能在LPC1788上正常运行。移植工作包括以下几个内容:

2.1 OS_CPU.H中的常量和宏定义

2.1 OS_CPU.H包括了用#defines定义的与处理器相关的常量,宏和类型定义,堆栈宽度和增长方式以及开关中断的宏定义[6]。

在IAR6.3环境下改写该文件时的几点说明:

1)由于Cortex-M3内核堆栈支持从上往下的生长方式,所以L1根据所选芯片LPC1788支持的类型对宏OS_STK_GRWOTH进行定义,

2)因LPC1788的状态寄存器是32位宽,L2,L3定义的os_cpu_sr用于OS_CRITICAL_METHOD#3.中保存中断状态[3]。

3)OS_CPU.H文件中另外3个宏OS_CRITICAL_METHOD,OS_ENTER_CRITICAL (),OS_EXIT_CRITICAL()用于定义开关中断的方式及开关中断的实现。而OS_CPU_SR_Save()和 OS_CPU_SR_Restore(cpu_sr)的代码则在OS_CPU_A.asm文件中汇编语言编写,稍候会详细介绍。

4)任务级的切换是通过调用L6的宏OS_TASK_SW()来实现,OSCtxSw()的具体代码在 OS_CPU_A.asm中用汇编语言实现。

2.2 OS_CPU_C.C中的用户C语言函数

在OS_CPU_C.C中要求用户编写8个简单的C函数:OSTaskStkInit ()、OSTaskCreateHook ()、OSTaskDelHook ()、OSTaskSwHook ()、OSTaskStatHook ()、OSTimeTickHook ()、OS_TaskStkIni ()、OS_CPU_SysTickInit ()、OS_CPU_SysTick Handler(),除三个必须的函数 OS_TaskStkIni,OS_CPU_SysTickInit和OS_CPU_SysTickHandler外,其它的5个函数是钩子函数,必须声明但没必要包含代码。

1) OSTaskStkInit()函数

定义任务堆栈初始化函数OSTaskStkIni()的具体程序及注释如下所示::

μC/OS-Ⅱ要求用户提供一个周期性的时钟源,以实现时间延迟和超时确认功能,时钟节拍每秒发生10~100次。必须在开始多任务后,启动时钟节拍中断,所以可以在OSStart()运行之后,μC/OS启动的第1个任务中调用OS_CPU_SysTickInit()初始化节拍中断。基于LPC1788移植下的时钟初始化函数的OS_CPU_SysTickInit()的代码如下所示:OSIntExit();} /*告诉 uC/OS-II退出中断服务程序*/当时钟节拍中断发生时,CPU会自动把CPU寄存器推人堆栈。当某任务的任务控制块中时间延时项OSTCBDly减到了零,OSTimtick()就进入了就绪态。 OSIntExit()会调用中断级的任务切换函数OSIntCtxSw执行任务切换,而不再执行后面的指令。

2.3 OS_CPU_A.ASM中的用户汇编语言函数

在OS_CPU_A.ASM中,因为C语言不能直接存取寄存器,用户在移植μC/OS-Ⅱ的时候,需要用汇编语言编写5个函 数 : OS_CPU_SR_Save ()、OS_CPU_SR_Restore ()、OSStartHighRdy ()、OSCtxSw ()、OS_CPU_PendSVHandler ()。如下所示:

1) OS_CPU_SR_Save()函数

OS_CPU_SR_Save()函数实现用R0保存中断屏蔽寄存器PRIMASK的状态值,该函数被OS_ENTER_CRITICAL()宏调用[3]。

4) OSCtxSw()函数

当一个任务放弃对CPU的控制后,OSCtxSw()就会被调用以实现任务切换,但对于ARM Cortex-M3来说,所有的任务切换都是由PendSV中断服务程序来实现的,所以OSCtxSw()只是简单触发PendSV中断,然后返回调用者。

OS_CPU_PendSVHandler()负责处理 ARM Cortex-M3 所有的任务切换[3],在该程序开始执行时,CPU首先把xPSR、PC、LR、R12,R0-R3和R4-R11寄存器保存到任务堆栈,然后获得最高优先级任务的堆栈指针,将最高优先级任务的寄存器按顺序从任务堆栈中恢复出来,最后执行中断返回:

不同任务的切换会发生在停止当前低优先级的任务转而去执行较高优先级任务的情形,这是由一个任务级切换函数OS_TASK_SW()实现的,该函数通过调用 OSCtxSw()函数触 发 PendSV中 断 ,PendSV中 断 服 务 程 序OS_CPU_PendSVHandler完成具体的任务切换操作。OS_CPU_PendSVHandler的编写实质上是通过改变PC中的内容来实现的,首先将当前任务环境保存到相应的任务堆栈中,同时将PC指向新任务开始运行的地方,然后将新任务环境从堆栈中恢复到相应的寄存器中,最后执行中断返回。在中断返回时,Cortex-M3将从堆栈中恢复R3-R0,R12,LR,PC和xPSR寄存器,开始运行新任务,从而实现任务的切换。

3 应用测试

文中使用LPC1788目标板对上述移植进行了实验测试,目标板有四个按键和两个LED,本测试建立了App_TaskStart()、App_TaskKbd()、App_TaskLed()三个任务。 App_TaskStart()负责硬件初始化及OS初始化,建立消息邮箱及另两个任务,然后进入无限循环,在循环体内调用OSTimeDly(200)以实现延时和任务调度。App_TaskKbd()负责查询按键并通过消息邮箱将键值发送给任务App_TaskLed(),App_TaskLed()根据键值改变LED的闪烁频率。测试程序通过IAR6.3编译,把生成的二进制文件固化到LPC1788目标板上,接通电源后可以准确稳定地运行,说明在IAR6.3环境下基于LPC1788的μC/OS-II移植成功。

4 结束语

文中分析了μC/OS-Ⅱ内核的文件结构及基本工作原理,成功实现了其在LPC1788上的移植。文中相应的源代码不用作任何改变,直接复制到μC/OS-Ⅱ相应文件中,可顺利实现多任务调度,且运行稳定、可靠,可以进行ARM Cortex-M3微控制器LPC17xx系列的各种应用系统的设计与开发。

[1]Jean J.Labrosse.嵌入式实时操作系统μC/OS-Ⅱ [M].2版.邵贝贝,译.北京航空航天大学出版社,2003.

[2]NXP LPC178x/7x preliminary user manual,[EB.OL]2011.http://www.nxp.com

[3]Micriμm μC/OS-II and ARM Cortex-M3 Processors Application Note(2011)http://www.Micrium.com

[4]孙继如,郭敏,张宇翔,等.嵌入式实时操作系统μC/OS-Ⅱ在LPC2378上的移植及应用[J].现代电子技术,2010(12):33-36.

SUN Ji-ru,GUO Min,ZHANG Yu-xiang,et al.Transplant and application of the embedded real-time OS μC/OS-Ⅱon LPC2378[J].Modern Electronics Technique,2010(12):33-36.

[5]顾凤玉,施国梁,杨涛.基于LPC2478的μC/OS-II的移植及多任务的实现[J].电脑知识与技术,2009(5):1736-1739.GU Feng-yu,SHI Guo-liang,YANG Tao.On the porting of μC/OS-II to LPC2478 ARM processor and the implementation of multitasks[J].Computer Knowledge and Technology,2009(5):1736-1739.

[6]韩明峰,李小滨,郑永志.uC/OS-II内核超时等待机制的分析与改进[J].计算机工程, 2009,35(7):259-266.

HAN Ming-feng,LI Xiao-bin,ZHENG Yong-zhi.Analysis and improvement of waiting-timeout mechanism in uC/OS-II Kernel[J].Computer Engineering,2009,35(7):259-266.

[7]刘艳军.基于C8051和μC/OS-Ⅱ的数控机床嵌入式执行控制器实现[J].现代电子技术,2010(16):63-65.

LIU Yan-jun.Realization of embedded actuator&Controller for CNC machine tool based on C8051 and μC/OS-Ⅱ[J].Modern Electronics Technique,2010(16):63-65.

[8]汪献忠,郭凤华,田增国.基于ARM和μC/OS-Ⅱ的在线磷酸根离子监测仪设计[J].现代电子技术,2010(19):154-155,158.

WANG Xian-zhong,GUO Feng-hua,TIAN Zeng-guo.Design of phosphate ion online monitoring instrument based on ARM and μC/OS-Ⅱ[J].Modern Electronics Technique,2010(19):154-155,158.

猜你喜欢

堆栈内核寄存器
基于行为监测的嵌入式操作系统堆栈溢出测试*
STM32和51单片机寄存器映射原理异同分析
强化『高新』内核 打造农业『硅谷』
Lite寄存器模型的设计与实现
基于嵌入式Linux内核的自恢复设计
Linux内核mmap保护机制研究
基于堆栈自编码降维的武器装备体系效能预测
微生物内核 生态型农资
高速数模转换器AD9779/AD9788的应用
一种用于分析MCS-51目标码堆栈深度的方法