DIY编程器网

 找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 176|回复: 0
打印 上一主题 下一主题

一种实时操作系统μC/OS-II在LPC2114上移植的实现

[复制链接]
跳转到指定楼层
楼主
发表于 2012-1-27 13:59:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

                      传统的嵌入式系统设计大多采用单任务顺序机制,应用程序是一个无限的大循环,所有的事件都按顺序执行,与时间相关性较强的事件靠定时中断来保证,由此带来系统的稳定性、实时性较差;尤其当系统功能较复杂,且对实时性要求较严格时,这种单任务机制的弱点暴露无遗。本文引入的嵌入式操作系统μC/OS-II是一个多任务的实时内核,主要提供任务管理功能。在实时系统中的多个任务,必须决定这些任务的优先级顺序,任务调度算法需要动态为就绪任务的优先级排序。为了满足对实时性要求越来越高的需要,同时避免频繁改变就绪任务的优先级,在分析μC/OS-II源代码的基础上,对其调度算法进行改进。
  LPC2114是Philips公司开发的一款支持实时仿真和跟踪的ARM7TDMI-S CPU,并嵌入了128KB的高速Flash存储器。其内部集成了与片内存储器控制器接口的ARM7局部总线、与中断控制器接口的AMBA高性能总线(AHB)和连接片内外设功能的VLSI外设总线(VPB,ARM AMBA总线的兼容超集)。LPC2114将ARM7TDMI-S配置为小端(little-endian)字节顺序。128位宽度的存储器接口和独特的加速结构使32位代码能够在最大时钟频率下运行。
  将μC/OS-II移植在LPC2119上不仅有益于ARM和μC/OS-II在车用控制器上的应用,其成果还可以用于其他嵌入式工业控制领域。本次移植中,使用CodeWarrior For ARM Developer Suite v1.2编译调试环境。
  1? μC/OS-II系统结构
  μC/OS-II是一个完整的,可移植、可固化、可裁剪的占先式实时多任务内核;支持56个用户任务,支持信号量、邮箱、消息队列等常用的进程间通信机制;适用于各种微控制器和微处理器;所有代码用ANSI C语言编写,程序的可读性强,具有良好的可移植性,已被移植到多种处理器架构中,在某些实时性要求严格的领域中得到广泛应用。
  图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 BSP的编写
  BSP是板级支持包,是介于主板硬件和操作系统之间的一层,应该说是属于操作系统的一部分,主要目的是为了支持操作系统,使之能够更好的运行于硬件主板。BSP是相对于操作系统而言的,不同的操作系统对应于不同定义形式的BSP,例如VxWorks的BSP和Linux的BSP相对于某一CPU来说尽管实现的功能一样,可是写法和接口定义是完全不同的,所以写BSP一定要按照该系统BSP的定义形式来写(BSP的编程过程大多数是在某一个成型的BSP模板上进行修改)。这样才能与上层OS保持正确的接口,良好的支持上层OS.
  为μC/OS-II编写一个简单的BSP的方法是:首先设置CPU内部寄存器和系统堆栈,并初始化堆栈指针,建立程序的运行和调用环境;然后使用C语言设置LPC2114向量中断控制器、GPIO以及SRAM控制器,初始化串口(UART0)作为默认打印口,并向操作系统提供一些硬件相关例程和函数(如dprintf( )),以方便调试;在CPU、板级和程序自身初始化完成后,就可以把CPU的控制权交给操作系统了。
  LPC2114处理器支持七种类型的异常。异常出现后,CPU强制从异常类型对应的固定存储地址开始执行程序,因此需要在程序头建立起异常向量表,例如:

 





?
  向量从上到下依次为复位、未定义指令异常、软件中断、预取指令中止、预取数据中止、保留的异常、IRQ和FIQ.保留的异常向量位置所填的数据0xb9205f80是为了使向量表中所有的数据32位累加和为0.这个向量在ARM文件中标识为保留,该位置被Boot装载程序用作有效的用户程序关键字。当向量表中所有的数据累加为0(且外部硬件禁止进入ISP程序)时,Boot装载程序将执行用户程序。
  从异常向量表可知:芯片复位时程序会跳转到标号Reset处。程序首先调用InitSTack初始化各种模式的堆栈,然后调用TargetResetInit对系统进行基本的初始化,最后跳转到ADS提供的启动代码__main.例如:
  Reset
  BL InitStack
  BL TargetResetInit
  B__main
  同时在每个硬件时钟到来后,μC/OS-II会在中断服务例程中调用OSIntCtxSw( )进行任务调度。另外,当某个任务因等待资源而被挂起时,它可以自己主动放弃CPU,而没有必要等到自己的时间片全都用完。这可以通过调用一个任务级的任务调度函数OSCtxSw( )来实现,其中相对复杂的是OSIntCtxSw( )。由于OSLickISR( )调用了 OSIntExit( ),OSIntExit( )又再次调用了OSIntCtxSw( ),如果进行任务切换,则二次调用都不会返回,而不同的C编译器、不同的编译选项处理C调用时对堆栈的使用也不尽相同。因此OSIntCtxSw( )是与编译器相关的。在ADS编译环境下,OSIntCtxSw的软件流程如图2所示。

            
                   



  3? μC/OS-II 任务堆栈初始化
  μC/OS-II中每个任务都有自己的任务堆栈。在任务创建初期由OSTaskStkInit( )初始化。初始化堆栈的目的就是模拟一次中断。任务堆栈中保存了任务代码的起始地址和一些CPU寄存器(初值是无关紧要的),这样一旦条件满足,就可以执行任务了。LPC2114在中断发生时,会自动保存程序指针PC、状态寄存器SR以及其他一些信息。图3为针对LPC2114编程结构设计的堆栈结构。



  本次移植的函数OSTaskStkInt( )代码为:




?
  4? μC/OS-II系统时钟管理
  μC/OS-II需要在系统初始化时开始一个系统时钟节拍,它是OS系统的时间基准。该时钟节拍一般由时间中断产生。LPC2114中可产生时钟节拍的模块很多,本次移植采用定时器0异常。因为它与外部中断使用不同的异常向量,便于对异常事件的管理,有利于提高OS的稳定性。32位定时器TC的计数频率由plck经过PR分频控制得到,而定时器的启动/停止、计数复位由TCR控制。当有捕获事件或比较匹配事件发生时,IR会设置相关的中断标志,若已打开中断允许,则会产生中断。
  本次移植设置系统时钟频率为11.0592MHz,代码在时钟初始化和每次进入定时器0异常时,将定时器0的计数器PWMTC设置为11.0592M/OS_TICKS_PER_SEC,这样可使OS每秒钟产生OS_TICKS_PER_SEC的时钟节拍。
  5? 应用方法
  在使用移植后的OS时,用户需要编写自己的主程序main( ),其流程图如图4.在适当的初始化后即可启动OS.



  另外,用户需在TaskStart任务中启动时钟节拍,调用OS_StartInit( )函数初始化统计任务,创建所需的其他任务,最后调用OSTaskDel( )函数删除TaskStart任务。OS在该函数调用结束后,会自动允许异常和中断,OS正常运转,不断调度任务,响应中断。
            
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
收藏收藏 分享分享 支持支持 反对反对
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|文字版|手机版|DIY编程器网 ( 桂ICP备14005565号-1 )

GMT+8, 2024-9-25 04:26 , 耗时 0.083513 秒, 18 个查询请求 , Gzip 开启.

各位嘉宾言论仅代表个人观点,非属DIY编程器网立场。

桂公网安备 45031202000115号

DIY编程器群(超员):41210778 DIY编程器

DIY编程器群1(满员):3044634 DIY编程器1

diy编程器群2:551025008 diy编程器群2

QQ:28000622;Email:libyoufer@sina.com

本站由桂林市临桂区技兴电子商务经营部独家赞助。旨在技术交流,请自觉遵守国家法律法规,一旦发现将做封号删号处理。

快速回复 返回顶部 返回列表