ARM是Advanced RISC Machines的缩写,它是一家微处理器行业知名企业,该企业设计了大量高性能、廉价、耗能低的RISC(精简指令集)处理器。
采用RISC架构的ARM处理器一般具有如下特点:
1.体积小、低功耗、低成本、高性能。
2.支持Thumb(16位)/ARM(32位)双指令集。
3.大量使用寄存器,指令执行速度更快。
4.大多数数据操作都在寄存器中完成。
5.寻址方式灵活简单,执行效率高。
6.指令长度固定。
选用EP7312处理器,主要是它具有高速ARM720T核心、丰富的外设接口与启动ROM的设置。EP7312可配置为外部的ROM启动的外启动方式或从片上ROM启动的内启动方式。
在外启动方式下,ARM从外部程序存储器(一般是Flash存储器)取指令执行相应的应用;在内启动方式下,ARM运行片上启动ROM中固化的一个128B启动程序,完成器件初始化,配置串口1以9600bps速率接收2048B用户程序存储于片内SRAM中,然后跳转到片内SRAM起始处开始执行刚下载的2KB用户程序,这为进一步的调试、代码下载、外启动Flash存储器编程提供途径,非常适用于嵌入式系统的实验与开发。
EP7312有强大的系统扩展能力,表1、表2中所示分别是内、外启动方式下的地址空间分配。
表1 内启动方式地址空间分配
表2 外启动方式地址空间分配
ARM处理器支持7种运行模式,如表所示。
表 ARM处理器运行模式
说明:ARM处理器的运行模式可以通过软件改变,也可以通过外部中断或异常处理改变。
大多数的应用程序运行在用户模式下,当处理器运行在用户模式下时,某些被保护的系统资源是不能被访问的。
除用户模式User以外,其余的6种模式称之为非用户模式或特权模式(PrivilegedModes);其中除去用户模式和系统模式以外的5种模式又称为异常模式(ExceptionModes),常用于处理中断或异常,以及需要访问受保护的系统资源等情况。
由于各种新型微处理器的出现和应用的不断深化,嵌入式系统在后PC时代得到了空前的发展。随着时间的推移和技术的进步,在工业控制和新兴的手持式应用等领域,用户体验成为产品成功的关键因素之一,越来越多的产品需要良好的用户界面、互联功能以及较强的数据处理能力,这对嵌入式处理器硬件、软件、教学等提出了新的要求。
1 嵌入式处理器与硬件
在处理器方面,目前大量的中、低端嵌入式应用,主要使用8/16位单片机。在国内,由于历史的原因,主要是以MCS51核为主的许多不同型号单片机,主要厂商有Atmel、Philips、Winbond、宏晶等。还有一些近几年发展较快的新型单片机,如PIC、AVR、MSP430系列等。这些单片机各有特点,但从目前的发展角度来看,单片机针对特定应用领域的个性化发展愈发明显,典型的例子就是TI公司的MSP430系列16位单片机、ST公司的STM8L系列8位单片机和STM32L系列32位超低功耗单片机。
在嵌入式中的高端应用领域,像工业控制、POS机、网络设备、图像处理、手机、PDA等,目前主要使用ARM、MIPS、PowerPC、DSP等16~64位处理器,以32位处理器为主。各种类型的处理器都有其一定的应用针对性。例如,DSP对数字信号处理技术中用到的常用运算、算法做了优化设计,主要用于实时信号处理领域,如实时音视频处理、电机控制等。MIPS处理器性能很好,但功耗较大,适合于有交流电源供电的固定应用,如固定的网络设备、机顶盒等。ARM处理器性能高,功耗低,适合于用电池供电的便携、手持式设备。由于近几年便携、手持式嵌入式应用的高速发展,ARM处理器的增长速度和市场占有率也快速提升,成为目前32位应用中的主力产品。
由于嵌入式应用系统的广泛性,嵌入式系统的硬件设计涉及的知识面很广,从模拟到数字、低频到高频、小信号到大功率,以及复杂的时序逻辑设计和PCB设计,还要考虑软硬件资源的合理分配,不仅要有广而扎实的理论基础,更需要丰富的实践经验。只有对大大小小各种应用系统反复实战演练,了解新技术、新器件,使用过多种多样的处理器和模拟/数字器件,才能逐步积累,聚沙成塔,对一个新的应用系统给出快速、合理的硬件方案与设计。
2 ARM处理器的优势
对于如今大量出现的32位嵌入式应用,以笔者之见,ARM处理器的优势主要有以下几个方面。
2.1 高性能、低功耗、低价格
把ARM处理器的性能拿来和一些着名的通用处理器(如Pentium)相比是不合适的,因为他们各自针对的应用需求是不同的。Pentium处理器采用多条指令流水线的超标量结构,追求通用应用目标下的超强性能,功耗大,可以用散热器加风扇散热。ARM针对嵌入式应用,在满足性能要求的前提下,力求的功率消耗。ARM结构的优点是能兼顾到性能、功耗、代码密度、价格等几个方面,而且做得比较均衡。在性能/功耗比(MIPS/W)方面,ARM处理器具有业界的性能。基于ARM核的芯片价格也很低,目前ARM CortexM的芯片价格可低至10元人民币左右。
2.2 丰富的可选择芯片
ARM只是一个核,ARM公司自己不生产芯片,采用授权方式给半导体生产商。目前,全球几乎所有的半导体厂家都向ARM公司购买了各种ARM核,配上多种不同的控制器(如LCD控制器、SDRAM控制器、DMA控制器等)和外设、接口,生产各种基于ARM核的芯片。目前,基于ARM核的各种处理器型号有好几百种,在国内市场上,常见的有ST、TI、NXP、Atmel、Samsung、OKI、Sharp、Hynix、Crystal等厂家的芯片。用户可以根据各自的应用需求,从性能、功能等方面考察,在许多具体型号中选择最合适的芯片来设计自己的应用系统。由于ARM核采用向上兼容的指令系统,用户开发的软件可以非常方便地移植到更高的ARM平台。
2.3 广泛的第三方支持
以如今的技术,设计一个处理器并非难事,但要使这个处理器得到大家认可,并取得市场成功却是非常困难的,其中涉及许多技术与非技术的因素和环节,还包括时机、运气。因为现在许多产品的开发,不是一个简单的处理器加几百条指令、语句就可以解决的。要用到32位处理器,一般都要有编译器、高效的开发工具(仿真器及调试环境)、操作系统、协议栈等,这些东西都不是一个芯片生产商可以解决的,而需要许多第三方的支持。这就像一粒种子,需要土壤、空气、水等环境才能发芽、成长。这也是我们的一些“中国芯”该反思之处。
ARM通过近20年的培育、发展,得到了广泛的第三方合作伙伴支持。目前,除通用编译器GCC,ARM有自己的高效编译、调试环境(MDK、Keil),全球约有50家以上的实时操作系统(RTOS)软件厂商和30家以上的EDA工具制造商,还有很多高效率的实时跟踪调试工具的厂商,对ARM提供了很好的支持。用户采用ARM处理器开发产品,既可以获得广泛的支持,也便于和同行交流,加快开发进度,缩短产品的上市时间。
2.4 完整的产品线和发展规划
ARM核根据不同应用需求对处理器的性能要求,有一个从ARM7、ARM9到ARM10、ARM11,以及新定义的CortexM/R/A系列完整的产品线。前几年应用较多的主要是基于V4架构的ARM7TDMI、ARM720T、ARM920T核的一些处理器芯片,如NXP的LPC2000系列、ST的STR7/9系列、Atmel 的AT91系列和Samsung的S3C系列。近两年,ARM Cortex系列以更好的性能、更低的价格得到快速推广,典型的就是基于CortexM3的STM32系列。
ARM CortexM/R/A系列分别针对不同的应用领域。M系列主要面向传统微控制器(MCU/单片机)应用,这类应用面很广,要求处理器有丰富的外设,并且各方面比较均衡;R系列强调实时性,主要用于实时控制,如汽车引擎;A系列面向高性能、低功耗应用系统,如智能手机。选用ARM处理器进行开发,技术积累性较强,生命周期长,设计重用度高,不易被淘汰。用户在选择ARM处理器时,可以针对应用需求,从大量的ARM芯片中选用满足性能、功能要求的产品,以获得较好的性价比。
3 ARM嵌入式系统的软件
由于嵌入式系统的差异性很大,对不同的应用需求,必须选择不同的软件设计方法、开发平台和系统工具。
对于一些不需要复杂图形用户界面、通信协议和复杂文件操作(如同时打开多个文件)的应用,如果选用CortexM3核的处理器就已可以满足要求,任务数不多,任务之间的关系也不复杂,则不一定需要移植复杂的操作系统。这样一方面可以降低系统硬件开销,也可以获得更好的实时性和执行速度。不过,这样的软件开发方法需要开发人员有较好的程序设计思想,对所用器件有深入的了解,并掌握其编程控制方法。若引入一个简单的操作系统,如μC/OS,可以简化程序结构,但开发者熟悉其内核结构,并有使用经验,否则可能会需要更多的系统开发、调试时间。
如果选择了带存储器管理单元(MMU)的ARM处理器(如ARM920T、CortexA8等),这种应用系统根据应用、实时性、开发环境等因素,移植一个功能较强的操作系统一般情况下会比较合适,如Linux、WinCE,甚至新的Android等。这种系统的开发难度主要是在OS的移植以及硬件驱动程序的开发上。当这二步工作完成后,主要的软件开发工作已和在PC机上开发没有多大区别,可以按照一般的软件工程方法来进行,要注意的只是与ARM硬件平台相关的软件优化问题。
由于嵌入式系统硬件资源的有限性,嵌入式软件与其他应用软件的主要区别,在于嵌入式软件要有较高的效率,包括执行速度和存储空间,尽管这二者经常是相互矛盾的。目前一般要求更多的是速度优化。要编写出高效的ARM程序,需要开发人员熟悉ARM的体系结构,包括内核结构、指令系统、Cache与存储器结构等,还要有好的程序设计思想,以及对一些常用函数、算法的深刻理解。这个过程也是ARM系统开发从低级到的进阶之路。
目前,由于应用系统越来越复杂,嵌入式软件的移植性和重用性也得到了人们的高度重视,因为它直接影响到嵌入式软件的开发效率和质量。选择一种通用的开发环境和编程语言,使开发的嵌入式软件可以方便地移植到不同的硬件平台,是实现软件重用的基础。目前在ARM嵌入式系统开发中,ARM RealView、Keil以及IAR的EWARM是较好的开发平台,C/C++语言是应用最广泛的编程语言,并具有广泛的库函数、程序支持,在今后很长一段时间内,仍将在嵌入式系统应用领域中占重要地位。
4 嵌入式系统的教学
如今,嵌入式系统作为一个热门领域,其教学问题也颇受高校的关注。教学的主要目的是培养社会需要的人,由于嵌入式系统的广泛性、差异性,社会对从事嵌入系统开发人员的要求也有很大的不同,既需要从事简单8/16位单片机开发的人员,也需要从事ARM、DSP开发的人员;既要有从事硬件、底层软件开发的人员,也要有从事OS移植、应用软件开发的人员。由于整个大学学习时间和课程教学时数的限制,一个人显然不可能学习、掌握嵌入系统开发的各个层面。所以,各个学校首先应根据自身情况,明确定位,确定自己培养学生的社会适应面,然后再制定教学大纲,确定课程内容和实验平台。对于高职、普通高校的电类与非电类、软件学院等,都应该有不同的选择,而不是人云亦云,一哄而上。
就目前的发展看,由于ARM等32位处理器应用渐成主流,开发工具已较完善、成熟,对于普通高校计算机学科的嵌入式系统教学,笔者认为可以定位在以32位嵌入式系统开发为主,重点是嵌入式系统的软硬件结构、嵌入式OS的知识,以及嵌入式软件设计(包括优化)。课程主体内容基本与硬件平台(处理器型号)无关,实验可以采用基于ARM核的不同厂家处理器的实验平台。主要考虑以下几点:
①在32位嵌入式系统开发上,软件开发人员的需求比硬件开发人员要多得多(尽管目前硬件开发人员较难找,但这应该是电子等培养的)。一般在一个从事嵌入式应用系统开发的公司中,软硬件人员的比例不会小于10:1。由于学习时间有限,教学重点应该偏软件。
②现代社会强调分工、合作,以求得整体利益的化。对个人的要求首先是专才,能把局部工作做精、做好。通才是需要的,但数量会比专才少得多,而且通才是练出来的,不是教出来的。今后的大学是大众教育,教学只能面向大众需求。在相关的研究生阶段,对一些有基础、有兴趣的学生,可以进行一些系统级硬件、底层软件的开发实践,同时也可满足社会对高层次嵌入式人才的需要。
③以此为主,可以再开设2门选修课。向下为“单片机原理与应用”,此课程以实践为主,让有兴趣的学生可以自己设计、制作一些单片机应用系统,同时也锻炼了硬件动手能力。向上为“数字信号处理(DSP)”,让那些数学基础较好、对实时信号处理有兴趣的学生有用武之地(现在这样的学生很难得)。
另外,由于应用日趋复杂,而教学时间有限,一个本科生在校期间不可能深入学习嵌入式系统的很多细节,嵌入式教学应采用自上而下的教学方法。一开始不必花很多时间讲解处理器内核架构/指令系统,只要知道各种内核的基本特点即可,重点学习、掌握处理器、外设的编程结构(即编程者角度看到的编程模型结构,非具体物理实现结构)。真实的应用、研究设计都是从粗粒度向细粒度进阶的,是一个自顶向下的过程,首先要重视的是系统架构和各个抽象层。1000行的C程序,编译后生成的目标代码只有10 KB左右,试想现在的MCU Flash动辄几百KB,为什么?一个目标代码几百KB的C程序,一般不是完全由个人写出来的,而都会使用一些第三方的库函数、中间件等。硬件也一样,现在很多硬件系统都会使用一些模块(Module),尽管这些模块看上去还是一个芯片,但实际上已经是一个SiP模块,如WiFi模块。所以,在了解基本嵌入式系统结构的基础上,本科阶段要更多地学习各种系统、模块、外设、协议、库函数的“边界(Interface)”,能够搭建一个简单系统(How to do),今后在工作、或研究生阶段进一步去做好一个系统(How to do better)。
5结语
嵌入式系统作为一种特殊的计算机应用系统,在任何时期都有相对的高、中、低端应用,即使在今后,没有OS支持的4位或8位单片机的嵌入式应用仍有大量需求,但趋势是系统化、复杂化。这既是嵌入式系统的特点--广泛性、差异性和不可垄断性,也是广大嵌入系统研发人员的生存与发展空间。ARM处理器在便携、手持式设备以及工业控制等应用领域,在今后相当长的时间内是一个很好的选择。当然,没有一种型号的处理器是可以覆盖所有应用的,也不是搬上一个嵌入式OS,就可以很好地解决软件问题的。深入了解各种器件特性,选择最合适的处理器、外围器件、操作系统和软件库,尽可能地优化软件设计,最贴切地满足应用需求,以获得的系统性价比,是嵌入式系统设计开发的精髓。
ARM编程特别是系统初始化代码的编写中通常需要实现中断的响应、解析跳转和返回等操作,以便支持上层应用程序的开发,而这往往是困扰初学者的一个难题。中断处理的编程实现需要深入了解ARM内核和处理器本身的中断特征,从而设计一种快速简便的中断处理机制。需要说明的是,具体的上层语言编写的中断服务函数不在本文的讨论范围之内。
ARM处理器异常中断处理概述
当异常中断发生时,系统执行完当前指令后,将跳转到相应的异常中断处理程序处执行。当异常中断处理程序执行完成后,程序返回到发生中断的指令的下一条指令处执行。在进入异常中断处理程序时,要保存被中断的程序的执行现场。从异常中断处理程序退出时,要恢复被中断的程序的执行现场。ARM体系中通常在存储地址的低端固化了一个32字节的硬件中断向量表,用来指定各异常中断及其处理程序的对应关系。当一个异常出现以后,ARM微处理器会执行以下几步操作:
1)保存处理器当前状态、中断屏蔽位以及各条件标志位;
2)设置当前程序状态寄存器CPSR中相应的位;
3)将寄存器lr[_]mode设置成返回地址;
4)将程序计数器(PC)值设置成该异常中断的中断向量地址,从而跳转到相应的异常中断处理程序处执行。
在接收到中断请求以后, ARM处理器内核会自动执行以上四步,程序计数器PC总是跳转到相应的固定地址。从异常中断处理程序中返回包括下面两个基本操作:
1)恢复被屏蔽的程序的处理器状态;
2)返回到发生异常中断的指令的下一条指令处继续执行。
当异常中断发生时,程序计数器PC所指的位置对于各种不同的异常中断是不同的,同样,返回地址对于各种不同的异常中断也是不同的。例外的是,复位异常中断处理程序不需要返回,因为整个应用系统是从复位异常中断处理程序开始执行的。
支持中断跳转的解析程序
解析程序的概念和作用
如前所述,ARM处理器响应中断的时候,总是从固定的地址开始的,而在语言环境下开发中断服务程序时,无法控制固定地址开始的跳转流程。为了使得上层应用程序与硬件中断跳转联系起来,需要编写一段中间的服务程序来进行连接。这样的服务程序常被称作中断解析程序。
每个异常中断对应一个4字节的空间,正好放置一条跳转指令或者向PC寄存器赋值的数据访问指令。理论上可以通过这两种指令直接使得程序跳转到对应的中断处理程序中去。但实际上由于函数地址值为未知和其它一些问题,并不这么做。这里给出一种常用的中断跳转流程:
图1中断跳转流程图
这个流程中的关键部分是中断向量表,为了让解析程序能找到向量表,应该将向量表的地址固定化(编程者自定义)。这样,整个跳转流程的所有程序地址都是固定的,当中断触发后,就可以自动运行。其中,只有向量表的内容是可变的,编程者只要在向量表中填入正确的目标地址值就可以了。这使得上层中断处理程序和底层硬件跳转有机地联系起来。
解析过程示例
以一次IRQ跳转为例,假定中断向量表定义在0x00400000开始的外部RAM空间:
图2 中断解析示例流程
图2中实线表示的流程都用ARM汇编语言编写,一般作为boot代码的一部分放在系统的底层模块中。填写向量表的操作可以在上层应用程序中方便地实现,比如在C语言中: *( int *(0x00400018)) = (int) ISR[_]IRQ;这样就将IRQ中断的服务程序入口地址(0x00300260)填写到中断向量表中的固定地址0x00400018开始的4字节空间了。
如此一来,就可避免在应用程序中计算中断的跳转地址,并且可以很方便的选择不同的函数作为指定中断的服务程序。当然,在程序开发时要合理开辟好向量表,避免对向量表地址空间不必要的写操作。
解析程序的扩展
众所周知,在ARM处理器中会包含很多中断源,通常会在ARM内核外面扩展一个中断控制器来管理各种原因产生的中断。比如,三星公司的S3C4510B处理器中的IRQ/FIQ类型的中断源可以有21个,S3C44B0X有26个。这时候中断处理的原理还是一样的,无非是向量表更长,并且当一个中断触发以后,需要在解析程序里查询中断控制器的状态来确定具体的中断源,再根据中断源来读取向量表中的对应地址内容。其处理流程可用图3表示。
图3 中断解析的扩展
相比图2,图3中多了一级的跳转,也就是在次解析跳转到IRQ/FIQ服务程序中后,再进行第二次的解析[_]中断源的识别。
向量中断的处理
一些处理器在设计外扩的中断控制器时提供了一种叫做“向量中断”的中断跳转机制。这与前文叙述的扩展解析跳转流程有所不同,它不需要软件来识别具体的中断源,也就是不需要添加图3中的IRQ/FIQ服务程序,而完全由硬件自动跳转到对应的中断地址。其它跳转流程的原理都是一样的。这相当于扩展了ARM内核的硬件中断向量表,减小了中断响应延时。以S3C44B0X处理器的外部中断0为例,需要在其对应的硬件固定跳转地址0x00000020处添加指令:ldr pc,=HandlerEINT,使得程序跳转到其服务程序HandlerEINT0处执行。
图4 向量中断解析流程示例
结语
本文介绍的中断处理机制是嵌入式编程中常常采用的方法,其原理是通用的。当然,在实际开发中,需要根据系统处理器ARM内核的中断特征和处理器自身的中断控制器特点具体细化流程图中的各个步骤和改写参考代码。