长沙民政职业技术学院学报
JournalofChangshaSocialWorkCollegeVol.19No.4
Dec.2012
基于STM32处理器的μC/OS-III移植
朱志伟
(长沙民政职业技术学院,湖南长沙410004)
[摘要]结合μC/OS-III和STM32处理器内核Cortex-M3的一些基本特征,用汇编语言和C语言修改了移植过程中
的源代码,并作出详细解释。移植过程使用了STM32F103RBT6处理器自带的标准外设库,减少了繁琐的寄存器配置,降低了移植的难度和加快了应用程序开发速度,同时使代码标准更统一。硬件实验的成功,表明该移植对其它Cor-tex-M3核的处理器基于μC/OS-III的开发应用也有很高的参考价值。[关键词]μC/OS-III;移植;STM32;Cortex-M3;标准外设库[中图分类号]TP316.2[文章标识码]A
[文章编号]
1671-5136(2012)04-0175-03
μC/OS-III是Micrium公司于2011年8月1日发布的第三代占先式实时内核,虽然其某些功能稍逊
于Linux、Android等市场占有率极高的嵌入式操作系统,但其优点也是显而易见的,如微内核、强实时性、对硬件要求低等。μC/OS-III支持无限数量的任务,支持无限数量的优先级。利用时间轮转的调度算法,还允许多任务同时运行于同一优先级。μC/OS-III提供几乎为零的中断禁用时间,确保了能够响应一些最快的中断源。完成基于STM32处理器的μC/OS-III移植,能加深对嵌入式操作系统原理的理解,把软硬件资源交由μC/OS-III管理,在此基础上集中精力进行应用程序设计,这些过程在嵌入式系统应用开发技术飞速发展的今天具有非常重要的意义。
1.移植环境
1.1编译软件和微处理器
移植过程使用的编译软件是RealViewMDK4.12,处理器采用了ST意法半导体公司生产的STM32F103RBT6,该处理器内置Cortex-M3核,并且具有非常丰富的片上资源。
1.2Cortex-M3核的ARM处理器Cortex-M3核采用ARMv7-M架构,它包括所有的16位Thumb指令集和基本的32位Thumb-2指令集架构。Cortex-M3处理器支持2种工作模式:线程模式
和处理模式。在复位时处理器进入线程模式,异常返回时也会进入该模式,特权和用户(非特权)模式代码能
够在线程模式下运行。出现异常模式时处理器进入处理模式,在处理模式下,所有代码都是特权访问的。μC/OS-III内核和用户代码都运行于特权级下。Cor-tex-M3拥有两个堆栈指针,任何时刻只能使用其中的一个。主堆栈指针(MSP):复位后缺省使用的堆栈指针,用于操作系统内核以及异常处理例程(包括中断服务例程);进程堆栈指针(PSP):由用户的应用程序代
系统复位时总是处于线程模式的特权方式下,码使用。
所以默认使用的堆栈指针是MSP,并且μC/OS-III内核和ISR(中断服务例程)使用MSP,μC/OS-III的任务则使用PSP。
1.3STM32标准外设库
STM32标准外设库之前的版本也称固件函数库或简称固件库,是一个固件函数包,它由程序、数据结构和宏组成,包括了微控制器所有外设的性能特征。该函数库还包括每一个外设的驱动描述和应用实例,为开发者访问底层硬件提供了一个中间API,通过使用固件函数库,无需深入掌握底层硬件细节,开发者就可以轻松应用每一个外设。因此,使用固态函数库可以大大减少用户的程序编写时间,进而降低开发成本。每个外设驱动都由一组函数组成,这组函数覆盖了该外设所有功能,其驱动程序结构、函数和参数名称都被标准
[收稿日期]2012-11-06
(青年项目)(编号:12B011)。[基金项目]2012年度湖南省高等学校科学研究项目
男,长沙民政职业技术学院电子信息工程学院副教授。研究方向:嵌入式系统和电力电子技术。[作者简介]朱志伟,
176长沙民政职业技术学院学报2012年
化。标准外设库覆盖了从GPIO到定时器,再到CAN、I2C、SPI、UART和ADC等等的所有标准外设。简单地说,使用标准外设库进行开发,最大的优势就在于可以使开发者不用深入了解底层硬件细节,就可以灵活规范地使用每一个外设,非常方便进行二次开发和应用。
2.移植过程详解
2.1移植准备
μC/OS-III内核的最新版本为V3.03.00,其源文件KRN-K3XX-000000.zip的下载地址见参考文献[1]。STM32标准外设库的最新版本为V3.5.0,其源文件stm32f10x_stdperiph_lib.zip下载地址见参考文献[2]。
2.2代码移植
μC/OS-III的源代码按照移植要求分为需要修改部分和不需要修改部分。其中需要修改源代码的文件
包括与内核相关的文件:
os_cpu.h、os_cpu_a.asm、os_cpu_c.c,与系统CPU相关的文件为:cpu.h、cpu_a.asm、cpu_core.c。为了实用性,移植时需要增加μC/OS-III与产生时基的定时器、中断控制器的接口,还要增加标准外设库与μC/OS-III的关联吻合工作。
2.2.1C语言头文件os_cpu.hos_cpu.h主要是对任务级任务切换函数OS_TASK_SW()和中断级任务切换函数OSIntCtxSw()以及时间戳获取函数OS_TS_GET()进行宏定义。OS_TASK_SW()被OSSched()调用,OSIntCtxSw()被OS-IntExit()调用。OS_TS_GET()用于获取当前的时间戳,其数据类型为CPU_TS,是无符号的32位整数。若使能μC/OS-III的时间戳功能,则将OS_TS_GET()宏定义为CPU_TS_TmrRd(),并且还要在os_cfg.h中把OS_CFG_TS_EN定义为1,无需时间戳功能时,则定义为0。相应的源代码如下:
#defineOS_TASK_SW()NVIC_INT_CTRL=NVIC_PENDSVSET
#defineOSIntCtxSw()NVIC_INT_CTRL=NVIC_PENDSVSET
#ifOS_CFG_TS_EN==1u#defineOS_TS_GET()(CPU_TS)CPU_TS_TmrRd()
#else#defineOS_TS_GET()(CPU_TS)0u2.2.2汇编语言文件OS_CPU_A.ASM
OS_CPU_A.ASM中需要编写OSStartHighRdy子程序和PendSV的中断服务子程序。OSStartHighRdy()由OSStart()调用,设置PendSV中断优先级到最低;初
始化进程堆栈指针PSP为0,并告诉具体的任务切换
程序OS_CPU_PendSVHandler(),这是第一次任务切换(做过切换后PSP就不会为0了);设置主栈指针MSP切换到异常堆栈OS_CPU_ExceptStkBase;对中断控制及状态寄存器ICSR(0xE000ED04)第28位写1触发PendSV中断;使能中断,启动最高优先级任务。
SVC(系统服务调用)和PendSV(可挂起系统调用)多用在操作系统的软件开发中。PendSV可以像普通的中断一样被挂起,可以利用它“缓期执行”一个异常———直到其它重要的任务完成后才执行动作,挂起PendSV的方法是:手工往NVIC的PendSV挂起寄存器中写1,
挂起后,如果优先级不够高,则将缓期执行。PendSV异常会自动延迟任务切换的请求,直到其他的ISR都完成了处理后才放行。为了实现这个机制,需要把PendSV编程为最低优先级的异常。如果检测到某IRQ正在活动并且被抢占,它将挂起一个PendSV异常,以便缓期执行任务切换。真正的任务切换是在PendSV中断处理函数里做的,由于CM3在中断时会有一半的寄存器自动保存到任务堆栈里,所以在PendSV中断处理函数中只需保存R4~R11,并调节堆栈指针即可。
PendSV中断处理函数伪代码如下:
OS_CPU_PendSVHandler(){if(PSP!=NULL){
SaveR4-R11ontotaskstack;OSTCBCur->OSTCBStkPtr=SP;}
OSTaskSwHook();
OSPrioCur=OSPrioHighRdy;OSTCBCur=OSTCBHighRdy;
OSTCBCurPtr=OSTCBHighRdyPtr;PSP=OSTCBHighRdy->OSTCBStkPtr;LR=LR|0x04;RestoreR4~R11fromnewtaskstack;Returnfromexception;}
如果PSP==0,说明OSStartHighRdy()启动后第一次做任务切换,而任务刚创建时R4~R11已经保存在堆栈中了,所以不需要再保存。OSTCBStkPtr是任务控制块结构体的第一个变量,所以OSTCBCur->OSTCB-StkPtr=SP;在中断处理函数中使用的是MSP,所以在返回任务后必须使用PSP,因此LR的D2位必须置1。
2.2.3C语言文件OS_CPU.C在将μC/OS-III移植到STM32的过程中对OS_CPU_C.C的修改是必要的,而此文件中最主要的
第4期朱志伟:基于STM32处理器的μC/OS-III移植177
是修改OSTaskStkInit()函数,供OSTaskCreate()调用,
为任务切换服务。OSTaskStkInit()的作用是把任务堆栈初始化成好像刚发生过中断一样。Cortex-M3中断时,寄存器xPSR、PC、LR、R12、R3、R2、R1、R0的压栈过程由Cortex-M3中的微代码自动完成。初始化时需要注意的地方是xPSR、PC、LR和R0的值,其他寄存器的初值没有特别的要求。xPSR的D24位(Thumb状态位),初始化时须置1,否则执行代码时会引起一个名为INVSTATE的异常,这是因为Cortex-M3只支持Thumb和Thumb2指令集,入栈的xPSRThumb状态位被破坏,使得在返回时内核尝试进入ARM状态。堆栈中PC和LR须初始化为有关任务的入口地址值,这样才能在任务切换时跳转到正确的地方开始执行。R0用于传递任务函数的参数,因此等于p_arg。
在OS_CPU.C中,还有8个钩子函数需要编写,这些钩子函数如果不使能,则可不包含任何代码,但必须声明。
2.2.4C语言头文件CPU.h
cpu.h中需要修改的内容有与编译器相关的数据类型重定义部分和与CPU相关的少量代码。在μC/OS-III中,没有使用C编译器的数据类型int,short,long,char等,而是定义了更易于看懂的数据类型,其中μC/OS-III中非常重要的数据类型CPU_STK决定了压入和弹出堆栈的数据是32位的,时间戳的数据类型为CPU_TS。与CPU相关部分代码主要包括:关中断的宏CPU_CRITICAL_ENTER()和开中断的宏CPU_CRITICAL_EXIT(),处理器堆栈增长方向定义为CPU_STK_GROWTH_HI_TO_LO。
2.2.5汇编语言文件CPU_A.ASM
CPU_A.ASM中包含关中断函数、开中断函数、计数清零函数等。这个函数至少需要包括中断使能函数CPU_SR_Save()和中断禁用函数CPU_SR_Restore()。CPU_SR_Save()在中断时保存当前CPU的状态寄存器到堆栈。CPU_SR_Save()被宏CPU_CRITICAL_ENTER()调用。CPU_SR_Restore()恢复中断前CPU的状态寄存器。CPU_SR_Restore()被宏CPU_CRITICAL_EXIT()调用。用CLZ指令实现的计数清零函数CPU_CntLeadZeros()被调度器用于查找最高优先级的就绪任务(使用这个函数之前需在CPU.H中定义CPU_CFG_DATA_SIZE的值)。
3.系统调试
在精简移植的思想指导下,使用标准外设库中的
startup_stm32f10x_md.s作为启动文件。由于start-up_stm32f10x_md.s文件中PendSV中断向量名为PendSV_Handler,所以需要用PendSV_Handler替换掉
μC/OS-III中的OS_CPU.h和OS_CPU_A.ASM中的OS_CPU_PendSVHandler。替换后的voidPendSV_Handler(void)函数在OS_CPU_C.h中有声明,
在OS_CPU_A.ASM中有具体的中断服务函数代码,
在startup_stm32f10x_md.s中有向量地址,实现了相互之间的关联与吻合。μC/OS-III正常工作,不能缺少系统时钟,需要进行SysTick初始化,SysTick是OS的“心跳”,可称为滴答时钟,本质上来说就是一个定时器。可用如下代码实现:staticvoidsystick_init(void)
{RCC_ClocksTypeDefrcc_clocks;
RCC_GetClocksFreq(&rcc_clocks);//调用标准库函数,获取系统时钟。
SysTick_Config
(rcc_clocks.HCLK_Frequency
/OS_CFG_TICK_RATE_HZ);//初始化并使能SysTick}最终的测试程序还要添加RCC、GPIO、LED等初始化函数和驱动程序。
4.结束语
通过将移植过程中修改的μC/OS-III内核代码、STM32标准外设库3.5.0以及LED闪烁应用程序代码在MDK4.12集成开发环境中编辑整合后进行编译、链接并且下载到参考文献[6]所对应的目标硬件平台进行长时间观察,发现LED能不停地交替闪烁,从而说明本移植过程是成功的。MDK4.12的软件仿真也反应出同样的效果。
[参考文献]
[1]
Micrium.DownloadμC/OSsourcecode[EB/OL].http://mi-crium.com/page/downloads/source_code,.2012-07-02.[2]STMicroelectronics.STM32F10xstandardperipherallibrary
[EB/OL].http://www.st.com/internet/com/SOFTWARE_RESOURCES/SW_COMPONENT/FIRMWARE/stm32f10x_stdpe_lib.riphzip,2012-07-05.[3]lbl1234.ucosii在stm32上的移植详解[EB/OL].http://blog.csdn.net/lbl1234,2012-07-02.
[4]JosephYiu,宋岩译.ARMCortex-M3权威指南[M].北京:北京航空航天大学出版社,2009.
[5]屈环宇,陈丽萍,王寄新.μC/OS–III任务间通信的研究[J].电脑知识与技术,2012,(2):306-308.
[6]
刘军.例说STM32[M].北京:北京航空航天大学出版社,2011.
因篇幅问题不能全部显示,请点此查看更多更全内容