典型范例:uCOSii在Coldfire MCF52235上的移植

发布者:TechGuru123最新更新时间:2018-04-01 来源: eefocus关键字:uCOSii  Coldfire  MCF52235  移植 手机看文章 扫描二维码
随时随地手机看文章

      引言

      C/ OS 是一种多任务实时操作系统。内核源代码公开、短小精干、可裁剪、执行时间可确定, 可移植性较强, 非常适用于一些中小型嵌入式系统开发。uC/OS 可以移植到8~ 64 位的不同类型、不同规模的嵌入式系统, 并能在大部分的8 位、16 位、32 位, 甚至64 位的微处理器和DSP 上运行[ 1] 。

    MCF52235 是飞思卡尔公司Co ldf ire 系列32 位单片机解决方案的嵌入式微控制器, 采用的是V2 版本的

    RISC 内核。MCF52235 内部有32 KB SRAM 和256 KB FLASH, 并且集成了标准的Coldfire 外围设备, 包括三个适合中长距离通信的SCI, 一个I2 C 和一个用于系统内部和外围设备通信的Q SPI。在60 Hz的核心频率下, MCF52235 的处理能力为56 MIPS, 具备较高的性能价格比[ 24] 。MCF52235 对于移植C/ OS 来说有足够的

    RAM 和FLASH, 且有较快的处理速度和较低的成本,所以对于嵌入式应用系统的开发来说, 嵌入C/ OS

    到MCF52235 微控制器是一个不错的选择。uC/ OS 的体系结构要实现C/ OS 向MCF52235 的移植, 需要做两方面的工作: 一是重新定义内核的大小和功能; 二是为内核编写与硬件相关的代码。C/ OS 的文件结构如图1 所示。可以看到, C/ OS 与CPU 类型无关的C 代码文件COS . C 包括很多文件, 它们是C/ OS 的内核和很多功能函数, 其中前三个文件是实时内核、任务管理和时钟节拍, 这三个文件是一定要用的。后面6 个功能函数用于任务间的通信, 应用程序中可能只用到其中

    的几个, 不用的可以不包含进去, 以免编译时生成没用的代码。这部分代码与CPU 类型无关, 在移植时, 这些文件不要改动。配置文件OS_CFG. H 需要根据应用要求来进行,主要作用是确定C/ OS 提供的系统功能函数, 应用

    程序用哪些和不用哪些, 这个文件移植时需要修改。与CPU 类型有关的代码文件主要有三个: OS _CPU. H, OS_CPU_A. ASM 和OS_CPU_C. C。文件定义用于特定CPU 的数据类型来定义相关的宏。OS _CPU_A . ASM 是用汇编语言写的与硬件有关的代码,OS_CPU_C. C 是用C 语言写的与硬件有关的代码。由于移植使用C 交叉编译工具, 在C 代码中可以插入汇编语句, 在移植中可将这两个文件合并成一个文件[ 5] 。

    产生时钟节拍的定时中断来自微控制器内部, 但并非来自V2 内核内部, 可以用实时时钟产生定时中断,

    也可以用片内的外设模块定时器单元来产生定时中断,这部分代码显然与硬件相关, 移植时要自己写[ 6] 。

     

image

     

    2 移植过程

    所谓移植, 就是使一个实时内核能在某个微处理器或微控制器上运行。为了方便移植, 大部分的C/ OS代码是用C 语言写的, 但仍需要用C 和汇编语言写一些与处理器相关的代码, 这是因为C/ OSII 在读写处理器寄存器时只能通过汇编语言来实现 。移植过程主要包括移植前的准备、BSP ( 板级支持包) 的编写和与处理器相关代码的修改和编写。C/OS 核心代码、与CPU 相关的接口程序、BSP 和用户应用程序之间的关系如图2 所示。

    2. 1 移植前的准备

    进入C/ OS 官方网站下载C/ OS 源代码。打开Codew arrior 6. 4 建立MCF52235 的工程文件, 然后把C/ OS 的源代码文件加入到工程里面[ 8] 。其中有几个地方需要改动:

    ( 1) 下载的源代码中os_cfg _r. h 改为o s_cfg. h;os_dbg_r. c改为os_dbg. c。

    ( 2) 由于会引起重复定义错误, 需要把源代码中重复包含的文件注释掉。

    ( 3) 需要在INT ERNAL_FLASH 模式下编译, 而不能在RAM 模式下, 否则会产生溢出错误。

     

image

     

    2. 2 编写BSP

    板级支持包( BSP) 是介于底层硬件和操作系统之间的软件层次, 负责进行系统启动后最初的硬件和软件

    初始化, 并对底层硬件进行封装, 使得操作系统不再面对具体的硬件[ 9] 。在此建立两个BSP 文件: BSP. ASM 和BSP. C。其中, BSP. ASM 中包含了汇编语言写的中断接口程序。BSP. C 中包含了硬件和软件的初始化程序和产生时钟节拍的中断服务程序。

    2. 3 与处理器相关代码的修改和编写

    有三个与处理器相关的文件, 即OS_CPU . H, OS_CPU _ A. ASM 和OS _ CPU _ C. C 需要修改。由于MCF52235 有eMAC 模块, 所以还需要编写OS_CPU _I. ASM 文件, 用来在任务切换和中断时以及中断返回

    时保存和恢复相关寄存器。

    2. 3. 1 OS_CPU. H 的移植

    OS_CPU. H 包含了一些与处理器和编译器相关的宏定义和数据类型定义。由于使用Codew arrior 编译

    器, shor t 类型是16 位的, int 类型是32 位的。MCF52235 的堆栈是32 位宽的, 因此OS_STK 定义为

    32 位, 所有任务的堆栈必须声明使用OS_ST K 这种数据类型。数据类型定义如下:

    ty pedef unsigned char BOOLEAN;

    ty pedef unsigned char INT 8U;

    ty pedef signed char INT8S;

    ty pedef unsigned sho rt INT16U;

    ty pedef signed shor t INT16S;

    ty pedef unsigned int INT32U;

    ty pedef signed int INT32S;

    typedef float FP32;

    typedef double FP64;

    typedef unsigned int OS_STK;

    typedef unsigned shor t OS_CPU_SR;

    ( 1) 临界区域处理。像所有的实时性内核一样, 在进入代码临界区时要关中断, 完成时要开中断。C/


    OS 定义了两个宏来关闭和使能中断: OS_ENT ER_CRITICAL( ) 和OS_EXIT _CRIT ICAL( ) 。C/ OS定义了三种方法来关闭和使能中断, 大多数情况下选择第三种方法。

    # define OS_CRITICAL_METH OD # 3

    # define OS_ENTER_CRITICAL( ) { cpu_sr = OS _CPU_

    SR_Save( ) ; } / / 关中断

    # def ineOS _ EXIT _ CRITICAL( ) { OS _ CPU _ SR_ Resto re

    ( cpu_sr) ; } / / 开中断

    ( 2) 任务层上下文切换。当C/ OS 调用OS _TASK_SW( ) 时发生任务层的上下文切换。因为上下

    文切换是根据处理器的不同而不同的, 所以需要执行一个汇编的函数。在这种情况下, 用TRA P 指令来产

    生一个异常, 用T RAP 指令的优点是能使它像发生了一次中断一样。这里用# 14 T RAP, 因为大多数情况

    下, # 15 TRAP 被调试和监控程序保留了。# 14TRAP 定位于VBR+ 0x00B8, 然后跳转到相应的地址。

    在这个向量处放置OSCtx Sw( ) 的地址。这个函数声明在OS_CPU_A. ASM 里。VBR 代表向量基址寄存器,

    包含异常向量表的基址, 程序开始时被初始化为0x00000000, 但是在运行时可以改变。

    # define OS_TASK_SW( ) asm( T RAP # 14; )

    ( 3) 堆栈的增长方向。MCF52235 的堆栈增长方向是从高地址向低地址, 因此OS _ST K_GROWTH 置

    为1。

    # define OS_STK_GROWTH 1

    2. 3. 2 OS_CPU _C. C 的移植

    OS_CPU_C. C 里面包含10 个比较简单的C 语言函数, 一般来说C/ OS 只需要OST askStkInit ( ) 。其他函数是用来让用户在自己的程序里扩展操作系统功能的。如果需要使用这些函数, 需要在OS_CFG. H 里设置OS_CPU _HOOKS_EN 为1。堆栈的初始化: OSTaskStkInit ( ) 虽然是用C 语言编

    写的, 但它是一个与CPU 硬件相关的函数。这个函数功能是初始化任务的堆栈, 由建立任务函数OSTask

    Create( ) 或扩展地建立任务函数OSTaskCreateExit ( ) 调用。任务堆栈初始化的实质就是模拟一次中断, 使堆栈看起来就像刚发生过中断一样。任务堆栈中保存了任务代码的起始地址和一些CPU 寄存器的值, 一旦条件满足, 就可以执行该任务。初始化后的任务堆栈结构如图3所示。

     

image

     

    2. 3. 3 OS_CPU_A. ASM 的移植

    这个文件包含5 个相当简单的汇编函数, 因为一般不能用C 语言来保存和恢复寄存器。

    ( 1) OS_CPU_SR_Save( )

    这个函数是通过保存中断屏蔽寄存器, 然后关闭中断来实现OS_CRITICAL_MET HOD # 3 的。当函数返回时, D0 包含了状态寄存器的内容, 里面包含当前的中断关闭状态。这个返回值被调用函数保存到变量

    cpu_sr 中。

    ( 2) OS_CPU_SR_Restore( )

    这个函数用来实现恢复中断屏蔽到调用OS _ENTER_CRITICAL( ) 之前的状态。也就是说调用OS_

    ENTER_CRITICAL( ) 之前中断是关闭的, 那么在OS_EXIT_CRITICAL( ) 之后, 中断是关闭的。

    ( 3) OSStartHighRdy( )

    这个函数被OSStar t ( ) 调用来运行优先级最高的任务。OSStar t ( ) 设置OSTCBHighRdy 指向优先级最高任务的OS _T CB。一旦从OSTaskSwHoo k( ) 返回,就把OSRunning 设为OS_T RU E, 它表明现在RT OS

    将要运行。从最高优先级任务的OS_T CB 中恢复堆栈指针, 然后从任务堆栈里取出CPU 寄存器。最后执行

    一个RET 指令, 这个指令可以从堆栈中弹出SR 和PC,现在的任务代码就开始执行。

    ( 4) OSCtx Sw( )

    当一个任务不再运行时就会发生一个任务级的任务切换, 比如任务调用一个延迟10 个时钟节拍的函数。

    这时, C/ OS 需要找出下一个最重要的任务准备去运行。OSCtx Sw ( ) 的功能是保存需要挂起的任务的CPU 寄存器和堆栈, 恢复需要运行任务的CPU 寄存器和堆栈。任务级上下文切换如图4 所示。

     

image

     

    ( 5) OSINTCtx Sw( )

    当中断服务函数完成时, 调用OSIntEx it ( ) 函数去决定是否有一个更重要的任务比被中断的任务更需要执行。这种情况下, OSIntEx it( ) 决定运行哪个任务, 然后调用OSIntCtx Sw ( ) 。这种情况下, 中断服务程序已经保存了被中断任务的CPU 寄存器, 而需要做的只是去恢复新任务的CPU 寄存器。

    2. 3. 4 OS_CPU _I. ASM 的编写

    如果用到增强的乘法累加单元( eMAC) 模块, 在上下文切换和中断时就应该保存和恢复eMAC 寄存器。保

    存和恢复eMAC 寄存器通过两个宏来实现[ 10] 。代码如下:

    . macro OS_EM AC_SAVE

    MOVE. L MACSR, D7

    CLR. L D0

    MOVE. L D0, M ACSR

    MOVE. L ACC0, D0

    MOVE. L ACC1, D1

    MOVE. L ACC2, D2

    MOVE. L ACC3, D3

    MOVE. L ACCEXT01, D4

    MOVE. L ACCEXT23, D5

    MOVE. L MASK, D6

    LEA 32( A7) , A7

    MOVEM. L D0D7, ( A7)

    . endm

    . macro OS_EM AC_REST ORE

    MOVEM. L ( A7) , D0D7

    MOVE. L # 0, MACSR

    MOVE. L D0, ACC0

    MOVE. L D1, ACC1

    MOVE. L D2, ACC2

    MOVE. L D3, ACC3

    MOVE. L D4, ACCEXT01

    MOVE. L D5, ACCEXT23

    MOVE. L D6, MASK

    MOVE. L D7, MACSR

    LEA 32( A7) , A7

    . endm

    2. 4 时钟节拍的产生

    最后还需要编写利用片内定时器产生时钟节拍的中断服务程序。C/ OS要求微控制器提供一个简单的时钟, 用于任务的延时等功能。在此利用可编程中断定时器来产生时钟节拍中断。在定时器中断服务程序中调用OSTimeTick( ) 就产生了系统所需要的时钟节拍。C/OS中产生中断后的中断处理程序如下所示:

    _BSP_TickISR:

    MOVE. W # 0x2700, SR

    LEA 60( A7) , A7


    MOVEM. L D0D7/ A0 A6, ( A7)

    OS_EMAC_SAVE

    MOVEQ. L # 0, D0

    MOVE. B ( _OSI ntNesting) , D0

    ADDQ. L # 1, D0

    MOVE. B D0, ( _OSI ntNesting)

    CMPI. L # 1, D0

    BNE _BSP_TICkISR_1

    MOVE. L ( _OSTCBCur) , A1

    MOVE. L A7, ( A1)

    _BSP_TickISR_1:

    JSR _BSP_T ickISR_H andler

    JSR _OSInt Ex it

    OS_EMAC_RESTORE

    MOVEM. L ( A7) , D0D7/ A0A6

    LEA 60( A7) , A7

    RTE

    3 任务的创建和移植代码的测试

    源程序移植完, 用户就可以试着制作自己的项目。编写任务代码, 与以前在前后台系统中基本相同, 不同

    的是要把每个任务独立编写成一个文件, 最后由主程序统一调度。为了测试是否移植成功, 用STaskCreateExt ( ) 创建了两个任务。一个任务使板上LED 每一秒闪动一次, 另一个任务是用片内A/ D 采样板上的加速度传感器信号, 并在数码管上显示出当前加速度数值。最后调用OSStar t( ) 启动多任务调度。

    3. 1 定义每个任务的堆栈大小

    OS_STK

    TaskStartStk[ T ASKSTART ST K_SIZE] ;

    OS_STK ADT askStk[ T ASKSTK_SIZE] ;

    然后在main( ) 函数里系统初始化:

    OSInit( ) ;

    3. 2 创建任务

    OST askCreateEx t( TaskStart, ( void * ) 0, ( OS _ ST K * )

    & T askStar tSt k[ T ASKSTARTST K_SIZE1] , T ASK _START _

    PRIO, TASK_START_PRIO, ( OS_ST K* ) & T askStart St k[ 0] ,

    TASK_ST ART_ST K_SIZE, ( vo id * ) 0, OS_TASK_OPT _ST K_

    CH K| OS_TASK_OPT_STK_CLR) ;

    OSTaskCreateExt ( ADT ask, ( vo id * ) 0, ( OS _ STK * )

    & ADTaskStk[ TASKST K_SIZE1] , ADTASK_PRIO, ADT ASK

    _ PRIO, ( OS _ ST K * ) & ADTaskStk [ 0] , TASK _ ST K _SIZE,

    ( vo id * ) 0, OS_TASK_OPT_STK_CHK) ;

    3. 3 系统启动运行

    OSStart( ) ;

    3. 4 测试结果

    测试代码经过编译下载到实验板上运行后, 通过实验板上显示的信息, 表示两个任务在交替运行, 说明移植工作是成功的, 如图5 所示。

     

image


关键字:uCOSii  Coldfire  MCF52235  移植 引用地址:典型范例:uCOSii在Coldfire MCF52235上的移植

上一篇:基于单片机的LED点阵控制设计方案
下一篇:基于单片机STCl2C2052AD的比例遥控控制系统设计

推荐阅读最新更新时间:2024-03-16 15:58

如何将ThreadX移植到STM32平台
现在一些小型系统中也往往有多任务处理的需求,这就为实时操作系统提供了用武之地。事实上国内外各种各样的RTOS有很多,而且基本都在走开源的路线,ThreadX也不例外,在这一篇中我们就来学习ThreadX初步应用并将其移植到STM32平台中。 1 、前期准备 在开始将ThreadX一直到STM32平台之间我们需要做一些前期准备。首先我们需要准备一个硬件平台,这次我们采用STM32F407IG控制单元来作为目标平台。其次我们需要准备一个该硬件平台下可以正常运行的裸机项目。这两点其实我们都已经具备了。 最主要的我们需要获得ThreadX的源码,这是我们移植它的基础。ThreadX的源码已经开源到Github上,其地址为:http
[单片机]
如何将ThreadX<font color='red'>移植</font>到STM32平台
移植MySQL到嵌入式ARM平台
因为MySQL5.5之后,编译是用的cmake不再使用./configure,因此,只好倒回支持./configure的版本来用,这里使用了文档上的5.1.51版本。进行如下步骤完成移植: 1) 下载mysql5.1.51: http://www.mirrorservice.org/sites/ftp.mysql.com/Downloads/MySQL-5.1/mysql-5.1.51.tar.gz 2) 安装编译器:用的是4.3.2的交叉编译器。gcc之类的都是ubuntu10.10自带的。 3) 编译PC版本的mysql备用 a) 解压mysql-5.1.51到/opt/mysql-5.1.51: tar zxv
[单片机]
基于Coldfire和uClinux的硬盘MP3
便携式闪存(Nandflash)MP3一路热销,闪存芯片也曾一度面临缺货,在这样的情况下,使用容量更大成本更低的硬盘作为存储介质的HDD-MP3播放器便应运而生。最为著名的硬盘MP3品牌苹果的iPOD系列硬盘MP3已经取得了极大的成功,在3年时间内总共卖出了超过1千万台。笔者所在的公司——华恒科技也开发了支持 Microdrive 微硬盘和1.8寸笔记本硬盘的MP3播放器解决方案,所采用的处理器是飞思卡尔半导体(Freescale,原Motorola半导体)的MCF5249。本文将就基于MCF5249的硬盘MP3产品设计作简单的介绍。 硬件设计   硬盘MP3播放器功能更加丰富、界面更加友善、操作更加灵活,可以支持更加复杂的文件系
[单片机]
基于<font color='red'>Coldfire</font>和uClinux的硬盘MP3
移植freeRTOS V10.2.0到stm32f103zet6
应用FPU 1、工程文件 startup_stm32f40_41xxx.s 新建一个 test.c 文件,并保存在 USER 文件夹下 2、工程文件夹 USER 文件夹专门用来存放启动文件(startup_stm32f40_41xxx.s)、工程文件(test.uvprojx)等不可缺少的文件, OBJ 则用来存放这些编译过程中产生的中间文件(包括.hex 文件也将存放在这个文件夹里面) SYSTEM文件夹,该文件夹由 ALIENTEK 提供,可以在光盘任何一个实例的工程目录下找到 3、工程分组 Target 目录树上点击右键 Manage Project Items 我没改文件夹,还是
[单片机]
<font color='red'>移植</font>freeRTOS V10.2.0到stm32f103zet6
MBED移植日记:gpio_api移植(基于STM32F107RC)
本文是继MBED串口API移植的又一篇系列文章,前阵子忙着赶项目,移植完了却没来得及写成文章来分享,今天来补上,一来可以温故知新,二来也可以献出自己的一点微薄之力。写的不好,移植的也不一定好,请大家多多指教。本文的gpio_api模块与mbed官方的会有一些不同,原因是加入了我个人理解的一些东西。 一、关联文件 1、ierror.h /* ************************************************************** file: ierror.c date: 2016-8-15 ver : 1.00.00 *****************************
[单片机]
u-boot移植(十三)---代码修改---裁剪及环境变量 一
一、内核裁剪   内核的裁剪首先就是修改我们的配置文件,即 include/configs/jz2440.h 文件,里面定义的很多宏,我们也许用不上的就要去掉。 1 /* 2 * (C) Copyright 2002 3 * Sysgo Real-Time Solutions, GmbH www.elinos.com 4 * Marius Groeger mgroeger@sysgo.de 5 * Gary Jennejohn garyj@denx.de 6 * David Mueller d.mueller@elsoft.ch 7 * 8 * Configuation settings for the
[单片机]
u-boot<font color='red'>移植</font>(十三)---代码修改---裁剪及环境变量 一
基于tiny4412的Linux内核移植 -- MMA7660驱动移植(九-2)
平台简介 开发板:tiny4412ADK + S700 + 4GB Flash 要移植的内核版本:Linux-4.4.0 (支持device tree) u-boot版本:友善之臂自带的 U-Boot 2010.12 (为支持uImage启动,做了少许改动) busybox版本:busybox 1.25 交叉编译工具链: arm-none-linux-gnueabi-gcc (gcc version 4.8.3 20140320 (prerelease) (Sourcery CodeBench Lite 2014.05-29)) 摘要 上一篇 博文在tiny4412上移植了MMA7660驱动程序,使用的是exynos4
[单片机]
基于tiny4412的Linux内核<font color='red'>移植</font> -- MMA7660驱动<font color='red'>移植</font>(九-2)
U-BOOT的启动流程及移植
摘要:嵌入式系统一般没有通用的bootloader,u-boot是功能强大的bootloader开发软件,但相对也比较复杂。文中对u-boot的启动流程作了介绍,详细给出了u-boot在S3C44B0开发板上的移植方法和步骤。 关键词:bootloader;u-boot;嵌入式系统;移植;S3C44B0 1 Bootloader及u-boot简介 Bootloader 代码是芯片复位后进入操作系统之前执行的一段代码,主要用于完成由硬件启动到操作系统启动的过渡,从而为操作系统提供基本的运行环境,如初始化CPU、 堆栈、存储器系统等。Bootloader 代码与CPU 芯片的内核结构、具体型号、应用系统的配置及使用的操作系统等
[嵌入式]
热门资源推荐
热门放大器推荐
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
  • 学习ARM开发(16)
    ARM有很多东西要学习,那么中断,就肯定是需要学习的东西。自从CPU引入中断以来,才真正地进入多任务系统工作,并且大大提高了工作效率。采 ...
  • 学习ARM开发(17)
    因为嵌入式系统里全部要使用中断的,那么我的S3C44B0怎么样中断流程呢?那我就需要了解整个流程了。要深入了解,最好的方法,就是去写程序 ...
  • 学习ARM开发(18)
    上一次已经了解ARM的中断处理过程,并且可以设置中断函数,那么它这样就可以工作了吗?答案是否定的。因为S3C44B0还有好几个寄存器是控制中 ...
  • 嵌入式系统调试仿真工具
    嵌入式硬件系统设计出来后就要进行调试,不管是硬件调试还是软件调试或者程序固化,都需要用到调试仿真工具。 随着处理器新品种、新 ...
  • 最近困扰在心中的一个小疑问终于解惑了~~
    最近在驱动方面一直在概念上不能很好的理解 有时候结合别人写的一点usb的例子能有点感觉,但是因为arm体系里面没有像单片机那样直接讲解引脚 ...
  • 学习ARM开发(1)
  • 学习ARM开发(2)
  • 学习ARM开发(4)
  • 学习ARM开发(6)
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved