LPC2132上移植_第1页
LPC2132上移植_第2页
LPC2132上移植_第3页
LPC2132上移植_第4页
LPC2132上移植_第5页
已阅读5页,还剩60页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、UOSii在ARM7 LPC2132上移植雷海华摘要:近年来,在单片机系统中嵌入操作系统已经成为人们越来越关心的一个话题,但很多软件是收费的,由于u C / O S 是一种免费公开源代码、结构小巧、具有可剥夺实时内核的实时操作系统,因而被使用频繁。本文通过对LPC2132硬件和源码公开的嵌入式实时操作系统ucos ii的分析,以lpc2132单片机为例,阐述了在单片机中移植ucosii,来运行多个任务,如测量当时的温度,用液晶显示,然后用传到PC机上,当温度过高,蜂鸣器自动报警等任务的运行,达到模拟PC机CPU温度过高自动关机,来说明ucosii移植的优缺点,以及在移植中应注意的问题,启动代码

2、的理解,解析代码的优化.关键字:硬件 编程 嵌入式 实时 ARM7Research and implementation of RtKernel uC/OS-II to ARM7 LPC2132Lei HaihuaAbstract: In recent years, single chip embedded operating system has become a topic of growing concern, but many of the software for a fee, since u C / OS is a free open source, compact structu

3、re, with real-time kernel can be deprived of real-time operating system, which is used frequently. Based on the LPC2132 hardware and open source operating system for embedded real-time analysis of ucos ii to lpc2132 microcontroller, for example, described in MCU transplantation ucosii, to run multip

4、le tasks, such as measuring the temperature at the time, with a liquid crystal display, and then PC, with the spread, when the temperature is too high, the sound operation of automatic alarm and other tasks, PC-CPU to simulate high temperature shut down automatically to show the advantages and disad

5、vantages ucosii transplantation, and transplantation should pay attention to the problem, start understanding the code, parse the code optimization.Keywords: Hardware Pprograming EC Real-time ARM7 目 录第一章 引言及ARM芯片11.1 Acorn RISC机器历史11.2 Arm内核31.2.1 Arm的编程模型61.2.2 控制逻辑121.2.3 启动代码理解121.3 Arm代码优化15第二章

6、UCOS ii202.1 ucosii分析202.1.1 任务运行222.1.2 任务通信262.1.3 内存动态分配332.2C/OS- 的测试34第三章 ucosii在arm上的移植363.1与cpu有关的文件363.1.1 OS_CPU.H363.1.2 OS_CPU_C.C373.1.3 OS_CPU_A.S393.2移植代码实现40第四章 结束语52参考文献:53附图:54附图1 本设计完整电路图:54附图2 PCB布线情况:55附图3 顶层布线情况:56附图4 底层布线情况:57附图5 UCOS在vc6.0上运行结果:58附表6 元件清单:59第一章 引言及ARM芯片l 早在20世

7、纪60年代,就已经有人开始研究和开发嵌入式操作系统。但直到最近,它才在国内被越来越多的提及,在通信、电子、自动化等需要实时处理的领域所曰益显现的重要性吸引了人们越来越多的注意力。但是,人们所谈论的往往是一些著名的商业内核,诸如VxWorks、PSOS等。这些商业内核性能优越,但价格昂贵,主要用于16位和32位处理器中,针对国内大部分用户使用的risc系列8/16/32位单片机,可以选择免费的ucos ii。通过在LPC2132上移植移植ucosii,移植bootload,ucosii的远行原理。在原理的分析中,通过理论的学习,理论结合实际,通过制作和调试实验板,其中多次用到单一分析法,单一调试

8、各个分支,然后系统综合所有任务,完成整个系统远行。论文第一章主要介绍lpc2132硬件结构和代码的编写;第二章讨论ucosii代码结构;第三章分析ucosii在arm板上的移植。1.1 Acorn RISC机器历史第一个ARM处理器是1983年10月-1985年4月间在英国剑桥Acorn Computer公司开发的。1985年4月26日,第一个ARM原型在英国剑桥的Acorn计算机有限公司诞生,由美国加州SanJoseVLSI技术公司制造。20世纪80年代后期,ARM很快开发成Acorn的台式机产品,形成英国的计算机教育基础。那时候ARM代表Acorn RISC Machine公司,并一直持续

9、到Advanced RISC Machine limited(后来将名称简化为ARM Limited)。1990年成立了Advanced RISC Machines Limited(后来简称为ARM Limited,ARM公司)。ARM 即Advanced RISC Machines的缩写,既可以认为是一个公司的名字,也可以认为是对一类微处理器的通称,还可以认为是一种技术的名字。以后的ARM2具有32位的数据总线、26位的寻址空间,并提供64 Mbyte的寻址范围与16个32-bit的暂存器。这些暂存器其中有一颗做为(word大小)程式计数器,其前面6 bits和后面2 bits用来保存处理器

10、状态标记(Processor Status Flags)。ARM2可能是全世界最简单实用的32位微处理器,其仅容纳了30,000个晶体管。而与现今大多数的 CPU 不同,它没有包含任何的高速缓存。20世纪90年代,ARM 32位嵌入式RISC(Reduced lnstruction Set Computer)处理器扩展到世界范围,占据了低功耗、低成本和高性能的嵌入式系统应用领域的领先地位。设计了大量高性能、廉价、耗能低的RISC处理器、相关技术及软件。技术具有性能高、成本低和能耗省的特点。适用于多种领域,比如嵌入控制、消费/教育类多媒体、DSP和移动式应用等。ARM将其技术授权给世界上许多著名

11、的半导体、软件和OEM厂商,每个厂商得到的都是一套独一无二的ARM相关技术及服务。利用这种合伙关系,ARM很快成为许多全球性RISC标准的缔造者。ARM架构是面向低预算市场设计的第一款RISC微处理器。ARM公司既不生产芯片也不销售芯片,它只出售芯片技术授权。基于 ARM 技术的微处理器应用约占据了 32 位 RISC 微处理器 75 以上的市场份额, ARM 技术正在逐步渗入到我们生活的各个方面。ARM是微处理器行业的一家知名企业,目前,总共有30家半导体公司与ARM签订了硬件技术使用许可协议,其中包括Intel、IBM、LG半导体、NEC、SONY、PHILIPS和国民半导体这样的大公司。

12、至于软件系统的合伙人,则包括微软、升阳和MRI等一系列知名公司。世界各大半导体生产商从ARM公司购买其设计的 ARM 微处理器核,根据各自不同的应用领域,加入适当的外围电路,从而形成自己的 ARM 微处理器芯片进入市场。ARM 是当前嵌入式领域最广泛使用的微处理器。ARM 芯片种类很多,都是采用英国ARM公司(前身是Acorn 公司)设计并授权的RISC 内核, ARM 内核的微处理器从ARM7 到最新的ARM11 等,具有高性能、低价格、通用性好等特点。最常见的是ARM7 和ARM9 这两个系列,ARM7 通常用于低成本方案,ARM9 通常用于性能要求较高的方案。各厂家根据自己的目标不同,在

13、ARM 内核的基础上扩充了不同的协处理器、外围接口等,方便嵌入式产品的设计。ARM 系列的微处理器已经完全不同于8位单片机时代的微处理器,性能提高很大,价格并不高,而软件系统的通用性相对单片机环境要好很多,开发模式也有极大改善。ARM7 是3 级流水线RISC 内核,以MIPS(百万指令处理每秒)表示的ARM7 运算能力指标的计算公式是主频 x 0.9,也就是说平均一条指令的执行只需要一个时钟周期略多一点的时间,约20ns(50MHz 主频条件下)。5 级流水线RISC 内核的ARM9 MIPS 指标计算公式是主频 x 1.1,也就是说一条指令的执行平均不到一个时钟周期就可以完成。50MHz

14、主频的ARM7芯片的MIPS 指标约为45MIPS(参见具体处理器的数据手册),该指标已经超过i486 的性能指标。这也是uCLinux 等从PC 环境的操作系统衍生来的系统能够在ARM7 这类微处理器上流畅运行的原因。通常这些ARM 芯片内还包含了网络等极为丰富的外设,而价格却非常低。而主频能达到200-400MHz 的ARM9 系列微处理器,性能已经超过i586(Pentium),外设更加丰富,性价比更好。1.2 Arm内核ARM模块表如下:图1.1 ARM模块示图一个简单的处理器可以由一些基本的部件构成,即:*程序计数器(PC)寄存器:用来保存当前指令的地址;*累加器(ACC)寄存器:用

15、来保存正在处理的数据;*算术逻辑单元(ALU):可以对二进制操作数进行若干操作,如加、减、增值等;*指令寄存器(IR):保存当前执行的指令;*指令译码器和控制逻辑:塔根据指令控制上述部件、产生所需的结果。一个处理器还有它自身的指令集,ARM就用精简指令集计算机(RISC,Reduced Instruction Set Computer),把简单的硬件和指令集结合起来,RISC具有这些优点:1.流水线:这是实现并行操作的最简单行式2.高时钟频率和单周期执行:RISC结构简单,它可以工作在较高的时钟频率,充分使用已有的存储器带宽。实际处理器中,外设挂在外设总线上,外设总线和系统总线之间有一个“桥”

16、,这个桥实际上就是一个硬件FIFO,用于两边交流信息和指令。如果仅仅是简单的编程情况下,按照上图的逻辑结构理解ARM7 处理器即可,但是在重要的内核组件代码中,则要仔细考虑外设总线和系统总线之间的数据传递问题。FIFO 是一种异步通讯的方式,这也是ARM 微处理器资料中谈到的虚假(spurious)中断产生的原因。桥接器在嵌入式处理器中很常见,PC 类的处理器中通常没有这类结构,而是在主板中设计桥接。例如读者可能在PC 主板中经常见到南桥、北桥的概念,就是此处桥接器的类似对应物。嵌入式处理器通常是在一个芯片内部集成了多种常用外设,也就是说如果用PC 环境来理解嵌入式环境,它的对应物实际上应该是

17、包括主板及板上设备在内的整个PC 机。当然这种对应关系仅仅是一个粗略的为了方便理解的大致描述,实际情况要复杂很多。这种FIFO 异步桥接结构是嵌入式处理器常见结构,并非ARM 处理器独有,因此虚假中断问题在嵌入式处理器中也是常见需要处理的现象。只是虚假中断出现的比例并不高,通常要在压力测试情况下,存在很高中断频率的时候才能比较明显地观察到。而且和具体设备相关,通常都要经受10 万千万次的中断冲击才会出现一次。但是在压力测试条件下,这种中断冲击并不难达到,可能10 分钟1 小时的测试就能观察到一次。或者在非压力测试的正常运作中,长时间运行之后偶尔出现。现在讨论处理器内部的大致逻辑结构,从逻辑上看

18、,采用ARM 处理的系统,包括如图1.2所示几个部分:1.处理器:处理器是核心运算模块,可以工作在多种模式、状态下。寄存器CPSR 标记处理器的当前状态、模式值;2. 寄存器:寄存器通常可以类比x86 CPU 中的EAX,EBX,ECX 等寄存器,是在指令集中可以直接访问的单元,包括最重要的保存当前状态的寄存器 CPSR,保存备份状态的寄存器SPSR,以及保存程序运行数据的寄存器R0R15。计算单元处于不同模式时访问的寄存器并不完全相同。R0R15 中,又以PC(R15) 、LR(R14)、SP(R13)最为关键;3. SFR 寄存器:SFR 寄存器从软件角度上来说是位于一些特定内存地址的数据

19、块。不同于上面所说的寄存器,访问时必须像访问内存那样访问。但是SFR 和普通内存最大的不同是对它们的改写可能会引起微处理器行为、特性等的变化。处理器的变化、环境设备的变化等也会在这些SFR 中体现。每种ARM7 微处理器都有特定的SFR,只是名称、具体功能细节等可能不同。通常SFR 位于系统总线侧;4.设备寄存器:多数ARM 自带设备是由SFR 代表的,用其它外围芯片构造的设备也同样映射到内存地址上。起到设备控制作用的设备寄存器的读写可能会引起设备行为、特性的变化,数据性质的设备寄存器读写通常不会影响设备的行为。通常设备寄存器位于外设总线侧,通常编程不必理解系统SFR 与设备SFR 的不同,但

20、是在处理虚假中断问题时必须理解两者的不同;5.RAM:RAM 通常是外挂的内存芯片模块,但是现在有一些微处理器内部本身带有一些高速RAM,称为SRAM,用于提高系统整体性能,通常用作高速缓冲(cache)或其它访问速度要求较高的数据缓冲(buffer)。RAM 也是映射到内存地址进行访问的,但是不同于SFR 的地方是和微处理器没有密切关系,改写其内容不会直接导致微处理器行为的变化,通常也不会引起设备行为的变化;6.ROM:ROM 通常用于保存系统代码,通电后代码被拷贝到RAM 中运行,有的方案让代码直接在ROM 中运行。大批量生产的产品为节省成本可能采用只写一次的ROM。通常嵌入式开发中最常使

21、用的ROM 是Flash(实际上是一种RAM,通常当作ROM),Flash 可以通过程序多次改写,非常方便产品调试、代码升级,基本上已经是嵌入式产品中的标准配置,价格也不高。有一些微处理器带有片内Flash,片内Flash 甚至可能高达512K。通常片内Flash 比外扩Flash 速度高,并且具有保护代码不被拷贝的作用。中小型嵌入式产品采用片内Flash配合片内Ram,基本上不用外扩内存即可满足代码运行的需求;7.协处理器:ARM7 通常不带协处理器。在ARM 微处理器领域最常见的两种协处理器是做内存保护和管理用的MMU,以及做浮点运算或乘除法运算用的算术协处理器。ARM9 及以上系列的微处

22、理器通常带有这两种协处理器。图1.2 处理器的基本结构这些部件中寄存器、SFR 和设备寄存器最为关键,掌握这三部分的用法,基本上就可以在ARM 环境下自如地编写程序。在内核代码中主要考虑的就是寄存器、SFR 寄存器,在设备驱动代码中主要考虑的是设备内部的寄存器。寄存器中最重要的是CPSR。但它的代码密度低,不能执行x86代码:很难和IBM PC兼容。1.2.1 Arm的编程模型当前程序状态寄存器(CPSR):当编写用户程序时,仅有15个通用32位寄存器(r0r14)、程序计数器(r15)和当前程序状态寄存器(CPSR)需要考虑,其余寄存器仅用于系统编程和异常处理(如中断)。图1.3 ARM寄存

23、器在汇编语言中寄存器R0R13为保存数据或地址值的通用寄存器。它们是完全通用的寄存器,不会被体系结构作为特殊用途,并且可用于任何使用通用寄存器的指令。其中R0R7为未分组的寄存器,也就是说对于任何处理器模式,这些寄存器都对应于相同的32位物理寄存器。寄存器R8R14为分组寄存器。它们所对应的物理寄存器取决于当前的处理器模式,几乎所有允许使用通用寄存器的指令都允许使用分组寄存器。寄存器R8R12有两个分组的物理寄存器。一个用于除FIQ模式之外的所有寄存器模式,另一个用于FIQ模式。这样在发生FIQ中断后,可以加速FIQ的处理速度。寄存器R13、R14分别有6个分组的物理寄存器。一个用于用户和系统

24、模式,其余5个分别用于5种异常模式。寄存器R13常作为堆栈指针(SP)。在ARM指令集当中,没有以特殊方式使用R13的指令或其它功能,只是习惯上都这样使用。但是在Thumb指令集中存在使用R13的指令。 R14为链接寄存器(LR),在结构上有两个特殊功能:在每种模式下,模式自身的R14版本用于保存子程序返回地址;当发生异常时,将R14对应的异常模式版本设置为异常返回地址(有些异常有一个小的固定偏移量),如图1.3。lr(R14)寄存器注意要点:当发生异常嵌套时,这些异常之间可能会发生冲突。例如:如果用户在用户模式下执行程序时发生了IRQ中断,用户模式寄存器不会被破坏。但是如果允许在IRQ模式下

25、的中断处理程序重新使能IRQ中断,并且发生了嵌套的IRQ中断时,外部中断处理程序保存在R14_irq中的任何值都将被嵌套中断的返回地址所覆盖。 解决办法是确保R14的对应版本在发生中断嵌套时不再保存任何有意义的值(将R14入栈),或者切换到其它处理器模式下。r14)的作用问题,这个lr一般来说有两个作用:当使用bl或者blx跳转到子过程的时候,r14保存了返回地址,可以在调用过程结尾恢复;异常中断发生时,这个异常模式特定的物理R14被设置成该异常模式将要返回的地址。另外注意pc,在调试的时候显示的是当前指令地址,而用mov lr,pc的时候lr保存的是此指令向后数两条指令的地址,大家可以试一下

26、用mov pc,pc,结果得到的是跳转两条指令,这个原因是由于arm的流水线造成的,预取两条指令的结果.寄存器R15为程序计数器(PC),它指向正在取指的地址。可以认为它是一个通用寄存器,但是对于它的使用有许多与指令相关的限制或特殊情况。如果R15使用的方式超出了这些限制,那么结果将是不可预测的。寄存器CPSR为程序状态寄存器,在异常模式中,另外一个寄存器“程序状态保存寄存器(SPSR)”可以被访问。每种异常都有自己的SPSR,在因为异常事件而进入异常时它保存CPSR的当前值,异常退出时可通过它恢复CPSR。CPSR在用户编程时用于存储条件码,如可以用来记录比较操作的结果和控制条件转移时是否发

27、生。在大多数情况下有一个简单的条件测试,不需要计算出条件码的精确值即可得到需要的结果。图1.4 CPSR结构简图位 7 6 5 4 3 2 1 0代号 I:IRQ 屏蔽位F:FIQ 屏蔽位T:Thumb 代码M:模式,如图1.4。状态寄存器的M0M4 位:表示处理器模式,包括SVC、USR、ABT、UND、IRQ、FIQ、SYS 等模式。CPSR 的模式、状态等位会根据ARM 处理器自身运行状态改变,也可以通过代码进行设置。SVC 模式通常是操作系统内核代码运行的模式,USR 通常是用户代码运行模式。处理器一旦进入USR 模式,必须通过SWI 异常中断才能进入SVC 模式调用内核代码的接口。但

28、是在没有MMU 做内存保护的情况下,USR 模式也能访问到SVC 模式的内存空间,因此用USR 隔离用户级代码的没有意义。在UCOS-II、uRtos V1.0 内核中主要代码在SVC 模式下运行,其他代码也都不是在USR 模式下,移植中不应该考虑USR 模式。ABT/UND 模式是真正的“异常”,通常的处理是在提示简单的系统错误信息(以便调试)后立即复位系统。对于具备MMU 协处理器并且采用了换页方式的系统,数据访问异常不是真正的异常,而是内核对内存进行换页调度的启动器。对于设计了异常处理功能的系统,指令异常也不是简单复位处理的,通常是进入异常处理过程,涉及到堆栈回滚等等方面的问题。IRQ/

29、FIQ 模式是在微处理器收到中断信号后强制处理器进入的模式,用于中断处理。SYS 模式用于嵌套中断处理。一些关于ARM7 编程指南中,认为SYS 模式是用于特权的操作系统代码运行模式,这种看法是错误的。一些ARM 开发工程师没有注意到SYS 模式的正确使用方式,它的主要用途就是嵌套式中断。ARM 在被IRQ/FIQ 中断信号中断的时候自动改写IRQ/FIQ 模式中的LR(也就是R14寄存器),LR 记录的是被中断的模式中运行的代码位置计数器,以便退出中断时能够回到原来模式的原来代码的位置。同时LR 也是每个模式下函数调用的返回代码位置计数器。也就是说LR 寄存器具有保存函数和中断返回位置两种功

30、能。如果用IRQ/FIQ 模式嵌套中断自身,则本模式的LR 被改写后,本模式下原有的函数返回代码位置计数器数据就无法还原。因此应该在关闭中断的条件下,在IRQ/FIQ 模式中进行基本的环境准备后,让ISR 切换到SYS 模式下运行。这种处理方式保证产生嵌套中断的时候,被中断的模式是SYS 而不是IRQ/FIQ 模式自身,IRQ/FIQ 模式中的LR 保存着回到SYS 模式的代码位置,SYS 模式下LR 未被破坏,保存着函数返回用的代码位置。需要注意的是,SYS、USR 模式的切换涉及到SWI 功能的应用。简单移植中不使用USR、SYS 两种模式。但是为了完成嵌套中断,可以使用UND 模式替代S

31、YS 模式作为中断的运行模式。在没有MMU 的ARM7 条件下,正如前面讨论不必使用USR 模式一样,采用SYS、SWI 等功能,仅仅是带入了复杂性,而没有其他的好处。而且UND 模式在没有协处理器的ARM7 中,同样没有用武之地,正好可以拿来替代SYS 模式使用。本书中多数描述中如果涉及到SYS 模式、嵌套中断等情况下,没有区别SYS/UND 两种模式。状态寄存器的I/F/T 位:表示处理器状态,表示屏蔽IRQ 中断、屏蔽FIQ 中断、Thumb。Thumb 代码是16 位的,主要作用是提高代码的功能密度。Thumb 代码最好的应用环境是一些有大量算法处理的代码,在操作系统内核一类的代码中用

32、处不大。Thumb 代码在32 位存储器环境下,比ARM 代码会降低一点执行效率。但如果是16 位存储器条件下,Thumb 代码实际上比ARM 代码效率还会高一些,因为16 位存储器环境下,微处理器读取32 位代码是分两次进行的。这种特征导致小型应用采用Thumb 代码有一个关键的优势就是可以很高效地直接在Flash 中运行,因为性价比最好的片外Flash 存储器通常都是16 位的。这种方式,加上微处理器通常都自带有一些SRAM,系统不必配置RAM 就可以运行。这样可以大量降低成本,并且不显著影响效率。当然,对于有一定规模的应用来说,典型的执行环境还是在32 位的RAM 中执行,这种时候,Th

33、umb 代码是有一点效率上的损失的。本书中给出的代码都是32 位ARM 环境下执行,没有考虑Thumb 代码的情况,读者如果有需要可以自行解决这方面的问题。通常C 语言的代码比较好处理,编译器可以直接将代码编译成Thumb 代码,汇编部分需要更多仔细编写,特别是在子函数调用、任务切换等等环节。存储器系统:ARM系统还有存储器状态,它可以看作是序号为0232-1的线性字节阵列。数据项可以是8位字节、16位半字和32位字。总是以4字节的边界对准,就是最低二位的地址为,半字则以偶数字节的边界对准。下面给出arm的小端格式图:图1.5 ARM小端格式3.LOAD-STORE体系结构A数据处理指令。这类

34、指令只能使用和改变寄存器中的值;B数据传送指令。这类指令把存储器的值拷贝到寄存器(load)或把寄存器的值拷贝到存储器(store);另一种仅在系统代码中有用,即交换存储器和寄存器的值;C控制流指令。一般指令在执行时使用存储于连续的存储器地址中的指令。块拷贝寻址,LOAD-STORE指令集汇总如图1.6:图1.6 LOAD-STORE指令集4.监控模式ARM支持被保护的监控模式。代码未经适当检查,确保不会执行非法操作,那么就不能进入监控特权。对于用户级程序员,只能通过监护调用,才能访问系统级函数,这些函数可以对外围硬件的访问和广泛使用的操作,并处理与程序外部有关的事务。只要程序需要输出或输入,

35、如把一些文本送到显示器,通常调用监控程序,监控程序时一个运行于特权级别的程序,它提供聊委托访问系统资源的方式,对用户级程序,更像一个专门的子程序入口。指令集包含一个专门的指令SWI,用来调用这类功能。SWI代表软件中断,但人们通常将它视为“监控程序调用”。由于它是在系统软件中实现的,从一个ARM系统到另一个系统的监控程序调用可能会完全不同。图1.7 24位立即数如果条件通过,则指令使用标准的ARM异常入口程序进入监控模式,SWI后面指令的地址保存到r14_svc,将CPSR保存到SPSR_svc,然后将CPSR4:0设置为100112和将CPSR7设置为1,以便禁止IRQ,再将PC设置为081

36、0,并且从哪里开始执行指令。1.2.2 控制逻辑1.决定何时激活RAM及何时激活ROM控制逻辑决定系统存储器的映射。复位后处理器从0地址开始。由于RAM还没有初始化,所以它肯定会找到ROM。因此,最简单的存储器映射是当A31为低时使能ROM,为高时使能RAM(大多数ARM系统在启动后立即改变存储器映射,将RAM放在存储器的低地址处以便使异常向量可以修改)。 2.在写操作时控制字节写使能信号进行字写操作时,使能所有字节信号;进行半字时,使能其中的二个;字节时,使能对应的字节。3.AMBA总线 AHB用于连接高性能系统模块。支持突发数据传送方式及单个数据传送方式,所有时序都以单一时钟的沿为基准;A

37、SB用于连接高性能系统模块,支持突发数据传送模式;APB为低性能的外围部件提供接口。连接如图1.8所示:图1.8 总线结构1.2.3 启动代码理解所谓启动代码,就是处理器在启动的时候执行的一段代码,主要任务是初始化处理器模式,设置堆栈,初始化变量等等.由于以上的操作均与处理器体系结构和系统配置密切相关,所以一般由汇编来编写。具体到LPC2132的启动代码分成两部分:一是与ARM7TDMI内核相关的部分,包括处理器各异常向量的配置,各处理器模式的堆栈设置,如有必要,复制向量到RAM,以便remap之后处理器正确处理异常,初始化数据(包括RW与ZI),最后跳转到Main;二是与处理器外部设备相关的

38、部分,这和厂商的联系比较大.虽然都采用了ARM7TDMI的内核,但是不同的厂家整合了不同的片上外设,需要不同的初始化,其中比较重要的是初始化WDT,初始化各子系统时钟,有必要的话,进行remap.这一部分与一般控制器的初始化类似。图1.9 ADS中startup.s文件模块ADS中startup.s文件模块如图1.9。程序见附表清单程序1。IRQ.S文件用于管理IRQ中断嵌套,可通过宏实现,一般很少用,代码见程序1,处理流程如图1.10所示:图1.10 IRQ.S文件处理流程Target.c文件包含和目标板初始化相关的代码,如Remap设置、系统时钟设置和存储器加速模块设置等,以及IRQ和FI

39、Q的异常处理空函数,模块框如图1.11:图1.11 Target.c文件结构Config.h包含一些类型定义和系统时钟定义,如下:Target.h包含一些特殊定义和开关IPQ中断、FIQ中断的函数声明,如下:INCLUDE.armirq.inc; Inport the head file 引入头文件CODE32AREA IRQ,CODE,READONLY;/* 以下添加中断句柄,用户根据实际情况改变 */;/* Add interrupt handler here,user could change it as needed */;/*中断*/;/*Interrupt*/IRQ_Handler

40、HANDLER IRQ_Exception;/*定时器0中断*/;/*Time0 Interrupt*/Timer0_Handler HANDLER Timer0_ExceptionENDLPC2132复位后启动代码工作流程如下7:1.3 Arm代码优化32位ARM处理器的指令集支持有符号/无符号的8位、16位、32位整型和浮点型变量类型。按照作用范围的不同,C语言的变量可以划分为全局变量和局部变量。ARM编译器通常将全局变量定位在存储空间中,局部变量分配给通用寄存器。在默认的情况下,armcc是全部优化功能有效的,而GNU编译器的默认状态下优化都是关闭的。ARM C编译器中定义的char类型

41、是8位无符号的,有别于一般流行的编译器默认的char是8位有符号的。所以循环中用char变量和条件 i 0时,就会出现死循环。为此,可以用fsigned char(for gcc)或者zc(for armcc)把char改成signed。变量类型如下: char 无符号8位字节数据 short 有符号16位半字节数据 int 有符号32位字数据long 有符号32位字数据 long long 有符号64位双字数据 在全局变量声明时,需要考虑最佳的存储器布局,使得各种类型的变量能以32位的空间位基准对齐,从而减少不必要的存储空间浪费,提高运行效率。如: 这里定义的四个变量形式相同,只是次序不同,

42、却导致了在最终映像中不同的数据布局,如下图所示。显然第二种方式节约了更多的存储器空间。 图1.12 数据存储结构 另外对于表达式的处理也要格外小心,如下例子: short checksum_v3(short * data) unsigned int i; short sum = 0; for(i = 0; i < 64 ; i+) sum = (short)( sum + data ); /这里表达式式整形的,所以返处理非32位数据时, /要小心处理数据类型的转换。 /原来shortshortint 但 int intint。奇怪的处理 return sum; 同时如上例的程序所示,这样

43、在循环体中的每次运算都要进行类型转换,会降低程序的效率,可以先把其当作int来运算,然后再返回一个short类型。 同时,由于处理的data是一个short型数组,用LDRH指令的话,不能使用桶型移位器,所以只能先进行偏移量的以为操作,然后再寻址,也会造成不佳的性能。解决的方法是用指针代替数组操作。如下: short checksum_v4(short * data) unsigned int i; int sum = 0; for( i = ; i<64; i+) sun += ( data +); return (short) sum; 对于局部变量,要尽量不使用32位以外的变量类型

44、。当一个函数的局部变量数目不多时,编译器会把局部变量分配给内部寄存器,每个变量占一个32位的寄存器。这样short和char类型的变量不但起不到节省空间的作用,反而会耗费更多的指令周期来完成short和char的存取操作。C语言代码及其编译结果如下所示1: C编译器必须逐字逐句地把C程序转换成汇编程序,这样编译器就不会漏掉所有可能的输入。实际上,许多输入组合是不可能的或不会出现的。数据类型有8位或者16位数据,但在装载或存储之前,先扩展成32位。无符号数把0作为扩展位。因此int格式数据无须花费多余的时间,来进行位扩展。同时8位和16位必须放到寄存器的低8位或低16位。而一个int或更小类型的

45、传送,存储时就不需要花费额外的指令时间了。因此,局部变量应尽可能用32位的数据类型int和long,即使在处理8位和16位的数值时,应避免使用char和short数据类型作为局部变量。唯一例外情况是,需要使用char和short类型的数据溢出归零特性时,如模运算255+1=0,就需要使用char类型。函数参数和返回值应尽量使用int类型。 另外,对于调用频率较低的全局变量,尽量使用小的数据类型以节省空间2。循环是程序设计中非常普遍的结构。在嵌入式系统中,微处理器执行时间在循环中运行的比例较大,因此关注循环的执行效率是非常必要的。除了在保证系统正确工作的前提下尽量简化核循环体的过程以外,正确和高

46、效的循环结束标志条件也非常重要。按照以上所述的“与0比较”原则,程序中的循环结束条件应该是“减到0”的循环,结束条件尽量简单。应尽可能在关键循环中采取上述的判断形式,这样可以在关键循环中省去一些不必要的比较语句,减少不必要的开销,提高性能。如下面二个示例1: fact1和fact2中通过定义局部变量a来减少对n的load/store操作。fact2函数遵循了“与0比较”原则,省去了fact1编译结果中的比较指令,并且,变量n在整个循环过程不参与运算,也不需要保存。由于省去了寄存器分配,从而给其他部分程序的编译带来了方便,提高了运行效率。 “减到0”的方法同样适用于while和do语句。如果一个

47、循环体只循环几次,可以用展开的方法提高运行效率。当循环展开后,不需要循环计数器和相关的跳转语句,虽然代码的长度有所增加,但是得到了更高的执行效率。C循环结构中的优化,使用减数到零的循环体,以节省指令和寄存器的使用。使用无符号的循环计数值,并用条件 i != 0中止;如果循环体至少执行一次,用优先选用dowhile;适当情况下展开循环体; 尽量使用数组的大小是4或8的备述,用此倍数展开循环体 寄存器分配;尽量限制函数内部循环所用局部变量的数目,最多不超过12个,以便编译器能把变量分配到寄存器;可以引导编译器,通过查看是否属于最内层循环的便赖宁嘎来去定某个变量的重要性。 函数调用中优化。 ARM中

48、的函数前4个整型参数通过寄存器r0、r1、r2、r3来传递,随后的整型参数通过堆栈来传递。(full desceding stack)。尽量限制函数参数,不要超过四个,也可以把相关的参数组织在结构体传递; 把比较小的被调用函数和调用函数放在同一个源文件中,并且限定一,后调用,编译器能进行优化; 用_inline内联性能影响较大的重要函数。 指针的使用, 用一个局部变量来保存公共子表达式的值,保证该表达式只求一次值。 避免使用局部变量的地址,否则访问这个变量的效率较低。 结构体的安排达到优化。小的元素放在结构体的开始,大的元素放在结构体的最后, 避免使用过大的结构体,用层次话的小结构体代替,人工

49、对API的结构体增加填充位以提高移植性,枚举类型要慎用,因为它的大小与编译器相关。 位域的优化。尽量用define或者enum来代替位域,用逻辑运算来丢位域操作 边界不对齐数据和字节排列方式,尽量避免使用边界不对齐数据,用char× 可指向任意字节对齐的的数据,与逻辑运算配合,可访问任意边界和排列的数据。在使用除法时,一堆算法,不好写,总的来说是以乘代除,配合移位运算。 内联函数和内嵌汇编,没什么好写的,就是内联减少调用开销,内嵌汇编提高运行效率。存储器相关的优化方法,用查表代替计算,在处理器资源紧张而存储器资源相对富裕的情况下, 可以用牺牲存储空间换取运行速度的办法。例如需要频繁计

50、算正弦或余弦函数值时,可预先将函数值计算出来置于内存中供以后ARM查找。充分利用片内RAM ,一些厂商出产的ARM 芯片内集成有一定容量的RAM。处理器对片内RAM 的访问速度要快于对外部RAM 的访问,所以应尽可能将程序调入片内RAM 中运行。若因程序太大无法完全放入片内RAM ,可考虑ARM将使用最频繁的数据或程序段调入片内RAM 以提高程序运行效率。ARM 7 处理器要求ARM程序中的32 位/16 位变量必须按字/ 半字对齐,这意味着如果变量顺序安排不合理, 有可能会造成存储空间的浪费。例如:一个结构体中的4个32 位int 型变量i1 i4 和4 个8 位char 型变量c1 c4,

51、若按照i1、c1、i2、c2、i3、c3、i4、c4 的顺序交错存放时, 由于整型变量的对齐会导致位于2 个整型变量中间的那个8 位char 型变量实际占用32 位的存储器,这样就造成了存储空间的浪费。为避免这种情况, 应将int 型变量和char 型变量按类似i1、i2、i3、i4、c1、c2、c3、c4 的顺序连续存放,这不仅可以节省代码,而且可以提高代码的运行效率。总结,高级语言的优化和编译器、硬件结构有关。硬件上,ARM一般为32位总线,以32位访问数据的速度较快。局部变量和其他常用的变量要尽量利用32位的int类型,组织结构体时,也要注意元素的位置(小前大后),以节省空间。另外,由于

52、ARM指令可条件执行,所以充分利用cpsr会使程序更有效率。同时注意好类型之间的运算,尽量减少转型操作。任何时候除法和取模运算可以同时取得结果而不会额外增加运算过程,但单单对于除法,还是以乘代除比较划算。对于编译器,armcc遵从ATPCS的要求,第一到第四个参数依次通过r0r4传递,其他参数通过堆栈传递,返回值用r0传递,因此,为了把大部分操作放在寄存器中完成,参数最好不多与4个。另外,可用的通用寄存器有12个,所以尽量将局部变量控制在12个之内,效率上会得到提升。同时,由于编译器比较保守,指针别名会引起多余的读操作,所以尽量少用。使用Thumb 指令为了从根本上有效ARM降低代码尺寸,AR

53、M 公司开发了16 位的Thumb 指令集。Thumb 是ARM 体系结构的扩充。Thumb 指令集是大多数常用32 位ARM 指令压缩成16 位宽指令的集合。在执行时,16 位指令透明的实时解压成32 位ARM 指令并没有性能损失。而且程序在Thumb状态和ARM 状态之间切换是零开销的。与等价的32 位ARM 代码相比,Thumb 代码节省的存储器空间可高达35% 以上。第二章 UCOS ii随着嵌入式技术的快速发展,实时多任务操作系统作为一种软件平台已逐步成为国际嵌入式系统的主流,目前世界上已经有一大批成熟的实时嵌入式操作系统,通常,对嵌入式软件的基本要求是体积小、指令速度快、具有较好的

54、裁减性和可移植性,目前,实时操作系统很多,如 VxWorks , Windows CE , pSOS , QNX , LynxOS 等,这些操作系统都具有高可靠性、强实时性等特点,但他们都是商业操作系统,价格昂贵,人们往往很难接受, C/OS- 操作系统的出现是对这些商业操作系统的一个很大的冲击。C/OS- 是源码公开的实时操作系统,是一个自由操作系统。程序开发人员可以改写源代码,使之符合自己的要求,裁减掉不需要的部分,使操作系统变得小巧、灵活、并且能满足用户特定操作系统的需要。为了提高系统的实时能力, C/OS- 可以将一个复杂的应用划分为多个相互独立的任务,并根据任务的重要性来分配优先级。

55、任务的调度完全由 C/OS- 的实时内核完成,主要包括任务的状态管理、选择最高优先级的任务、执行任务和撤销任务等, C/OS- 内核还负责 CPU 时间分配, CPU 时间总是优先分配给中断事件,其次是任务队列中当前优先级最高的任务,不同任务间的通信可以通过 C/OS- 提供的信号量、邮箱、信息队列等机制完成,他的绝大部分代码是用 C 语言编写的,可移植性强,因此 1997 年以后,在国际上逐渐被广泛采用。2.1 ucosii分析实时系统的特点是,如果逻辑和时序出现偏差将会引起严重后果的系统。有两种类型的实时系统:软实时系统和硬实时系统。在软实时系统中系统的宗旨是使各个任务运行得越快越好,并不

56、要求限定某一任务必须在多长时间内完成。在硬实时系统中,各任务不仅要执行无误而且要做到准时。大多数实时系统是二者的结合。实时系统的应用涵盖广泛的领域,而多数实时系统又是嵌入式的。这意味着计算机建在系统内部,用户看不到有个计算机在系统里面。以下是一些嵌入式系统的例子:通讯类Switch Hurb路由器机器人航空航天飞机管理系统武器系统喷气发动机控制民用消费品微波炉洗碗机洗依机稳温调节器过程控制药品加工化工厂汽车业发动机控制防抱死系统(ABS)办公自动化传真机复印机计算机外设打印机计算机终端扫描仪调制解调器实时应用软件的设计一般比非实时应实时应用软件的设计一般比非实时应用软件设计难。不复杂的小系统一

57、般设计成如下图所示的样子。这种系统可称为前后台系统或超循环系统(Super-Loops)。应用程序是一个无限的循环,循环中调用相应的函数完成相应的操作,这部分可以看成后台行为(background)。中断服务程序处理异步事件,这部分可以看成前台行为(foreground)。后台也可以叫做任务级。前台也叫中断级。时间相关性很强的关键操作(Critical operation)一定是靠中断服务来保证的。因为中断服务提供的信息一直要等到后台程序走到该处理这个信息这一步时才能得到处理,这种系统在处理信息的及时性上,比实际可以做到的要差。这个指标称作任务级响应时间。最坏情况下的任务级响应时间取决于整个循环的执行时间。因为循环的执行时间不是常数,程序经过某一特定部分的准确时间也是不能确定的。进而,如果程序修改了,循环的时序也会受到影响。图2.1

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论