基于 S3C44B0X处理器的μC/OS-Ⅱ的移植方法研究

2011-11-06 05:36:54李兴霞
大庆师范学院学报 2011年3期
关键词:堆栈指针调用

李兴霞

(佳木斯大学应用技术学院,黑龙江佳木斯 154007)

基于 S3C44B0X处理器的μC/OS-Ⅱ的移植方法研究

李兴霞

(佳木斯大学应用技术学院,黑龙江佳木斯 154007)

主要研究了嵌入式操作系统μC/OS-Ⅱ在 ARM7上的移植方法。首先,分析了μC/OS-Ⅱ的软硬件体系结构。然后,在基于 ARM7架构的 Samsung S3C44B0X硬件平台上,成功地将μC/OS-Ⅱ移植到 S3C44B0X处理器上。详细说明了μC/OS-Ⅱ的移植过程,给出了移植的具体方法和步骤。设计的移植方法不但使系统速度快、性能稳定,而且操作简单,具有很高的实用价值。

计算机软件;移植;实验;μC/OS-Ⅱ;嵌入式操作系统;S3C44BOX

0 引言

所谓移植,就是使一个实时内核能在特定的微处理器或微控制器上运行。μC/OS-Ⅱ是由美国人JeanJ.Labrosse编写的,是一个完全免费的公开源代码的实时操作系统。μC/OS-Ⅱ作为一个被广泛应用的操作系统,在设计时就已经充分考虑到了可移植性,其技术已经很成熟[1]。本文分析了μC/OS-Ⅱ的结构,在以 S3C44BOX为核心的硬件平台上移植实时操作系统,给出移植要点及核心代码实现,对其它嵌入式操作系统的移植也有一定的参考价值。

1 μC/OS-II的源程序文件结构

图 1是μC/OS-Ⅱ的软硬件体系结构。与硬件相关的代码处于程序的最底层,在其上是操作系统的相关代码。与硬件无关的代码,如应用程序处于整个系统的顶层。这样的结构方便了μC/OS-Ⅱ操作系统的移植[2],在移植中,主要是对三个与硬件密切相关的文件进行修改和配置[3]。

图1 μC/OS-Ⅱ的软硬件体系结构

2 μC/OS-II的移植

2.1 移植工作包括的内容

1)用#define设置一个常量的值 (OS_CPU.H文件中);2)声明 10个数据类型 (OS_CPU.H文件中);3)用#define声明 3个宏 (OS_CPU.H文件中);

4)用 C语言编写 6个简单的函数 (OS_CPU_C.C文件中);5)编写 4个汇编语言函数 (OS_CPU_A.AS M文件中)。

2.2 移植过程

接下来对移植过程中需要修改的文件做一些具体说明。

2.2.1 修改后的 OS_CPU.H

1)数据类型的定义

typedef unsigned charBOOLEAN;typedef unsigned char INT8U;typedef signed char INT8S;typedef unsigned short INT16U;typedef signed short INT16S;typedef unsigned int INT32U;typedef signed int INT32S;typedef float FP32;

typedef double FP64;typedef unsigned intOS_STK;

typedef unsigned intOS_CPU_SR;

2)常量的值设定

#define OS_CR ITI CAL_METHOD 2

3)宏的声明

#define OS_ENTER_CR ITI CAL()ARMDisableInt()#define OS_EXIT_CR ITI CAL()ARMEnableInt()#define OS_TASK_S W OSCtxS w

2.2.2 关于 OS_CPU_A.AS M

在OS_CPU_A.AS M文件中,要求编写以下四个简单的汇编语言函数:

①OSStartHighRdy();②OSCtxSw();③OSIntCtxSw();④OSTickISR()。

下面依次进行介绍,OSStartHighRdy()是系统刚刚创建完最初的若干任务后,有一个 OSStart()就开始运行,OSStart()找到最优先的任务,然后就调用 OSStartHighRdy()来启动那个任务。在 OSStartHigh-Rdy()被调用之前,优先级最高的任务的 TCB(很重要的概念)的指针 (同时也是刚才放好的堆栈指针)已经被 OSStart()放在全局变量 OSTCBHighRdy中。OSStartHighRdy()的任务归结如下:

1)启动了之后,先调用一个任务允许用户定 HOOK函数;

2)全局变量 OSRuning设置为 TRUE,标志多任务系统开始运行;

3)SHighRdy指向的 TCB中得到堆栈指针,放在 R13里;

4)堆栈中恢复所有其他的相关寄存器,包括 CPSR,R0~R12,LR,PC。

这样,任务函数就象被 BL指令调用了一样,从 Task的第一条指令开始执行了。除了这个最初的调度之外,系统里还会发生其他两种情况的调度:一个任务调用 OsxxxPend()、OST imDelay()之类的函数,主动放弃 CPU的使用权;一个任务正在执行,不愿意中止却被中断了,这个中断源恰恰是 OST imTick类,要引起系统重新调度,这时发生的是抢占式调度,抢占式调度是实时系统实现的法宝,也是μC/OS-II的特色[4]。对于前者,它所调用的放弃 CPU的函数最后会调用一个 OS自己使用的函数 OS_Sched(),这个函数找到下一个可以立即执行的最高优先级任务,把他的 TCB指针放在全局变量 OSTCBHighRdy里,然后调用一个宏 OS_TASK_S W(),这个宏实际上被定义为 os_CPU_a.s中的函数 OSCtxSw()。OSCtxSw()的任务:保存当前任务上下文,装入新任务上下文。伪代码如下:

void OSCtxS w(void)

{

保存处理器寄存器;

将当前任务的堆栈指针保存到当前任务的 OS_TCB中:

OSTCBCur->OSTCBStkPtr=Stack pointer;

调用用户定义的 OSTaskSwHook();

OSTCBCur=OSTCBHighRdy;

OSPrioCur=OSPrioHighRdy;

得到需要恢复的任务的堆栈指针;

Stack pointer=OSTCBHighRdy->OSTCBStkPtr;

将所有处理器寄存器从新任务的堆栈中恢复出来;

执行中断返回指令;

}

OSIntCtxSw()就是刚才提到的第二种情况,在中断中发生调度时用到。如果一个中断需要从中断服务程序中进行调度,μC/OS-II的文档给出了这种调度的处理方法:一旦有这种中断发生,就保存正在运行任务的上下文,然后处理中断,之后调用一个操作系统提供的在 ISR中使用的Mutex、Mai lBox之类的服务函数,在这些函数的最后都会调用OSIntExit(),在这里发生了调度,OSIntExit()找出可以运行的最高优先级任务,把他的 TCB指针放在 OSTCBHighRdy里,最后如果需要调度,OSIntCtxSw()被调用。ARM硬件的中断时续并不自动压栈任何寄存器,所以免去了恢复堆栈指针的麻烦[5];另外,在进入 ISR保存当前任务现场时一同保存好 TCB中的堆栈指针,而不是在 OSIntCtxSw()中保存。下面是这个函数的伪代码:

void OSIntCtxSw(void)

{

调整堆栈指针去掉在调用;

OSIntExit();

OSIntCtxSw()过程中压入堆栈的多余内容;

将当前任务堆栈指针保存到当前任务的 OS_TCB中:

OSTCBCur->OSTCBStkPtr=堆栈指针;

调用用户定义的 OSTaskSwHook();

OSTCBCur=OSTCBHighRdy;

OSPrioCur=OSPrioHighRdy;

得到需要恢复的任务的堆栈指针:

堆栈指针 =OSTCBHighRdy->OSTCBStkPtr;

将所有处理器寄存器从新任务的堆栈中恢复出来;

执行中断返回指令;

}

OSTickISR()是μCOS-II抢占式调度 ISR的一个标本。当一个优先级高的任务放弃 CPU使用权,例如要休眠 10个 Tick,系统调度一个低优先级的任务执行之。OSTickISR()为休眠的任务计时,每次执行,就把休眠任务剩余的睡觉时间减去一个 Tick数。如果发现一个任务睡够了,就顺便恢复它为 READY态。OSIntExit()从所有已经 READY的任务中,选择一个优先级最高的,恢复现场并往下执行。所以可以相信,10个 Tick之后,恢复到那个高优先级的任务现场,然后执行它。伪代码为:

void OSTickISR(void)

{

保存处理器寄存器;

调用 OSIntEnter()或者直接将 OSIn tNesting加 1;调用OST imeTick();调用OSIntExit();恢复处理器寄存器;执行中断返回指令;

}

2.2.3 关于 OS_CPU_C.C

μC/OS-II的移植要求编写 6个简单的 C语言函数。唯一必要的函数是 OSTaskStkInit(),其他五个函数必须得声明但没有必要包含代码。

OSTaskCreate()和 OSTaskCreateExt()是通过调用 OSTaskStkInit()来初始化堆栈的,因此,此时的堆栈看起来就同刚发生过中断、并将所有的寄存器保存到堆栈中的情况一样。

每个任务都是一个函数,执行这个任务就是调用这个函数。我们设想,这个任务的函数是 void Task1(void*pdata),执行这个任务就是用 BL指令来调用函数,执行完 BL指令,中断发生了,源代码文件为 os_CPU_c.c,其中的 OSTaskStkInit()就改写成:

/*注意上面一行,task1的第一个参数放这里,这是符合 ARM调用规范的,就是说,规范要求汇编程序在 BL指令之前,传递给函数的第一个参数要放在 R0里。记住我们的堆栈是刚刚执行完 BLTASKn之后的状态*/

经过上述这些移植工作,μC/OS-II就可以在 S3C44BOX上开始工作了。

3 结束语

嵌入式操作系统的移植是一件很繁琐的工作,开发人员要耗费很多时间和精力。本文实现了在S3C44BOX平台上对μC/OS-II的移植,对移植过程进行了深入的研究,研究成果具有一定的实用价值,对其它嵌入式操作系统的移植也有一定的参考作用。

[1]拉伯罗斯.嵌入式实时操作系统μC/OS-Ⅱ[M].2版,邵贝贝,译.北京:北京航空航天大学出版社,2005:27-34.[2]任哲.嵌入式实时操作系统μC/OS-II原理及应用[M].北京:北京航空航天大学出版社,2005:13-24.

[3]黄燕平.uC/OSARM移植要点详解[M].北京:北京航空航天大学出版社,2005:391-396.

[4]周立功.ARM嵌入式系统基础教程[M].北京:北京航空航天大学出版社,2005:365-368.

[5]田泽.嵌入式系统开发与应用实验教程[M].北京:北京航空航天大学出版社,2004:86-89.

Study forμC/OS-Ⅱ TransplantMethod Based on S3C44B0X Processor

L IXing-xia
(Institute of Technology,JiamusiUniversity,Jiamusi 154007,China)

This article hasmainly studied the embedded operating systemμC/OS-ⅡOnARM7 transplantmethod.First,has analyzedμC/OS-ⅡSoftware and hardware architecture.Then,in based on ARM7 construction Samsung in S3C44B0X hardware platfor m,successfullyμC/OS-Ⅱtransplants to the S3C44B0X processor.In the article explained in detailμC/OS- Ⅱtransplant process,has given the transplant concrete method and the step.This article designs not only the transplant method causes the system speed to be quick,stable property,moreover the simplicity of operator,has the very high use value.

computer software;transplant;experiment;μC/OS- Ⅱ;embedded operating system;S3C44BOX

TP316.2

A

2095-0063(2011)03-0028-04

2010-11-25

李兴霞 (1972-),女,黑龙江宝清人,佳木斯大学应用技术学院讲师,从事嵌入式系统研究。

佳木斯大学科学技术研究项目 (L2009-159)。

猜你喜欢
堆栈指针调用
核电项目物项调用管理的应用研究
偷指针的人
娃娃画报(2019年5期)2019-06-17 16:58:10
LabWindows/CVI下基于ActiveX技术的Excel调用
测控技术(2018年5期)2018-12-09 09:04:46
嵌入式软件堆栈溢出的动态检测方案设计*
为什么表的指针都按照顺时针方向转动
基于堆栈自编码降维的武器装备体系效能预测
基于系统调用的恶意软件检测技术研究
基于改进Hough变换和BP网络的指针仪表识别
电测与仪表(2015年5期)2015-04-09 11:30:42
ARM Cortex—MO/MO+单片机的指针变量替换方法
利用RFC技术实现SAP系统接口通信