微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > μCOS-II在ARM Cortex-M3处理器上的移植

μCOS-II在ARM Cortex-M3处理器上的移植

时间:09-29 来源:互联网 点击:

摘要:Cortex-M3是ARM公司最新推出的基于ARMv7-M架构的低功耗处理器。在深入了解μCOS-II工作原理和Cortex-M3特性的基础上,给出了在STWl32F103ZE处理器上的详细移植过程。将移植后的μC/OS-Ⅱ操作系统应用于移动多媒体直放站CMMB项目中,验证了移植的成功。这对于管理硬件资源,缩短开发周期和提高系统稳定性方面有着重要的意义。
关键词:Cortex-M3;μCOS-Ⅱ;移植;嵌入式系统

0 引言
嵌入式系统已经广泛渗透到了人们工作、生活中的各个领域,嵌入式处理器已占分散处理器市场份额的94%,其中ARM的应用最为广泛。基于ARM内核的处理器以其诸多优异性能而成为各类产品中选用较多的处理器之一。
当系统越来越大,应用越来越多时,就出现了如何管理众多的硬件资源,以及如何满足系统的实时控制要求和如何提高系统软件开发效率等不可回避的问题。这时,使用嵌入式操作系统很有必要。操作系统的主要作用有:统一管理系统资源;为用户提供访问硬件的接口;调度多个应用程序和管理文件系统等。

1 概述
μC/OS-II是著名的、源码公开的实时内核,是专为嵌入式应用设计的,可用于各类8位、16位和32位处理器。μC/OS-II已经在世界范围内得到广泛使用,包括诸多领域,如手机、飞行器、医疗设备及工业控制等。实际上,μC/OS-II已经通过了非常严格的测试,并且得到了美国航空管理局的认证,可以用在飞行器上。这说明μC/OS-II是稳定可靠的。
Cortex-M3是一款低功耗处理器,具有门数目少,中断延迟短,调试成本低的特点,是为要求有快速中断响应能力的深度嵌入式应用而设计的。该处理器采用最新的ARMv7-M架构。还具有如下特性:
(1)采用Thumb-2指令集。在Thumb-2中,16位指令首次与32位指令并存,代码密度得到很大改善。
(2)Cortex-M3处理器可配置为具有SW-DP或JTAG-DP调试端口。
(3)使用可选的MPU对处理器提供存储器保护。
(4)具有嵌套向量中断控制器(NVIC),低延迟的异常处理。
本论文采用的是意法半导体ST公司生产的基于Cortex-M3内核的STM32F103ZE处理器,详细论述了μC/OS-Ⅱ的移植过程。编译环境采用的是RVMDKV3.7。

2 移植工作
所谓移植,就是使一个实时内核能在指定的微处理器上运行。为了方便移植,大部分μC/OS-II的代码都是用C语言编写的,但是仍需要用C语言和汇编语言编写一些与处理器硬件相关的代码。μC/OS-II是第一个支持Cortex的RTOS,图1显示应用程序、μC/OS-II、port和BSP四者之间的关系。具体移植工作主要涉及到头文件OS_CPU.H、C语言文件OS_CPU_C.C以及汇编格式文件OS_CPU_A.ASM。


2. 1 OS_CPU.H
OS_CPU.H包含处理器需要的用#defines语句定义的、与处理嘉相关的常数、宏以及类型。因为不同的处理器有不同的字长,μC/OS-II的移植包括了一系列的数据类型定义,以确保其可移植性。μC/OS-II内核代码不使用C语言中的short、int及long等数据类型,因为它们是编译器相关的,是不可移植的。Cortex-M3是32位处理器,同时参照RVMDK编译器文档,对μC/OS-II内核中的数据类型作如下定义:

typedef unsigned int OS_STK;
typedef unsigned int OS_CPU_SR;
OS_STK定义的是32位宽的堆栈入口地址数据类型,OS_CPU_SR定义的是32位宽的Cortex-M3处理器状态寄存器数据类型。
和所有的实时内核一样,μC/OS-II为了访问临界区的代码需要关闭中断,访问完,重新使能中断。为了增加可移植性,μC/OS-II定义了两个宏分别关闭和使能中断一OS_ENTER_CRITICAL()、OS_EXIT_CRITICAL()。μC/OS-II定义了三种关闭和使能中断方法,只需要使用其中一个。多数情况下,推荐使用OS_CRITICAL_METHOD#3。
OS_CRITICAL_METHOD#3通过写一个保存CPU状态寄存器在一个临时变量里的函数,实现OS_ENTER_CRITICAL()。OS_EXIT_CRITICAL()调用另一个函数从临时变量恢复CPU状态寄存器。
绝大多数微处理器和控制器的堆栈是从上往下递减的,但是也有些处理器使用的是相反的方式。μC/OS-II对两种都可以处理,只要配置常数OS_STK_GROWTH指定堆栈的方向就可以了。ARM Cortex-M3的堆栈增长是从高内存地址往低内存地址,因此,OS_STK_GROWTH应该设置为l。
2. 2 OS_CPU_C.C
移植μC/OS-Ⅱ要求编写10个简单的C语言函数,但唯一必要的函数是OSTaskStkInit(),其他9个函数必须申明,但并不一定要包含任何代码,允许用户在必要时添加扩展OS功能的代码。
OSTaskCreate()和OSTaskCreateExt()通过调用OSTaskStklnit(),初始化任务堆栈。因此,堆栈看起来像中断刚发生过一样,所有寄存器都保存在堆栈中。多数CPU寄存器的初始值并不重要,但是为了方便调试和检查堆栈,用寄存器序号去初始化它们。寄存器的顺序是重要
的,应该和ARM Cortex-M3在发生异常时的堆栈顺序一样。
2. 3 OS_CPU_A.ASM
移植μC/OS-II要求编写5个简单的汇编语言函数。
OS_CPU_SR_Save()
OS_CPU_SR_Restore()
OSStartHighRdy()
OSCtxSw()
OSIntCtxSw()
OS_CPU_SR_Save()按照OS_CRITICAL_METHOD#3的方式,首先保存中断屏蔽寄存器,接着关闭中断。这个函数被宏OS_ENTER_CRITICAL()调用。当这个函数返回时,RO包含关闭中断前的中断屏蔽寄存器的状态。
OS_CPU_SR_Restore()恢复在调用OS_ENTER_CRITICAL()之前中断屏蔽寄存器的原值。也就是说,若在调用OS_ENTER_CKJTICAL()之前中断是关闭的,调用之后仍是关闭的。
OSStart()调用OSStartHighRdy()来运行在调用OSStart()之前创建的最高优先级任务。OSStart()设置OSTCBHighRdy指向最高优先级任务的OS_TCB。
当一个任务放弃对CPU的控制时,OS_TASK_SW()宏被调用,实际最终调用的是OSCtxSw()函数。通常,OSCtxSw()应该实现任务上下文切换,但是在ARM Cortex-M3中,所有的上下文切换由pendSV句柄来完成。OSCtxSw()仅仅触发PendSV句柄,再返回到调用处。
ISR完成后,调用OSIntExit()查看是否有比中断任务更重要的任务需要去执行。若确实如此,OSIntExit()调用OSIntCtxSw()决定下一步将要运行哪一个任务。然而,和OSCtxSw()一样,仅仅触发PendSV句柄,再返回到调用处。
限于篇幅,不详细列出5个函数的源代码。
2.4 PendSV句柄及系统滴答
PendSV句柄函数为μC/OS-Ⅱ实现所有的上下文切换。这是ARM Cortex-M3推荐的上下文切换方法。这是因为ARM Cortex-M3发生任何异常时,自动保存多个寄存器,异常返回时自动恢复这些寄存器。PendSV仅仅需要保存R4-Rll和调整堆栈指针。不管是任务的初始化还是中断或
异常引发的PendSV异常都是采用同样的方法实现保存和恢复上下文。
μC/OS-Ⅱ要求用户提供一个周期性的时钟源来实现时间的延时和超时功能。Cortex-M3的系统滴答定时器是专门为RTOS设计的。可以在OSStart()运行后,μC/OS-II启动运行的第一个任务中调用OS_CPU_SysTickInit()初始化系统滴答定时器并使能中断。
需要注意的是:在系统启动代码中,初始化中断向量时,向量14和15应放置PendSV和SysTick对应的句柄。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top