uCOS移植

2024-07-22

uCOS移植 篇1

一、系统的硬件架构

LPC1343是飞利浦公司生产的基于第二代ARM Cortex-M3内核的微控制器。最高运行频率达到72M.LPC1343配置有32KB的Flash存储器、8KB的数据存储器、集成了USB设备、1个快速模式I2 C接口、1个UART、4个通用定时器。

内嵌NVIC控制器,该中断控制器可对低优先级中断进行延时,对外部中断进行有效控制。中断向量表可重定位,具有软中断向量,适合于在使用操作系统时进行模式切换。

System Tick定时器,可产生固定的10ms中断,适合于作为操作系统的时钟信号。

二、UCOS-II简介

UCOS-II是一个可裁减的、抢占式、实时多任务内核,具有高度可移植性,特别适合于微处理器和控制器。U-COS-II绝大多数代码使用ANSI C语言进行开发。仅与CPU硬件相关部分是用汇编语言编写的,总量约200行,目的是便于移植到任何一种CPU上。UCOS-II仅仅包含了任务调度,任务管理,时间管理,内存管理和任务间的通信和同步等基本功能。不提供输入输出管理,文件系统,网络等额外的服务。用可户根据需要自行实现。

UCOS-II的架构可以分为三层,底层为物理层,主要是嵌入式系统硬件的驱动包括系统的时钟信号。中间层为系统层,用于对任务的管理,它提供了邮箱,信号量,消息队列同步信号。可以根据需要通过配置os_cfg_r.h里定义的宏对UCOS-II进行裁剪。最高层为应用层,使用者可根据系统提供的API函数创建任务完成应用工作。

三、移植的主要工作

移植UCOS-II时主要解决以下几个问题:第一.系统时钟信号怎么产生;第二.初始的任务堆栈是什么结构,任务堆栈是递增堆栈还是递减堆栈;第三.哪些变量需要保存到堆栈;第四.怎么处理临界段代码;第五.任务之间如何切换。

我们使用System Tick定时器作为系统的时钟,时钟频率为100Hz,当系统的任务已知时,可以对该值进行调节使系统的负荷和响应速度达到一个平衡。发生中断时,系统对当前的任务状态进行裁决,以决定是否要进行任务切换。时钟的初始化代码可用C语言编写。

任务堆栈有两种结构,递减堆栈和递增堆栈,递减堆栈就是堆栈从高地址向低地址方向增长,递增堆栈就是堆栈从低地址向高地址方向增长。LPC1343的堆栈为递减堆栈。

LPC1343在发生中断时,需要保存的寄存器依次有堆栈指针,x PSR状态寄存器,链接寄存器R14,R12,R3-R0,R11-R4。当然这些寄存器是否保存到堆栈里在实际中与中断程序的内容有关,但我们在移植UCOS时。必须假设新的任务将会使用到这些寄存器,因为操作系统要处理的任务对于我们来说是未知的。这个将在OSTask Stk Init函数中用到。

UCOS-II的任务有5种状态,分别为睡眠态,挂起态,就绪态,运行态,中断态。任务一旦创建即进入就绪态,如果处于就绪态的任务优先级比正在运行的任务优先级高,则发生中断,优先级高的任务得以运行,而被中断的任务则处于中断态,当该高优先级的任务执行完毕且就绪任务的优先级没有中断态任务的优先级高时,中断态的任务重新进入运行态。当运行态的任务等待某事件发生时则进入挂起态。处于挂起态的任务当某事件发生时进入就绪态。当任务被删除时,进入休眠态。处于中断态的任务不能被删除,否则将引起系统崩溃。

任务的切换有两种情况,第一种是高优先级的任务因等待某事件的发生而请求挂起,使低优先级的任务得以运行,这种情况下通过调用OSCtx Sw函数进行任务切换。这种任务称为任务级任务;第二种情况是高优先级的任务出现,在System Tick中断服务程序中直接切换到高优先级的任务,这种任务称为中断级任务。中断级任务的切换通过OSInt Ctx Sw函数实现。OSCtx Sw的示例代码如下:

OSInt Ctx Sw函数也由汇编语言实现,由于代码同OS-Ctx Sw类似,这里不再列出。

临界段代码指的是系统执行的不可分割的代码,这些代码一旦执行就不允许从中打断,所以在执行临界段代码前必须关中断,在临界段代码执行结束后必须立即开中断,所以临界段代码必须精简,以确保系统的运行效率。进入和退出临界段代码的例程如下:

OS_ENTER_CRITICAL;进入临界段的示例代码

OS_EXIT_CRITICAL;退出临界段的示例代码

任务切换时首先将当前正在执行的任务的状态保存到当前任务的任务堆栈中,从待运行的新任务的任务堆栈中获取该任务的运行状态,执行新任务。CPU的内部寄存器越多,需要保存和获取任务状态时消耗的时间也越多,因此System Tick的最短时间不得小于这个切换所要消耗的时间。

本文定义了3个任务,分别为USB接收帧处理任务,应用处理任务,USB发送帧任务处理。当USB接收到应用层的命令时,进行接收帧处理;提取有效命令,进行应用命令处理;回送响应数据。任务之间通过邮箱进行同步。

uCOS移植 篇2

关键词:嵌入式;操作系统移植;UCOS

中图分类号:TP316文献标识码:A文章编号:1006-8937(2012)05-0068-01

由于基于ARM7内核的各种芯片之间有着很大的差异,这些差异主要表现在存储系统不同、片内外设不同、中断源不同等。这就造成了嵌入式操作系统移植的不可避免性,而嵌入式操作系统移植效果的优劣直接影响着目标系统的整体质量。文中采用LPC2000系列ARM7微控制器以及ADS编译器对UCOS-II的移植过程进行了测试研究。

1UC/OS-II的移植步骤

UC/OS-II是一个占先式的实时多任务内核,由ANSI C语言编写,包含小部分汇编代码供不同架构的处理器使用,能够管理64个任务,主要系统功能包括:内存块管理、任务管理、消息队列管理、信号量、互斥信号量、事件标志组、消息邮箱等。从移植UCOS-II的过程来看,逻辑上可分作三大组成部分:与处理器无关的内核代码、与处理器有关的核心代码、与软硬件环境设置有关的配置代码。其中与处理器无关的内核代码主要包括OS_CORE.C、OS_FLAG.C、OS_MBOX.C、OS_MEM.C、OS_MUTEX.C、OS_Q.C、OS_SEM.C、OS_TASK.C、OS_TIME.C、UCOS_II.C、UCOS_II.H,它们主要实现任务管理、信号量、内存管理、消息队列、系统调度等功能;与处理器有关的核心代码主要包括OS_CPU.H、OS_CPU_A.ASM、OS_CPU_C.C,它们主要与操作系统的移植相关;与软硬件环境设置有关的配置代码主要包括OS_CFG.H、INCLUDES.H,它们主要用于剪裁和设置操作系统。以上文件名为UCOS-II的默认设置,无须严格按照上述名称命名文件。

由UCOS-II的逻辑结构可以看出,其移植工作主要集中在与处理器有关的核心代码部分。实际测试中遵循了如下步骤。第一,对OS_CPU.H进行移植,这部分工作主要包括:首先定义与处理器有关的数据类型,如BOOLEAN、INT8U、INT8S等;其次进行与处理器有关的宏定义主要包括OS_ENTER_CRITICAL以及OS_EXIT_CRITICAL;再次编写软中断函数主要包括OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()。第二,对OS_CPU_A.ASM进行移植,依据ADS编译器扩展名规则将文件名改为OS_CPU_A.S,主要工作是编写4个汇编语言函数,名称为OSStartHighRdy()、OSCtxSw()、OSIntCtxSw()、OSTickISR()。USOS-II启动时调用OSStart(),而OSStart()又调用OSStartHighRdy()运行优先级最高的任务。第三,移植OS_CPU.H。在OS_CPU_C.C文件中,需要编写以下10个C函数,名称分别为OSTaskStkInit()、OSTaskCreateHook()、OSTaskDelHook()、OSTaskSwHook()、OSTaskIdleHook()、OSTaskStatHook()、OSTaskTickHook()、OSInitHookBegin()、OSInitHookEnd()、OSTCBInitHook()。任务堆栈初始化函数OSTaskStkInit的定义按照移植时规定的堆栈结构进行,其他九个函数按照设计要求编写,或者为空。

2UCOS-II移植的技术要点

2.1数据类型的处理

在C语言中常用的int、short等数据类型与处理器类型密切相关,这就意味着采用上述类型定义后的程序本身具有不可移植性,为此在代码编写中需要采用移植性强的数据类型进行替换,因此这些数据类型定义也便成了代码移植工作的一部分,当然依编译器的选择不同也会略有差异,在ADS编译器中部分相关参考代码如下:

typedef unsigned char BOOLEAN;

typedef unsigned char INT8U;

typedef signed char INT8S;

typedef unsigned short INT16U;

typedef signed short INT16S;

typedef unsigned int INT32U;

typedef signed int INT32S;

2.2任务与函数调用的封装

ARM7内核具有7中工作模式,带T后缀的具有两套指令集,在提升处理器功能和效率的同时也带来了复杂性。在移植过程中应设法编制接口函数将底层复杂性与操作系统层的管理和应用隔离开,为了达到这个目的可以采用软件终端SWI(software interruption),而且在ADS编译器中也提供了相应的支持,即__swi关键字。采用该关键字声明一个莫须有的函数,调用时则在该处插入SWI指令,且可以设定中断功能编号,以及完成参数传递等。比如:

__swi(0x00) void OS_TASK_SW(void)/*任务切换函数*/

__swi(0x00) void _ OSStartHighRdy(void) /*运行顶级优先任务*/

__swi(0x00) void _ OS_ENTER_CRITICAL (void) /*关中*/

__swi(0x00)void_OS_EXIT_CRITICAL(void)/*开中*/

2.3中断服务的切换

如果在OS_CPU.H做过相应的声明,采用OS_TASK_SW函数切换任务,则函数OSCtxSw是可以省略的,所以通常情况下OSCtxSw并不是移植初期需要关注的要点。前文提到基于ARM7的不同芯片之间的中断系统存在差异,这就要求移植后的操作系统要保证目标机的中断系统稳定运行保障系统的可靠性。而在中断服务程序中切换任务时需要调用函数OSIntCtxSw,因此OS_CPU_A.S的移植要点在与保证OSIntCtxSw准确性,其代码主要任务包括保护现场、将当前任务堆栈指针保存到对应的任务控制块TCB(task control block)、获取新任务的堆栈指针等。OS_CPU_A.S中的__ OSStartHighRdy()与之存在调用关系,OSStartHighRdy()须在OS_CPU_C.C中定义。部分相关代码如下:

OSIntCtxSw_OSHR

获取新任务堆栈指针

LDR R4,[R6]

ADD SP,R4,#68;

LDR LR,[SP, #-8]

MSR CPSR_c,#(NoInt|SVC32Mode);切换至管理模式

MOV SP,R4;设置堆栈指针

LDMFD SP!,{R4, R5};CPSR,关中次数

恢复新任务的关中计数器

LDR R3,=IECounter;为关中计数器分配寄存器

STR R4,[R3]

MSR SPSR_cxsf,R5;恢复CPSR

LDMFD SP!,{R0-R12, LR, PC }^;运行新任务

关中计数器为全局变量,不同的任务由各自的关中计数器,在任务切换时分别堆栈互不影响,从而隔离了任务切换时可能造成的相互影响。

3结语

嵌入式操作系统的移植往往是影响全局且复杂性较强的工作。这类系统的移植也必然要建立在移植者对整体软硬件系统有深入准确的掌握基础之上。文中针对UCOS-II结合ARM7内核处理器以及ADS编译器测试并总结了移植的步骤和部分技术要点,此类工作需要丰富的实践和理论研究才能日臻完善。文中所论有很多不足之处和不全面的地方,需要在日后的实践中不断更正总结。

参考文献:

[1] 武国平,史仪凯.ARM7处理器Bootloader的设计与实现[J].

微处理机,2010,(5).

[2] 周立功.ARM嵌入式系统基础教程[M].北京:北京航空航

天大学出版社,2006.

[3] 宁杰城,王春,周新志.ARM7内核上的uC/OS—II嵌入式系

统移植[J].中国测试技术,2005,(2).

上一篇:长期大强度训练论文下一篇:大学教育不是职业训练