实时操作系统μC/OS-II在MCF5272的移植

发布者:Yaqi最新更新时间:2018-02-03 来源: eefocus关键字:实时操作系统  μC  OS-II  MCF5272  移植 手机看文章 扫描二维码
随时随地手机看文章

  介绍了实时操作系统μC/OS-II的特点和内核结构,并首次实现μC/OS-II在Motorola嵌入式处理器MCF5272上的移值。
  
  作为一个实时内核,μC/OS从1992年开始为人们熟悉,到现在已经发展为μC/OS-II。ΜC/OS-II最多支持56个任务,其内核为占先式,总是执行就绪态的优先级最高的任务,并支持Semaphore(信号量)、Mailbox(邮箱)、Message Queue(消息队列)等多种常用的进程间通信机制。与大多商用RTOS不同的是,μC/OS-II公开所有的源代码,并可以免费获得,对商业应用收取少量LICense费用。一般商用操作系统如VxWorks、pSOS、WinCE,购买费用动辄数万美元,而且每件产品都需要交纳运行费,开发、使用成本高昂。
  
  目前MCF5272是Motorola公司一款集成度最高的ColdFire处理器,采用ColdFire V2可变长RISC处理器核心和DigitalDNA技术,在66MHz时钟下能够达到63Dhrystone2.1MIPS。其内部SIM(System Integrated Module)单元集成了丰富的通用模块,如10/100MHz快速以太网控制器,USB1.1接口等,并且能够与常用的外围设备(如SDRAM、ISDN收发器)实现无缝连接,从而简化了外围电路设计,降低了产品成本、体积和功耗。
  
  使用GNU工具链(包括交叉编译器GCC、汇编器AS等)进行μC/OS-II内核的编译,Host(宿主机)环境为16MB SDRAM。在宿主机上编译出MCF5272处理器的可执行代码,通过MCF5272的BDM调试工具下载到目标板调试运行。
  
  1 μC/OS-II系统结构
  
  图1说明了μC/OS-II的软硬件体系结构。应用程序处于整个系统的顶层,每个任务都可以认为自己独占了CPU,因而可以设计成为一个无限循环。μC/OS-II处理器无关的代码提供μC/OS-II的系统服务,应用程序可以使用这些API函数进行内存管理、任务间通信以及创建、删除任务等。


  
  大部分的μC/OS-II代码是使用ANSI C语言书写的,因此μC/OS-II的可移植性较好。尽管如此,仍然需要使用C和汇编语言写一些处理器相关的代码。μC/OS-II的移植需要满足以下要求:
  
  (1)处理器的C编译器可以产生可重入代码;
  
  (2)可以使用C调用进入和退出Critical Code(临界区代码);
  
  (3)处理器必须支持硬件中断,并且需要一个定时中断源;
  
  (4)处理器需要能够容纳一定数据的硬件堆栈;
  
  (5)处理器需要有能够在CPU寄存器与内存和堆栈交换数据的指令。
  
  移值μC/OS-II的主要工作就是处理器和编译器相关代码以及BSP的编写。
  
  2 μC/OS-II DSP编写
  
  BSP(板级支持包)是介于底层硬件和操作系统之间的软件层次,它完成系统上电后最初的硬件和软件初始化,并对底层硬件进行封装,使得操作系统不再面对具体的操作。
  
  为μC/OS-II编写一个简单的BSP。它首先设置CPU内部寄存器和系统堆栈,并初始化堆栈指针,建立程序的运行和调用环境;然后可以方便地使用C语言设置MCF5272片选地址(CS0~CS7)、GPIO以及SDRAM控制器,初始化串口(UART0)作为默认打印口,并向操作系统提供一些硬件相关例程和函数如dprintf(),以方便调试;在CPU、板级和程序自身初始化完成后,就可以把CPU的控制权交给操作系统了。
  
  MCF5272处理器将系统上电作为2号异常,因此需要在异常矢量表中相应位置填写第一条命令的物理地址,这可以在编译时自动完成。该矢量表必须存放在CS0对应的FLASH中供CPU上电时自动读取。如:
  
  _vectors: //矢量表起始地址
  
  .long 0x0,_start,_fault,_fault,… //初始化1K字节矢量表
  
  ……
  
  _start: nop //第一条指令
  
  move.w #0x2700,%sr //屏蔽所有中断
  
  move.1 #_vectors,%d0
  
  move.c %d0,%VBR //#vectors->VBR
  
  move.1 #0x10000001,%d0
  
  move.c %d0,%MBAR //SIM单元基地址0x10000000
  
  move.1 #0x20000001,%a0 //SRAM起始地址0x20000000
  
  move.c %a0,%RAMBAR0 //初始化内部SRAM
  
  move.1 #0x20001001,%a7 //设置堆栈指针
  
  ……
  
  jsr cpu_init //调用cpu_init初始化SIM单元
  
  jsr ucos_start //启动μC/OS-II
  
  ……
  
  其中,cpu_init函数用于初始化CPU内部SIM单元、SDRAM控制器、UART串口。值得注意的是SDRAM初始化,不同生产商的SDRAM的初始化时序有一定差异。
  
  BSP在完成片级和板级初始化后,还负责初始化程序自身,如将.data段的内容从只读的ROM复制到SDRAM中,建立运行时环境。以下是建立程序数据段的代码:
  
  mEMCpy(&_sdata,&_etext,(&_EDAta-&_sdata)); //拷贝.data段
  
  MEMSet(&_sbss,0,(&_ebss - &_sbss)); //将.bss段清零
  
  还需要为μC/OS-II编写4个简单的汇编函数。在每个硬件时钟到来后,μC/OS-II会在中断服务例程中调用OSINTCtxSw()进行任务调度;另外,当某个任务因等待资源而被挂起时,没有必要等到自己的时间片全都用完,可以自己主动放弃CPU,这可以通过调用一个任务级的任务调度函数OSCtxSw()来实现。其中相对复杂的是OSIntCtxSw()。由于OSTickISR()调用了OSIntExit(),OSIntExit()又再次调用了OSIntCtxSw(),如果进行任务切换,那么两次调用都不会返回,而不同的C编译器、不同的编译选项处理C调用时对堆栈的使用也不尽相同。因此OSIntCtxSw()是编译器相关的。GCC在使用2~4级优化时,在主调函数中会是一个jsr跳转指令,而被调函数以linkw %FP,#开始。这两条指令都会影响堆栈指针。为了实现任务切换,必须重新调整堆栈指针以补偿调用的影响。一个完整过程如下:
  
  OSIntCtxSw:
  
  adda.1 #16,%a7 //栈补偿,GCC-O2->-04优化
  
  move.1 (OSTCBCur),%a1
  
  move.1 %a7,(%a1) //OSTCBCur->OSTCBStkPtr=SP
  
  jsr OSTaskSwHook //调和Hook钩子函数
  
  /*OSTCBCur->OSTCBStkPtr=OSTCBHighRdy->OSTCBStkPtr*/
  
  move.1 (OSTCBHighRdy),%a1
  
  move.1 %a1,(OSTCBCur)
  
  move.b (OSPrioHighRdy),%d0
  
  move.b %d0,(OSPrioCur) //OSPrioCur=OSPrioHighRdy
  
  move.1 (%a1),%a7 //SP=OSTCBCur->OSTCBStkPtr
  
  movem.1 (%a7),%d0-%d7/%a0-%a6 //恢复CPU寄存器,切换到新任务
  
  lea 60(%a7),%a7
  
  rte
  
  篇幅所限,其它三个函数就不述了。
  
  3 μC/OS-II任务堆栈初始化
  
  μC/OS-II中每个任务都有自己的任务堆栈,在任务创建初期由OSTaskStkInit()初始化。初始化堆栈的目的就是模拟一次中断。任务堆栈中保存了任务代码的起始地址和一些CPU寄存器(初值是无关紧要的),这样一旦条件满足,就可以执行该任务了。MCF5272在中断发生时,会自动保存程序指针PC、状态寄存器SR以及其它一些信息,为四字帧结构。除此以外,%d0-%d7、%a0-%a6也必须按一定顺序入栈。OSTaskStkInit()在完成堆栈初始化后,还要返回栈顶指针以用于该任务控制块TCB结构的初始化。该程序使用C语言编写。
  
  4 μC/OS-II系统时钟
  
  MCF5272处理器内置了4个定时器,使用TIMER0产生周期10ms的定时中断作为系统时钟。当PIVR寄存器设置为0x40时,TIMER0为69号中断,在矢量表的相应位置需填入时钟服务程序OSTickISR()的入口地址,并初始化时钟:
  
  volatile unsigned short*pTimer;
  
  pTimer=(unsigned short*)(0x10000000+0x200); //指向TIMER0
  
  /*复位时钟*/
  
  *pTimer &=0xFFF9; //定时器处于STOP状态
  
  *pTimer=(*pTimer & 0x00FF)|0xFA00;//预分频=250
  
  *pTimer |=0x0018; //计数满自动清零,中断方式
  
  pTimer[2]=165; //Set TRR=165
  
  *pTimer=(*pTimer & 0xFFF9) |0x0004; //CLK=Master/16,启动
  
  上述程序段时钟节拍的周期为:(1/66MHz)×250×164×16=0.01秒。实时性要求高的场合可以使用更为精细的时钟。TIMER0一旦完成初始化,就开始工作,但是要让中断发生,还必须设置ICR寄存器相应字段给该中断分配IPL(Interrupt Priority Level,中断优先级),并保证该中断没有初状态寄存器SR屏蔽。
  
  该时钟初始化代码可以放在第一个μC/OS-II任务中,在OSStart()后执行。一旦内核可以进行正常的任务切换,移植工作也就基本完成了。
  
  5 内核编译与下载
  
  所有的C和汇编源文件经过编译、链接,最终形成一个二进制映像文件。由于μC/OS-II使用了自定义的数据类型,因此必须将其转变成为GCC(GNU C Compiler)能识别的类型,如INT8U可以定义为unsigned char。另外,还必须编写一个LD(链接脚本)文件控制编译,将程序定位到实际的ROM和RAM资源中。为了调试方便,通常是通过BDM工具将内核下载到目标板SDRAM中运行,调试通过后再固化到FLASH中。
  
  RTOS是当前嵌入式应用的特点。应用RTOS,可以使产品更可靠、功能更强大而开发周期更短。μC/OS-II有着良好的实时性和很小的代码量,并被广泛移植到x86、68K、ColdFire、MPC 8xx、ARM、MIPS、C5409等许多处理器上。数百个成功的商业应用实例说明μC/OS-II是一个稳定可靠的内核,因此将μC/OS-II移植到MCF5272具有很强的实用前景。


关键字:实时操作系统  μC  OS-II  MCF5272  移植 引用地址:实时操作系统μC/OS-II在MCF5272的移植

上一篇:基于高性能模拟器件简化便携式医疗设备原理及设计
下一篇:基于SHARC 2147x处理器的浮点数字信号处理

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

C51语言编程:单片机与 PC 串口通信程序
单片机接收PC机发来的指令信号,然后单片机又向PC机发送字符串。具体要求如下: 当接收指令信号为:'go',单片机向PC机发送字符串:WELCOME TO CHINA!; 当接收指令信号为:'who',单片机向PC机发送字符串:MY NAME IS LIMING; 当接收指令信号为:'home',单片机向PC机发送字符串: YINGYONGKEXUEXUEYUAN。 PC机上的串口调试软件,会在窗口显示出单片机送回来相应字符串; 如果接送的字符串不正确,单片机不响应。 采用C语言。 题目链接:http://zhidao.baidu.com/quest
[单片机]
c语言结构体的用法
1、一般用法(多数在一些C语言的书中常见) 声明结构体: struct s1 { int a; char b; }s2; //此时s1为结构体名称,s2为结构体变量,在使用时可以如下: s2.a = 3; //或者 struct s1 s3; s3.a = 3; //或者 s1 s4; s4.a = 3; //以上3种方法均可 2、带有typedef关键字的用法(在弄STM32单片机的时候,库函数里面的用法) 声明结构体:
[单片机]
USB Type-C 接口上的大统一?
近日,又有一家手机厂商确定他们的新产品将配备新USB Type-C接口,有关于USB Type-C接口的话题也是再次被大家热议起来。从去年年底的Nokia N1平板电脑,到今年苹果春季发布会上推出的新MacBook以及上月底Google宣布Android M也将支持该接口......这么一个不起眼的小接口,为什么会受到如此广泛的关注,它有能力肩负起下一个引领行业变革的重担么? 一、USB Type-C到底是个啥东西? 没有听说过太多关于USB Type-C的内容不要紧,相对于它来说大家应该对USB 2.0更熟悉一些。其实这些像 Type-C 、 2.0 、 3.0 这样的描述,也就是将USB(UniversalSeria
[嵌入式]
USB Type-<font color='red'>C</font> 接口上的大统一?
Keil c51指针变量
单片机c语言支持一般指针(Generic Pointer)和存储器指针(Memory_Specific Pointer)。 1. 1. 一般指针 一般指针的声明和使用均与标准C相同,不过同时还能说明指针的存储类型,例如: long * state;为一个指向long型整数的指针,而state本身则依存储模式存放。 char * xdata ptr;ptr为一个指向char数据的指针,而ptr本身放于外部RAM区,以上的long,char等指针指向的数据可存放于任何存储器中。 一般指针本身用3个字节存放,分别为存储器类型,高位偏移,低位偏移量。 2. 2. 存储器指针 基于存储器的指针说明时即指定了存贮类
[单片机]
基于stm32的I2C通讯
IIC(Inter-Integrated Circuit)总线是一种由 PHILIPS 公司开发的两线式串行总线,用于连接微控制器及其外围设备,是一种半双工的同步通讯方式,由数据线 SDA 和时钟 SCL 构成的串行总线,可发送和接收数据。在 CPU 与被控 IC 之间、 IC 与 IC 之间进行双向传送, 高速 IIC 总线一般可达 400kbps 以上。 关于半双工同步以及串行的相关解释在之前的博文中有详细的讲解,参考连接 通讯方式简介 I2C 总线在传送数据过程中共有三种类型信号, 它们分别是:开始信号、结束信号和应答信号。 开始信号: SCL 为高电平时, SDA 由高电平向低电平跳变,开始传送数据。 结束
[单片机]
基于stm32的I2<font color='red'>C</font>通讯
基于STC89C52RC单片机的无线呼叫系统设计
随着科技的进步以及生活质量的不断提高,人们要求在消费中得到的服务更加快捷、方便、舒适;同时处于激烈竞争中的服务性企业也需要进一步吸引顾客,提高企业自身的服务档次和形象。在这样的背景下,产生了各种不同类型的呼叫系统。传统的呼叫系统多是有线的,比如采用分布控制方式的单片机系统,主机和呼叫器的应答通过一根三芯导线,包括电源线、信号线、地线来完成,各呼叫器并行挂接。这样的系统存在着布线繁琐,安装麻烦、成本高等问题,针对这些问题,无线呼叫系统逐渐发展起来,越来越多的研究者将目光投向了无线领域。 1 系统设计方案 低功耗无线呼叫系统的发送和接收模块的框图如图1,图2所示。 其中图1为无线发送模块,以STC89C52RC为主控制
[单片机]
基于STC89<font color='red'>C</font>52RC单片机的无线呼叫系统设计
基于FPGA视频采集中的I2C总线设计与实现
随着科学技术的发展和现代战争条件的变化,传统图像信号提供的单一服务已远远不能满足现代战争的需要。图像信号由于包含有极其丰富的信息,具有通信效率高、便于记录、形象逼真、临场感强等特点,所传送的信息量远远超过其他通信手段,所以得到越来越多的重视。在JPEG2000系统下,视频采集系统是视频采集功能的FPGA(现场可编程门阵列)前端系统,是视频图像处理、应用的前项通道。作为视频采集系统的重要组成部分I2C(Inter Integrated Circuit)总线,早在20世纪80年代由荷兰Philips公司研制开发成功。它是一种简单、双向二线制同步串行总线硬件接口。 1I2C总线的特点和协议   I2C总线协议作为一个串行总线标
[安防电子]
基于FPGA视频采集中的I2<font color='red'>C</font>总线设计与实现
氢燃料电池汽车走进C端,咋就这么难?
“氢 燃料电池汽车 大规模商业化,比L4落地还难。” 上述言论,大抵可一语道出业内大多数人对氢燃料电池汽车未来前景的看法:即有前景,但前景很远…… 此略显悲观的判断,从氢能相关企业的股市表现可见一斑。 据悉,截至目前,国内氢能源相关上市企业,只有亿华通和国鸿氢能两家。其中,亿华通是我国最早投身氢能领域的企业,主业是氢燃料电池发动机系统研发及产业化,2020年8月成功在上交所科创板挂牌上市,2023年1月又登陆港股,实现两地上市。2023年11月,国鸿氢能在港交所主板挂牌上市,成为我国的“氢能第二股”,该公司主营业务是氢燃料电池的研发、生产和销售。 具体从上述两家公司的股市表现来看,去年1月港股上市之时,亿华通全球发
[汽车电子]
氢燃料电池汽车走进<font color='red'>C</font>端,咋就这么难?
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

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

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