书名:龙芯嵌入式系统软硬件平台设计
ISBN:978-7-115-60100-1
本书由人民邮电出版社发行数字版。版权所有,侵权必究。
您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。
我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。
如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。
著 符意德
责任编辑 赵祥妮
人民邮电出版社出版发行 北京市丰台区成寿寺路11号
邮编 100164 电子邮件 315@ptpress.com.cn
网址 http://www.ptpress.com.cn
读者服务热线:(010)81055410
反盗版热线:(010)81055315
嵌入式系统是一个面向应用、高度裁减的专用计算机系统。随着应用场景的不断丰富,嵌入式系统越发重要。龙芯1号是龙芯中科技术股份有限公司(简称龙芯中科)推出的低功耗、低成本专用微处理器芯片,其面向嵌入式专用应用领域。掌握嵌入式系统的软硬件平台设计,不仅是从业者的需求,也是龙芯中科构建自主创新生态体系不可或缺的一环。
本书第01章概要性地介绍嵌入式系统设计的特征,嵌入式系统的发展及应用、设计方法,并详细介绍了龙芯1B的开发工具。第02~04章介绍核心板、常用接口、人机接口这三大硬件平台。第05章和第06章分析嵌入式软件平台,包括汇编编程及启动引导程序、操作系统移植及驱动设计。第07章通过一个综合示例,带领读者实践从需求分析到软硬件平台设计的全流程。
本书适合作为高等院校计算机、电子信息相关专业的教材,也可供从事嵌入式软硬件设计、开发的技术人员参考。
收到符意德老师的《龙芯嵌入式系统软硬件平台设计》一书,心有两“感”,一是感激,二是感慨。
我10多年前进入龙芯中科,多年来奋战在一线,带领研发与市场人员为实现我国信息技术领域的自主化而努力,这让我深感推广自主技术的不易。在嵌入式领域,龙芯中科推出了数款芯片产品,覆盖了MCU、SoC不同的计算层级,在性能与功能上已经可以和国外处理器较量。但是受限于技术资料和软硬件参考设计的贫乏,国产处理器的技术生态建设还有很长的一段路要走。我们一直在推广和建设龙芯的技术生态,正因为不断有像符意德老师这样的开发者、内容贡献者的参与,龙芯处理器才能够不断进入新的领域并生根发芽。国产软硬件技术生态的枝繁叶茂要归功于我们的朋友圈不断扩展,因此,我对龙芯中科的好朋友——符意德老师充满感激。
中国的电子信息和计算机教学,关键在于两个融合——原理与实践的融合,软件与硬件的融合。而这两个融合,尤其是软件与硬件在教学上的融合,长期以来无法摆脱国外处理器构建的软硬件体系的影响。广大师生翘首以盼,在电子信息和计算机领域我国的自主技术能支撑高等院校的认知教学、原理教学、实验教学和软硬件协同教学,而本书的出版,让我们看到了自主技术产业应用和教学领域脱节问题得到解决的希望。
在“信创”向多行业、多领域推广的过程中,整个社会对支撑行业转型的人才提出了更高的要求。在之前,一位工程师精通一种处理器架构,甚至一款芯片的开发,就可以支撑多个项目的运行。但是随着行业应用对自主软硬件要求的逐渐深入,一位工程师可能会碰到多种国产处理器和国产操作系统的开发需求。这就要求工程师具有软硬件的迁移适配能力,而具备这种能力的前提是,工程师要掌握与处理器运行原理有关的核心技能,这样在他的眼中,虽然处理器架构在变,但是万变不离其宗。这就是所谓“可重构的开发能力”。因此,行业对人才需求的变化,也对培养人才的高等院校提出了更高的要求。
符意德老师的《龙芯嵌入式系统软硬件平台设计》一书,符合电子信息和计算机产业发展阶段社会对于掌握应用迁移能力的、软硬件协同贯通型人才培养的需求,也为嵌入式方向课程引入国产软硬件教学内容带来了新的思路。
《龙芯嵌入式系统软硬件平台设计》是一个很好的开始,我对未来我国自主技术支撑我们国家自己的人才培养体系充满信心。
杜安利
龙芯中科技术股份有限公司副总裁
2023年1月
嵌入式系统是一种被广泛使用的计算平台,在工业控制、通信设备、医疗仪器、信息家电、军事装备等众多领域得到了广泛的应用。在国内许多院校中,“嵌入式系统”课程是计算机科学与技术、通信工程、网络安全、智能计算等相关专业的必修课程。目前,嵌入式系统硬件平台采用的微处理器种类很多,而“嵌入式系统”课程教材大多以ARM体系结构(一种精简指令集处理器架构)的硬件平台为背景来进行讲解,以我国自主研制的龙芯微处理器芯片为背景来进行讲解的教材较少。随着龙芯微处理器芯片的成熟及应用推广,系统地打造以龙芯微处理器芯片为背景的教材是非常有必要的,这可以帮助计算机科学与技术、通信工程、网络安全、智能计算等相关专业的学生掌握以龙芯微处理器芯片为核心的嵌入式系统的设计方法。想要完整地学习嵌入式系统的设计知识,需要进行多门课程的系统学习。本书重点讲解从事以龙芯微处理器芯片为核心的嵌入式系统平台设计工作的人员所必须掌握的基本知识。
嵌入式系统涉及的知识非常多,因此,对于初学者来说,结合自己的学习目标,找准学习嵌入式系统设计知识的切入点是非常必要的。狭义地说,学习嵌入式系统设计知识可以从两个不同的层面切入。第一个层面,对于将来只是应用嵌入式系统硬件平台、软件平台来进行二次开发的读者而言,应侧重提升基于某个嵌入式系统平台(包括硬件平台和软件平台)进行应用系统设计和开发的能力,即主要学习在某个嵌入式系统(如RT-Thread)环境下的应用程序的编写、调试,学习其API(应用程序接口)函数的使用,学习I/O部件的驱动程序编写等。第二个层面,对于将来想从事嵌入式系统平台设计工作,或者需要结合应用环境设计专用硬件平台的读者而言,需重点学习嵌入式系统体系结构及接口设计原理,即主要学习某个具有代表性的嵌入式微处理器(如龙芯1号系列)的内部寄存器结构、汇编指令系统、中断(异常)管理机制及常用的外围设备接口,同时要学习无操作系统下的编程技术,还需要学习启动程序的编写和操作系统移植等方面的知识。
本书是从嵌入式系统的平台构建角度来组织编写的,重点介绍了硬件平台和软件平台的构建方法。书中没有局限于某个具体的嵌入式微处理器芯片,而用了大量的篇幅来介绍其原理。但在介绍原理的同时,还列举了许多基于龙芯1B微处理器的设计示例,从而使原理、概念具体化。
在本书的写作中,卞岳良、王宁、王丽芳、符冠瑶给予了极大的支持与帮助,在此表示衷心的感谢。在本书的编写过程中,还得到了龙芯中科技术股份有限公司、苏州市天晟软件科技有限公司的支持及帮助,在此向他们表示感谢!
感谢本书责任编辑的支持及付出!
感谢家人给我的关心和支持!
嵌入式系统目前正处于快速发展的阶段,新的技术和应用成果不断地涌现,囿于笔者的水平,书中难免存在疏漏之处,希望广大读者批评指正。读者可将意见与发现的错误发送到邮箱njfyd@mail.njust.edu.cn。
符意德
2022年12月31日 于紫金山麓
嵌入式系统(Embedded System)是一种计算平台,是与应用目标紧密结合的专用计算机系统。它被广泛地应用在各种智能仪器及设备中(如日常生活中使用的智能手机、数码相机、汽车导航仪等,工作中使用的数字式仪器仪表、一些生产设备中的控制器等),起监视、控制等作用。本章将回顾嵌入式系统的发展过程,描述嵌入式系统开发流程,并介绍一种嵌入式系统的开发工具LoongIDE。
嵌入式系统本质上是计算机系统,其硬件的核心组成是微处理器、存储器、输入输出(I/O)端口。许多嵌入式系统设计中需考虑的问题也是计算机系统设计中需考虑的共性问题。但嵌入式系统在设计时,与通用个人计算机(Personal Computer,PC)相比,还具有许多特殊性。这是因为嵌入式系统通常与其所嵌入的设备紧密关联,并且其硬件资源有限。下面对嵌入式系统设计的特征进行介绍。
什么是嵌入式系统呢?目前对嵌入式系统的定义主要有两种。
第一种定义是传统的定义:嵌入其他设备中,起智能控制作用的专用计算机系统。也可以说,它是任意包含可编程计算机的设备,但是这个设备不是作为通用个人计算机而设计的。一台通用个人计算机不能被称为嵌入式系统,尽管有时会把它嵌入某些设备中。而一台嵌入数控机床里的控制器可以算作嵌入式系统。
第二种定义是目前比较流行的:以应用为中心,以计算机技术为基础,并且软硬件可裁减、软件固化的专用计算机系统。例如:数码相机、GPS(Global Positioning System,全球定位系统)导航仪就体现了这种特点,因此它们能被称为嵌入式系统;而笔记本计算机没有体现这种特点,因此它不能被称为嵌入式系统。
无论采用哪种定义来描述嵌入式系统,可以确定的是,嵌入式系统本质上是计算机系统。它是计算机系统的一种体现形式,因为它的硬件由微处理器、存储器、I/O部件组成,并且是由存储的指令来控制任务的执行,只不过它与应用目标紧密结合,硬件结构中的组成部件需要根据应用目标来定制,同时软件结构中的软件功能模块也需要定制。
我们可以把嵌入式系统的特征归纳如下。
(1)嵌入式系统与应用目标紧密结合,硬件组件需要定制(或称硬件裁减)。也就是说,设计者需要根据自己所设计的嵌入式系统的功能要求,自行设计硬件电路。除设计通用的电路,如微处理器与存储器的接口电路、时钟电路(或称晶振电路)、复位电路等之外,还需要设计一些专用部件的电路,如在设计、开发GPS导航仪时,设计者需要设计能够接收卫星定位信号的GPS模块的接口电路。
(2)嵌入式系统的软件组件也需要定制(或称软件裁减)。也就是说,设计者需要根据应用的功能要求,确定所设计的嵌入式系统是否需要操作系统作为软件平台,并设计专用的软件功能模块。通常情况下,如果嵌入式系统的应用软件可以设计成单任务形式,并且不需要具有图形化人机交互界面、以太网通信等复杂功能,那么设计应用软件时无须将操作系统作为软件平台。但如果嵌入式系统应用功能要求复杂,如需要处理多媒体信息、需要以太网通信功能等,那么其应用软件的开发通常需要基于某个操作系统(如Linux)来进行,这样可以缩短嵌入式系统的开发周期。若需要将操作系统作为软件平台,设计者还需要结合所设计的硬件结构,完成操作系统的移植和裁减,使操作系统能在该硬件环境下有效地运行。
(3)嵌入式系统的所有软件组件均需要存储在非易失性存储器中。把运行代码写入非易失性存储器中的过程叫作“软件固化”,这样可保证程序代码及数据在嵌入式系统断电以后不会丢失,从而保证嵌入式系统再次开机时能够正常运行。由于嵌入式系统中通常不用磁盘,而采用存储器作为系统的程序代码及数据的存储介质,因此嵌入式系统中软件固化是必需的。
(4)相对于通用个人计算机来说,嵌入式系统的硬件、软件资源受限。因为嵌入式系统通常对某些非功能性指标,如成本、体积、功耗等,有比较严格的要求,甚至到了苛求的地步,所以嵌入式系统的硬件、软件资源通常只要能满足应用需求即可,而没有更多的冗余。
由于与通用个人计算机比较而言,嵌入式系统有上述的几点特征,因此,嵌入式系统的设计、开发方法与通用个人计算机的应用系统的设计、开发方法相比,有以下几点不同。
(1)需要软硬件一体的设计理念。在嵌入式系统设计阶段,设计者需要根据应用功能需求,结合成本、体积、功耗等非功能性需求,综合考虑哪些功能由硬件完成、哪些功能由软件完成,并在开发实施阶段,根据硬件结构的具体情况,设计适用于该硬件结构的软件。
(2)需要系统软件与应用软件融合设计。系统软件通常是指管理及控制系统资源的软件,而应用软件是指具体实现用户所需功能的软件。嵌入式系统设计时,设计者往往需要完成系统软件和应用软件两部分的设计工作。例如:若嵌入式系统无操作系统,那么设计者除了要设计应用软件外,还要设计监控、管理硬件资源的软件,这两部分软件的代码通常融合在一个循环结构中;若嵌入式系统需要操作系统,那么设计者即使不设计操作系统,也需要完成操作系统的移植和裁减,并在完成应用软件的设计时,完成一些非标准的硬件接口驱动程序设计。
(3)需要建立交叉开发环境。嵌入式系统由于受到资源的限制,通常软件的开发环境与运行环境是不同的。也就是说,嵌入式系统开发时,需要借助通用个人计算机(称为宿主机)来完成嵌入式系统的软件编辑、编译、链接等工作,生成可执行文件;而运行时,必须把可执行文件下载到嵌入式系统(称为目标机)上,在宿主机上是不能直接运行的。这种宿主机-目标机的开发架构被称为交叉开发环境。
综上所述,嵌入式系统的设计与通用个人计算机应用系统设计的主要差别体现在设计手段和设计者需具备的技能上。嵌入式系统的设计者更需具备软硬件一体的综合设计技能。
嵌入式计算技术所面临的挑战源于基础技术的迅猛发展及用户需求的不断增加。在设计中,系统的功能对于通用个人计算机系统和嵌入式系统来说都是非常重要的。但是,与通用个人计算机系统的设计相比,嵌入式系统的设计有许多特殊的要求,主要体现在以下几方面。
(1)实时性。许多嵌入式系统需要在实时情况下工作。如果数据或控制信息在某个时限内不能到达,系统将会出现错误。在某些嵌入式系统中,实时性得不到满足是不能接受的,超过时限会引发危险甚至对个人造成伤害。如高速列车控制器,控制信息超时会引起列车运行故障,甚至翻车。而在某些嵌入式系统中,超过时限虽然不会引发危险,但会导致一些不愉快的结果。如打印机在打印时,若控制信息的响应超时,就会使打印机产生混乱。
(2)多速率。许多嵌入式系统不仅有实时性要求,而且需同时运行多个实时任务,系统必须同时控制这些任务,虽然这些任务有些处理得慢,有些处理得快。多媒体应用系统就是多速率的典型例子,多媒体数据流的音频和视频部分以不同的速率播放,但是它们必须保持同步。若音频数据或视频数据不能在有限时间内准备好,就会影响整体播放效果。
(3)功耗。功耗在通用个人计算机系统中不是一个需要主要考虑的因素,但在嵌入式系统中,尤其是在用电池供电的嵌入式系统中则是。大功耗会加大硬件使用开销,影响电源寿命并带来散热问题。
(4)低成本。多数情况下,我们都希望嵌入式系统是低成本的。制造成本由许多因素决定,其中包含硬件成本和软件成本。硬件成本主要取决于所使用的微处理器、所需的内存及相应的外围芯片;软件成本通常难以预测,但一种好的设计方法有利于降低软件成本。
(5)环境相关性。嵌入式系统不是独立的,而是与被嵌入的设备紧密关联的。因此,设计嵌入式系统时,必须考虑模拟量信号、数字量信号及开关量信号的输入输出,系统抗干扰性,温度和湿度等。
外部约束是设计嵌入式系统遇到的较大的困难。下面列出嵌入式系统设计过程中需考虑的一些主要问题。
(1)需要多少硬件。我们在设计嵌入式系统时不仅需考虑选择何种微处理器,还需考虑存储器容量、I/O设备及其他外围电路。要在满足系统性能要求的前提下,满足系统经济性要求:系统硬件太少,将不能满足性能要求;硬件太多,又会使产品变得过于昂贵,并降低可靠性。
(2)如何满足实时性要求。通过提高微处理器速度来使程序运行的速度加快,从而解决实时性问题的方法是不可取的,因为这是以增加系统成本投入为前提的。同时,仅仅提高微处理器的速度有时并不能提高程序运行速度,因为程序运行速度还受存储器工作速度的限制。因此应精确设计程序以满足实时性要求。
(3)如何降低系统的功耗。对于用电池供电的嵌入式系统而言,功耗是一个十分重要的考虑因素;对于不用电池供电的嵌入式系统而言,高功耗会带来高散热量。降低嵌入式系统功耗的一种方法就是降低它的运算速度。但是单纯降低运算速度会导致系统不满足实时性要求。应认真设计嵌入式系统,以便通过降低系统非关键部分的速度来降低系统功耗,同时满足系统的实时性要求。
(4)如何保证系统可升级。系统的硬件平台可能使用在不同代的产品中,或者使用在同一代但不同级别的产品中,且仅需做一些简单的改变。我们希望通过修改软件来改变系统的功能。如何才能设计一种硬件平台使它能够提供未来程序需要的功能呢?
(5)系统调试复杂。调试嵌入式系统比调试通用个人计算机上的程序困难得多。我们通常需运行整台设备以产生测试数据,而数据产生的时间往往是非常重要的。也就是说,不能离开嵌入式系统运行的整个环境来测试嵌入式系统。另外,嵌入式系统有时没有配备键盘和显示器,这导致我们不能了解系统的运行情况,也不能干预系统的运行,从而导致难以测试嵌入式系统。
(6)开发环境受限。嵌入式系统可用的开发环境(用于开发硬件、软件的工具)比通用个人计算机上的少。我们通常在通用个人计算机上将程序代码编译成机器码,然后将编译好的机器码下载到嵌入式系统中。为了调试这些代码,通常必须依靠运行在通用个人计算机上的程序来观察嵌入式系统的运行情况。
嵌入式系统是伴随着计算机理论及技术的发展而发展的。早在20世纪70年代初,随着微处理器的诞生,“个人计算时代”到来,就出现了嵌入式系统,只是那时的嵌入式系统的应用局限在工业控制和一些数字式仪器仪表中。那时计算机的体现形式主要是通用个人计算机,而不是嵌入式系统。但是到了21世纪初,随着普适计算(Ubiquitous Computing,又称泛在计算)理论的出现,伴随着智能手机等各种应用产品的涌现,嵌入式系统改变了以通用个人计算机为主的计算模式,使计算无处不在。嵌入式系统成为当代计算机的主要体现形式。
嵌入式系统硬件平台的核心部件是各种类型的嵌入式微处理器。在嵌入式系统的发展过程中,每个发展阶段均有一些微处理器作为主流芯片被大量使用。但是,没有哪一种微处理器处于绝对的垄断地位,这一点与通用个人计算机是不同的,这是因为嵌入式系统的应用需求多种多样,硬件平台很难统一。在国内,以下几种出现过的主流嵌入式微处理器,被大量用在相应各阶段的嵌入式系统上。
Intel 8080是Intel(英特尔)公司于1974年推出的微处理器,MC6800是Motorola(摩托罗拉)公司于1974年推出的微处理器,Z80是美国Zilog公司于1976年推出的微处理器。这些微处理器的数据位均是8位(bit),可直接寻址的存储器容量通常为64KB。
上述3种微处理器,在微处理器诞生的早期阶段(20世纪70年代中期~20世纪90年代初期),被广泛地用在了企业生产过程及其设备的控制中,那时嵌入式系统的产品形式主要是控制器,是嵌入其他设备中起控制作用的专用计算机,如数控机床的控制器、数字式温控器等。
由于这个阶段的微处理器内部一般没有集成特定功能的部件,如定时器部件、UART(Universal Asynchronous Receiver/Transmitter,通用异步接收发送设备)部件、A/D(模/数)转换部件等,因此嵌入式系统硬件平台需要外加具有专用功能的芯片来完成这些功能,并且外围的其他组合逻辑电路及时序逻辑电路通常采用74系列的芯片来完成设计。
MCS-51系列单片机是Intel公司生产的一系列8位数据宽度的微处理器的统称,由于这些微处理器中集成了存储器以及许多专用功能部件,如定时器部件、UART部件、A/D转换部件等,因此把它们称为单片机。与上面的Z80、Intel 8080等微处理器不同的是,它们有时被称为嵌入式微控制单元。这一系列微处理器包括许多品种,如8031、8051、8052、8055等。
自20世纪80年代Intel公司推出MCS-51系列单片机以来,该系列的微处理器迅速在嵌入式系统中得到广泛的应用,并逐步取代了Z80等微处理器,在工业控制器及智能仪器仪表等产品的硬件平台中成为主流。在我们的日常生活中,也涌现了许多以MCS-51系列单片机为核心的嵌入式系统产品,如用于公交车、食堂等场合的IC(Integrated Circuit,集成电路)读卡器,用于小区、办公区等场合的门禁系统,等等。目前,MCS-51系列的微处理器仍然在许多嵌入式系统的产品中得到应用。
为了满足更高的计算要求,Intel公司还推出了MCS-96系列单片机。这一系列的微处理器的数据宽度是16位,具有16位数据乘以16位数据的乘法指令,以及32位数据除以16位数据的除法指令。
DSP(Digital Signal Processor,数字信号处理器)微处理器是一系列适合完成数字信号处理工作的微处理器的统称。所谓数字信号处理,指的是信号(如音频信号、视频信号)经过A/D转换后的后续处理,主要有数字滤波、编码/解码等。这些信号处理工作涉及大量的乘法、加法运算。例如:进行数字滤波处理时,需要涉及卷积运算;进行编码/解码处理时,需要涉及傅里叶变换和傅里叶逆变换等;而卷积运算、快速傅里叶变换等算法均是采用多次相乘并累加来完成的。若采用普通的微处理器处理这些运算,需要执行的指令非常多(即通常需要采用多重循环结构来编程实现),效率很低。DSP微处理器具有专门的指令处理这些运算,效率要高得多。因此,DSP微处理器在需要进行信号处理的场合得到了广泛使用,如数码相机、VoIP(Voice over IP,互联网电话)机、机器人控制等领域。
目前,在国内,使用得最多的DSP微处理器是TI公司推出的TMS320系列的DSP微处理器。TI公司在1982年推出了首款DSP微处理器TMS32010,之后又推出了多种型号的DSP微处理器,以满足不同应用场合的需求。目前,TI公司的DSP微处理器主要有三大系列,具体如下。
● TMS320C2000系列的DSP微处理器。该系列的DSP微处理器适合应用在数字控制、运动控制的场合,主要的型号有TMS320C24×/F24×、TMS320LC240×/LF240×、TMS320C24×A/LF240×A、TMS320C28××等。
● TMS320C5000系列的DSP微处理器。该系列的DSP微处理器适合应用在手持设备、无线终端设备等功耗低的设备中,主要的型号有TMS320C54×、TMS320C54××、TMS320C55×等。
● TMS320C6000系列的DSP微处理器。该系列的DSP微处理器适合应用在高性能、多功能、复杂的应用领域,主要的型号有TMS320C62××、TMS320C64××、TMS320C67××等。
除了TI公司的DSP微处理器外,目前国内使用的DSP微处理器还有ADI公司、Motorola公司、Agere System公司等生产的DSP微处理器。
ARM系列微处理器也是一类微处理器的统称,它是指以ARM公司微处理器核为中心、集成了许多外围专用功能部件的芯片,如三星公司的S3C2440、Atmel公司的AT91SAM9260、Intel公司的PXA270等。目前,主流的ARM系列微处理器的数据宽度为32位,主频为几百兆赫兹。它们在许多嵌入式系统中得到广泛应用,如智能手机、PDA(Personal Digital Assistant,个人数字助理)、GPS导航仪等。
由于嵌入式系统的应用目标是多种多样的,ARM公司为满足这些多样性的要求,开发出了多种不同架构的微处理器核。因此,ARM系列微处理器根据其微处理器核的架构,又分成许多子系列。目前的子系列主要有ARM9系列、ARM9E系列、ARM10系列、ARM11系列、Cortex系列、XScale系列等。并且,ARM公司通过ARM架构授权、IP核授权或应用级授权,使ARM微处理器核被集成到许多智能移动芯片中,如高通公司的骁龙835芯片,其内部就集成了Cortex-A架构的微处理器核。
SOPC(System on a Programmable Chip,可编程片上系统)是一种新的计算机体现形式。它可以在一块FPGA(Field Programmable Gate Array,现场可编程门阵列)芯片中,通过软硬件协同设计技术来实现整个计算机应用系统的主要功能。它是嵌入式系统的一种特殊形式,也是嵌入式系统的一个发展方向。
SOPC的实现需要基于超大集成规模的FPGA芯片。通常,这个FPGA芯片上需要集成至少一个微处理器核(硬核或者软核)、片上总线、片内存储器以及大量的可编程逻辑阵列等。
SOPC上的微处理器核有硬核和软核两种。所谓硬核是指微处理器核由一个专门的硅片实现,也就是说,由FPGA芯片中的一组专用的硬件电路实现。例如:Xilinx公司推出的Zynq-7000系列芯片,内部集成了两个ARM的Cortex-A9微处理器硬核;Altera公司推出的Excalibur系列芯片,内部集成了一个ARM920T微处理器硬核。而所谓软核是指SOPC通过硬件描述语言(如Verilog)或者网表描述,利用FPGA芯片中的可编程逻辑部件实现的微处理器核。Nios Ⅱ就是一个典型的微处理器软核。
Nios Ⅱ是Altera公司于2004年推出的32位微处理器软核,具体包括3种软核:Nios Ⅱ/f(一种当时实现了最佳性能优化的软核,需要中等的FPGA逻辑资源使用量)、Nios Ⅱ/s(一种标准需求的软核,需要较少的FPGA逻辑资源使用量)、Nios Ⅱ/e(一种经济的软核,需要最少的FPGA逻辑资源使用量)。采用Quartus Ⅱ集成开发环境就可以方便地在FPGA芯片中构建Nios Ⅱ系统,以便支持SOPC的设计。
目前,国内使用的FPGA芯片主要是由Xilinx公司和Altera公司提供的。另外,Actel公司、Lattice公司、Atmel公司等提供的FPGA芯片在我国也有一些特定的行业选择使用。
开发基于SOPC的嵌入式系统,需要软硬件协同的综合设计。若嵌入式系统的应用功能需要用软件实现,则需要采用能支持C语言、C++语言开发的软件工具,利用C语言或C++语言等进行编程,设计完成该功能的软件代码。而若应用功能需要用硬件实现,则需要采用Verilog语言或VHDL(VHSIC Hardware Description Language,VHSIC硬件描述语言)来完成硬件逻辑电路的设计。并且软硬件的功能可以融合在一起,在一块FPGA芯片上实现。
前文大概介绍了嵌入式系统的硬件平台发展过程。在不同的硬件发展阶段,我国的嵌入式系统产品广泛地使用了若干种嵌入式微处理器。如今这些微处理器有些已经被淘汰了,不再使用,如Z80、Intel 8080、MC6800等,有些还在继续使用。目前,基于ARM+FPGA的嵌入式系统结构在嵌入式系统产品开发中得到了广泛的使用,但也不具备垄断地位,其他嵌入式微处理器也在一些领域得到应用,如MCS-51系列、DSP系列以及MIPS系列、PowerPC系列等。
目前,国产的龙芯微处理器在国内的许多领域得到应用。龙芯微处理器至今主要有三大系列产品——龙芯1号、龙芯2号、龙芯3号。其中龙芯1号又有龙芯1A、龙芯1B、龙芯1C、龙芯1E等子系列,它们面向嵌入式系统,主要被应用在智能仪器仪表、工业控制等领域。
硬件平台是嵌入式系统的基础,而软件平台是嵌入式系统的“灵魂”。早期的嵌入式系统由于应用需求简单,如整个系统的软件设计成单任务形式、采用LED(Light Emitting Diode,发光二极管)或LCD(Liquid Crystal Display,液晶显示器)显示、用RS-485总线进行联网等,因此设计者往往不需要基于某个操作系统来进行嵌入式系统软件开发,而把嵌入式系统的应用功能程序、硬件平台中各部件电路的驱动程序以及存储单元的分配等融合在一个大的循环结构中实现。也就是说,对于应用需求简单的嵌入式系统,整个系统的软件均由设计者自行设计完成,不需要操作系统作为软件平台。
但是随着人们对嵌入式系统的需求越来越复杂,如需要嵌入式系统具有图形化的显示、需要与互联网(Internet)联网、需要处理多媒体信息等,并且嵌入式系统的硬件结构也越来越复杂,这时设计者往往需要基于某个操作系统来进行嵌入式系统软件开发,以便减少工作量,从而提高系统开发效率。设计者一般通过移植一个适用于该应用需求的嵌入式操作系统作为软件平台,然后基于该软件平台来开发应用程序。应用程序控制着嵌入式系统的动作和行为,也就是完成应用功能;而操作系统控制及管理着嵌入式系统的硬件资源,并提供标准硬件资源操作的接口函数(即API函数),如图形显示的API函数、TCP/IP的API函数等,应用程序借助嵌入式操作系统完成与硬件的交互。
目前,在嵌入式系统中使用的操作系统有许多种,且没有哪一种嵌入式操作系统具有垄断地位,这一点与通用个人计算机中使用的操作系统有所不同。但无论采用哪一种嵌入式操作系统作为软件平台,嵌入式系统的软件都具有以下共同特点。
(1)所有软件代码均固化存储。所谓软件代码固化存储,是指系统程序代码(即操作系统等软件代码)和应用程序代码均需要烧写到非易失性存储器中,如Flash芯片,而不是存储在磁盘等载体中。这主要是因为嵌入式系统通常不用磁盘等存储介质,从而提高软件执行速度和系统可靠性。
(2)软件代码要求具有高效率、高可靠性。尽管半导体技术的发展使嵌入式微处理器的处理速度不断提高、存储器容量不断增加,但在大多数应用中,存储空间仍然是宝贵的,还存在实时性的要求。为此要求程序编写和编译工具的效率应较高,以减少程序二进制代码长度,提高运行速度。较短的代码也可提高系统的可靠性。
(3)系统软件有较高的实时性要求。在多任务嵌入式系统中,对重要性各不相同的任务进行统筹兼顾的合理调度是保证每个任务及时执行的关键,单纯提高嵌入式微处理器速度通常是无法完成或没有效率的,这种任务调度只能由优化编写的系统软件来完成。因此对于许多嵌入式系统而言,其软件的实时性是基本要求。
可以说,嵌入式系统的软件平台是随着越来越复杂的嵌入式系统应用需求发展起来的。虽然从20世纪80年代起,国际上就有一些IT组织和公司开始进行商用嵌入式操作系统的研发,但直到21世纪初,嵌入式操作系统在嵌入式系统的开发中才得到广泛的应用,并在开发中起到关键的作用。
在国内,比较流行的嵌入式操作系统有以下4种。
让·拉布罗斯(Jean J. Labrosse)于1992年完成μC/OS(Micro Controller Operating System, 微控制器操作系统)的设计,并于1998年推出了μC/OS-Ⅱ(2000年得到了美国联邦航空管理局的认证,可以在飞行器中使用,足见其安全性高);2009年则推出了μC/OS-Ⅲ。
μC/OS-Ⅲ是在μC/OS-Ⅱ基础上推出的新版本,是一个可移植、可裁减的实时多任务内核,其源代码是公开的,非常适用于具有实时性要求的嵌入式系统。目前,μC/OS-Ⅲ被广泛用在以各类MCU或DSP为核心开发的嵌入式系统中,如工业控制上的控制器、医疗设备、飞行器控制器、路由器等。
为了满足移植的要求,μC/OS-Ⅲ绝大部分的代码用ANSI(American National Standards Institute,美国国家标准学会)的C语言编写,包含一小部分汇编语言代码,其源代码文件下载的官网地址是https://www.micrium.com/。在进行μC/OS-Ⅲ移植时,设计者需根据自己开发的嵌入式系统硬件平台的具体情况,来修改与硬件相关的文件中的源代码,使其适合在此硬件平台上运行。
需要指出的是,μC/OS-Ⅲ实际上是一个实时操作系统内核,它为设计者提供了一组C语言函数库。也就是说,为基于它开发应用程序的设计者提供了任务创建、消息发送、消息响应等内核功能函数,并附带文件系统,以及图形界面、TCP/IP协议栈等标准I/O部件的API函数。而对于非标准的I/O部件,设计者在开发应用程序时需自己设计相关驱动程序。
Linux也是一种内核源代码开放的操作系统。严格地说,Linux一词本身只表示Linux内核,但在实际中,人们通常用Linux一词来泛指一种操作系统。这种操作系统是基于Linux内核的,并且使用GNU(一种自由软件操作系统)的各种工具软件来完成其上的应用程序开发,即完成应用程序的编译、链接、调试等开发工作。
林纳斯·贝内迪克特·托瓦兹(Linus Benedict Torvalds,又译为莱纳斯·贝内迪克特·托瓦尔兹)于1991年10月5日正式对外推出Linux内核的第一个版本——Linux 0.02。之后借助互联网,在世界各地计算机自由软件爱好者的共同努力下,Linux内核得到了不断的改进和完善,相继推出了Linux内核的其他版本。2003年,Linux 2.6正式发布,至今,该版本的内核源代码还是许多嵌入式系统开发者进行软件平台构建(即Linux移植)的蓝本。
Linux自诞生以来,其内核就没有停止过修改和升级,不同时期的内核版本格式也有所不同。在国内使用时间最长的版本是2003年发布的Linux 2.6,该内核版本的格式是Linux m.n.x,其中,m表示主版本号,n表示次版本号,x表示该版本错误修补的次数。2021年,Linux内核发布了5.14版本。Linux内核的稳定版本源代码可以通过其官方网站来获得。
Linux操作系统无论是在通用个人计算机上,还是在嵌入式系统中均得到了使用。在通用个人计算机上使用的Linux操作系统通常被称为桌面Linux系统,在国内,比较知名的商用桌面Linux系统有Red Hat公司的Red Hat Linux、Fedora、中国科学院的红旗Linux、麒麟软件的银河麒麟、统信软件的统信UOS等。
在嵌入式系统环境中运行的Linux,通常被称为嵌入式Linux。在通用个人计算机上,微软公司的Windows操作系统占据了领先地位,Linux要打破这个局面是非常困难的。嵌入式系统是Linux的重要应用场合,尤其是在智能手机、平板计算机、PDA、GPS导航仪等嵌入式系统产品中。由于Linux内核源代码开放,无版权使用费用,因此在这些产品中Linux可作为软件平台,来缩短和减少这些产品的开发周期与费用。可以说,Linux是嵌入式系统最重要的软件平台之一,但嵌入式系统也成就了Linux。
目前,市场上基于Linux开源内核而开发出的嵌入式Linux操作系统有很多,如美国风河(Wind River)公司的商用嵌入式Linux、诺基亚公司和Intel公司共同推出的MeeGo操作系统、Google公司推出的Android(安卓)操作系统等。其中,Android操作系统是目前国内非常流行的基于Linux内核的嵌入式操作系统,它被广泛地用在便携式设备上。
Android操作系统最初由安迪·鲁宾(Andy Rubin)开发,主要支持智能手机的应用。2005年,Google公司收购注资,并组建开放手机联盟进行修改补充;2007年11月5日正式对外展示;2008年9月正式发布Android 1.0,这是Android操作系统最早的版本。从此,Android作为智能手机的开源操作系统逐渐流行起来,并逐渐推广到了平板计算机及其他便携式设备上。Android实际上不仅是一种操作系统,它还包含用户界面、中间件以及一些应用程序,如SMS(Short Message Serv ice,短消息服务)程序、日历时钟、地图、浏览器等。
作为软件平台,Android提供了丰富的系统运行库,以供设计者开发Android应用程序时调用,并且提供了应用程序框架,便于设计者发布其所设计的功能模块。同时,通过应用程序框架,设计者可以使用系统核心应用软件的API函数以及其他设计者发布的功能模块。需要指出的是,Android的应用程序开发工具不再是GNU工具,而是Eclipse集成开发环境以及相关的SDK(Software Development Kit,软件开发工具包),这一点与传统的Linux应用程序开发有所不同。Eclipse集成开发环境可以到其官方网站上下载,SDK也可到Android相关网站下载。
无论采用哪种嵌入式Linux作为软件平台,设计者的重要工作都是基于Linux内核的某个版本进行移植、裁减,使之适合其需要运行的嵌入式系统硬件平台。本书介绍的内容正是做这个工作的重要基础。
VxWorks是美国风河公司于1983年推出的一种嵌入式实时操作系统,它具有高可靠性、高实时性,被广泛地用在航空、航天、通信等领域。例如,2008年5月登陆火星的凤凰号火星探测器和2012年8月登陆火星的好奇号火星探测器等都使用了VxWorks作为其软件平台。
VxWorks内核的多任务调度功能采用了优先级抢占方式,并支持同优先级任务间的时间片分时调度,这样可保证紧急的处理任务得到及时的执行。VxWorks除了提供基本的内核功能外,还提供与ANSI C兼容的I/O部件的驱动函数,这些驱动函数主要有键盘驱动、显示驱动、网络驱动、RAM(Random Access Memory,随机存取存储器)盘驱动等,并提供多种文件系统。
为了适应嵌入式系统硬件平台的多样性,用于嵌入式环境中的操作系统均需要有很好的可移植性。VxWorks的BSP(Board Support Package,板级支持包)提供了移植VxWorks操作系统的基础,它是操作系统上层功能程序与目标硬件平台的软件接口。换句话说,嵌入式系统设计者若需要在其设计的目标硬件平台上运行VxWorks操作系统,就需要修改BSP,使其适合运行在该目标硬件平台上。
VxWorks的BSP的主要功能包括硬件平台初始化和标准I/O部件的驱动加载,通常完成的功能如下。
(1)目标系统上电后的硬件平台初始化,具体完成的操作是:
● 异常向量表的处理;
● 禁止中断及看门狗部件(若有看门狗部件);
● 堆栈指针设置;
● 初始化存储器的控制器;
● 载入VxWorks段代码到RAM中;
● 引导VxWorks的内核。
(2)为VxWorks操作系统提供必要的硬件访问驱动函数,通常包括:
● ISR(Interrupt Service Processing,中断服务处理)函数;
● 定时器驱动函数;
● 串口驱动函数;
● Flash存储器驱动函数;
● LCD接口驱动函数。
基于VxWorks操作系统的开发,早期所使用的开发环境是Tarnado集成开发环境,目前多采用Workbench集成开发环境。
RT-Thread是一种实时操作系统,其内核源代码是开源的。它诞生于2006年,RT-Thread 1.0.0于2012年1月发布,RT-Thread 2.0.0于2014年8月发布,RT-Thread 3.0.3于2018年3月发布。目前,RT-Thread操作系统广泛地应用在物联网领域。
RT-Thread操作系统包含内核、组件及服务等,其架构如图1-1所示。内核层是RT-Thread操作系统的核心部分,具有多线程管理及调度功能,包括信号量、消息队列、邮箱等,以及内存管理、时钟管理、中断管理等。组件及服务层在内核层之上,通常与硬件细节无关,该层包括虚拟文件系统、网络协议栈、命令行界面等。
图1-1 RT-Thread操作系统架构
嵌入式系统的应用领域可以大致分成以下几个。
工业控制领域是嵌入式系统的传统应用领域,也是当前嵌入式系统应用中最典型、最广泛的领域之一。工业生产中的许多数字化生产设备、检测设备或检测仪器仪表、生产流水线的控制器等,都是典型的嵌入式系统产品。这个领域中的嵌入式系统应用复杂度高,既有满足相对简单应用需求的设备控制器,也有满足复杂应用需求的设备控制器(如基于嵌入式Web的可远程操控的设备控制器等)。
工业控制领域若按行业细分,又可以分成许多不同行业的应用领域,下面列举几个比较典型的工业生产行业应用。
(1)机械零件或整机生产行业中的自动化生产设备,如图1-2(a)所示。该行业中的数控机床、装配机器人、焊接机器人等都是典型的嵌入式系统产品。
(2)过程化生产行业中的过程控制设备,如化工生产过程控制设备、制药生产过程控制设备、自来水生产过程控制设备等,如图1-2(b)所示。
(3)电力生产及智能电网控制与检测设备,如图1-2(c)所示。
图1-2 嵌入式系统在几个工业生产行业中的应用
除了上述的工业生产行业外,还有其他许多生产行业也采用了嵌入式系统产品,这里就不一一叙述了。
现代农牧业是在传统农牧业基础上发展起来的,是相对于传统的、手工生产的农牧业而言的。现代农牧业采用了生物技术、信息技术以及生理学原理等来组织生产,生产中通常都采用了计算机管理及控制系统,使得农牧业生产集约化、高效化,农牧业产品优质、高产。
例如,现代农业的生产控制设备,如图1-3(a)所示。田间作物什么时候需要浇水、哪块地要浇水、浇多少水等,均由嵌入式系统进行信息的采集和控制,从而使得浇水及时、有效。
再例如,现代畜牧业的生产控制设备,如图1-3(b)所示。家禽什么时候喂食、喂水均由自动控制系统控制,所产蛋的流水包装也均由自动包装设备完成。这些系统和设备均由嵌入式系统进行控制。
图1-3 嵌入式系统在现代农牧业控制系统中的应用
智能交通系统(Intelligent Transportation System,ITS)是物联网的一种重要应用形式,是交通系统的未来发展方向。它利用信息技术、传感器技术、通信技术、控制技术等,对一个大范围内的地面交通运输网进行实时、准确、高效的综合管理和控制,从而减少交通负荷和环境污染、保证交通安全、提高运输效率等。
在智能交通系统中,有许多子系统涉及嵌入式系统的应用,如图1-4(a)所示,主要涉及车载电子设备和车辆控制系统、交通管理系统、电子收费系统等。
另外,汽车行业是我国飞速发展的一个行业,汽车上70%的创新来源于汽车电子系统,汽车电子系统具有巨大的发展空间。汽车电子系统包括车载音响、车载电话、防盗系统等产品,还包括汽车仪表、导航系统、发动机控制器(如空燃比控制、点火正时控制)、底盘控制器(如制动防抱死控制、驱动防滑控制、车辆稳定性控制)等技术含量高的产品,如图1-4(b)所示。在将来,汽车可能会成为娱乐中心和移动办公中心,汽车电子系统的各组成部分将会建立在标准通信协议基础上。随着MCU应用需求的增加,人们对在汽车电子系统中的嵌入式系统将有新的要求,如其可靠性和温度特性都不同于消费电子系统。嵌入式Linux等操作系统也将在汽车电子系统中得到广泛使用。
图1-4 嵌入式系统在智能交通系统及汽车电子系统中的应用
智能小区是指城市中由若干住宅楼群组成的,采用计算机技术、自动控制技术、IC卡技术、网络通信技术来构建其综合物业管理系统的人居区域。在我国,相关管理部门对智能小区所具备的功能有明确的要求,即智能小区的主要功能应有水/电/气(主要是天然气,北方城市还包括暖气)集中抄表、小区配电自动化、自动门禁系统、电动车自动充电桩、光纤到户、智能家居服务等,如图1-5(a)所示。
智能家居是智能小区的重要组成部分,以一户家庭的住宅为平台,利用综合布线技术、网络通信技术、嵌入式计算技术、自动控制技术等,把家居生活中有关的家电、照明、安全防范等设施集成,构建一个安全、便利、舒适的居住环境。
智能家居又称智慧家居或智能住宅,国外常用Smart Home表示。智能家居功能组成如图1-5(b)所示。信息家电是构成智能家居的重要元素。信息家电是指所有能提供信息服务或通过网络系统交互信息的消费类电子产品。如电视机、冰箱、微波炉、电话等都将嵌入计算机,并通过家庭服务器与互联网连接,转变为智能网络家电,还可以实现远程家电控制、远程教育等新功能。
图1-5 嵌入式系统在智能小区及智能家居中的应用
移动智能终端包括智能手机、PDA、平板计算机等。中国拥有世界上最大的手机用户群,智能手机已向着具有强大计算功能的方向发展,而不仅仅用于通信。在未来,新的移动、手持式设备将会得到极大的发展,通过这些设备人们可以随时随地进行互联访问。
嵌入式系统最早出现在20世纪70年代的武器控制中,后来用于军事指挥控制和通信系统,所以军事国防历来是嵌入式系统的一个重要应用领域。在现代各种武器控制(如火炮控制、导弹控制和智能炸弹的制导、引爆),以及坦克、军舰、战斗机、雷达、通信装备等陆、海、空多种军用装备上,都可以看到嵌入式系统的影子。
一种好的嵌入式系统设计方法是十分重要的,原因有3点:第一,它使我们对所做的工作进度有清晰的了解,可以确保不遗漏其中的细节;第二,可以使整个开发过程分阶段进行,从而做到有条不紊;第三,方便设计团队中的成员相互交流、相互配合以完成系统的设计目标。
图1-6给出了嵌入式系统设计的主要步骤。以自顶向下的角度来看,系统设计第1步从系统的需求分析开始;第2步是规格说明,对需设计的系统功能进行更细致的描述,这些描述并不涉及系统的组成;第3步是体系结构设计,在这一阶段以大的构件为单位设计系统内部详细构造,明确软、硬件功能的划分;第4步是构件设计,它包括系统程序模块设计、专用硬件芯片选择及硬件电路设计;第5步是系统集成,在完成了所有构件设计的基础上进行系统集成,构造出所需的完整系统。
图1-6 嵌入式系统设计的主要步骤
在设计之前,我们必须清楚要设计什么。在设计的最初阶段,我们应从客户那里收集系统功能的非形式描述,在此称其为需求;对需求进行提炼,以得到系统的规格说明,规格说明中应包含我们进行系统体系结构设计所需的足够信息。
在此把需求和规格说明区分开是有必要的,因为嵌入式系统的用户不是专业人员,他们对系统的描述是建立在他们想象的、系统应具备的功能基础上的,对系统可能有些不切实际的期望,表达需求时使用自己的话而不是专业术语。所以,必须将用户的描述转化为系统设计者的描述,从用户的需求中整理出正式的规格说明。
用户需求通常包括功能部分和非功能部分。非功能部分需求主要指性能、生产成本、尺寸和质量、功耗等。表1-1所示是一个在系统设计初始阶段使用的需求说明表格样本,可在该表格中用简练、清晰的语句描述用户对系统的基本需求。
表1-1 需求说明表格样本
项目 |
说明 |
---|---|
名称 |
|
目的 |
|
输入 |
|
输出 |
|
功能 |
|
性能 |
|
生产成本 |
|
功耗 |
|
尺寸和质量 |
● 名称。给该项目取一个名称是十分有用的,这可以使设计者和用户、设计者和设计者之间讨论这个项目时更方便,也可以使设计的目的更加明确。
● 目的。用一到两句话对系统需要满足的基本需求进行描述。如果你不能用一两句话来描述你所设计的系统的主要特性,说明你还不是十分了解它。
● 输入和输出。这两项内容较复杂,对系统的输入和输出进行描述,其应包括如下内容。
❏ 数据类型:I/O信号是模拟量信号、数字量信号,还是开关量信号。
❏ 数据特性:数据是周期性到达的还是随机到达的,每个数据有多少位。
❏ I/O设备类型:有什么类型的输入设备、什么类型的输出设备。
● 功能。这一项是对系统所做工作的更详细描述,通常从系统的输入到系统的输出来进行描述。例如,当系统接收到输入时,它执行哪些任务?用户通过界面输入的数据如何对系统产生影响?不同功能如何相互作用?
● 性能。性能主要指系统的处理速度及系统所处的运行环境。对性能的要求必须尽早明确,以便设计时随时检查系统是否达到性能要求。
● 生产成本。生产成本主要指硬件构件的费用。如果你不能确定将要花费在硬件构件上的确切费用,那么起码应对最终产品的价格有粗略的了解,因为价格最终会影响系统的体系结构。
● 功耗。对系统的功耗必须有粗略的了解,因为功耗决定系统是靠电池供电还是通过插座供电,这是系统设计过程中的一个重大决定。对于靠电池供电的系统,设计者必须认真地对功耗问题进行考虑。
● 尺寸和质量。对系统的物理尺寸和质量的了解有助于系统体系结构的设计。某些嵌入式系统对尺寸和质量的要求是非常严苛的。
下面以GPS移动地图为例来说明系统需求表(见表1-2)如何填写。
表1-2 GPS移动地图系统需求表
项目 |
说明 |
---|---|
名称 |
GPS移动地图 |
目的 |
为司机等用户提供图形化的移动地图 |
输入 |
一个电源开关、两个操作按钮、GPS信号输入 |
输出 |
LCD,分辨率为400×600 |
功能 |
可接5种GPS信号接收器,具有3种用户可选的地图比例,总是显示当前经纬度 |
性能 |
0.25s内即可更新一次屏幕,常温下工作 |
生产成本 |
1500元 |
功耗 |
4节电池供电应可连续工作8h,功耗约为100mW |
尺寸和质量 |
尺寸不大于20cm×30cm,质量不大于0.25kg |
GPS移动地图是一种手持设备,该设备为用户(如汽车驾驶员)显示他当前所处位置及周围的地图,显示的地图内容应随用户以及该设备所处位置的改变而改变。该设备从GPS得到位置信息。移动地图的显示看起来应类似纸张上的地图。
规格说明应更精确地反映用户的需求,它是设计者在设计时必须明确遵循的要求。规格说明应小心编写,描述应足够清晰,不能有歧义,以便设计者可以通过它来验证设计是否达到要求。规格说明中通常只描述系统应做什么,而不描述系统该怎么做。
描述规格说明的工具可采用UML(Unified Modeling Language,统一建模语言)。UML是一种面向对象的建模语言,它是软件工程课程中详细讲解的内容。本书附录简要地介绍了它的概念和图形工具。
体系结构设计的目的是描述如何实现系统的功能,它是系统整体结构设计的计划。下面以一个具体的体系结构设计为例,让读者明了如何进行体系结构设计。
图1-7以框图的形式描述了GPS移动地图的体系结构,展示了GPS移动地图的主要功能及其数据流。框图很抽象,还没有规定软件完成什么、专用硬件完成什么等。但框图还是清楚地描述了许多功能,如需搜索地图数据库、需显示地图、需接收GPS信号等。
图1-7 GPS移动地图的体系结构
只有在完成了一个并未涉及太多具体实现细节的初始体系结构的设计后,才可能把系统框图再分成两部分:一部分针对硬件,另一部分针对软件。将图1-7细分成硬件结构、软件结构两部分,分别如图1-8和图1-9所示。
图1-8 GPS移动地图的硬件结构
图1-9 GPS移动地图的软件结构
系统结构描述必须同时满足功能部分和非功能部分的需求,不仅要体现所需求的功能,而且必须符合成本、速度、功率和其他功能约束。先从系统体系结构开始,逐步把这一结构细化为硬件和软件体系结构是确保系统符合规格说明的一种好方法,即我们首先集中考虑系统中的功能约束,然后在设计硬件和软件结构时考虑非功能约束。
体系结构设计告诉我们需要什么样的构件,而构件设计就是设计或选择符合体系结构和规格说明要求的构件。构件通常既包括FPGA、电路板等硬件,也包括软件模块。
一些硬件构件是现成的。现成的硬件构件既有标准构件,也有专用构件,例如CPU芯片、存储器芯片等就是标准构件,而在GPS移动地图中的GPS信号接收器就是专用构件。同样,软件构件也可利用标准软件模块,如地图数据库及数据库标准访问例程和函数。在系统开发时,采用标准软件模块可以节约开发时间。
更多情况下,我们需要自己设计一些构件,即使采用标准的集成电路(IC),也必须设计连接它们的印制电路板(PCB),同时需做大量的定制编程。当然,建立嵌入式软件模块时,你必须利用专业技能来确保系统实时性良好,并且在允许的范围内不占用更多的存储空间。在GPS移动地图这个例子中,电能消耗特别重要,设计时应尽量减少存储器读/写次数,因为存储器的访问是主要的功耗来源,存储器的访问必须精心安排,以避免多次读取相同的数据。
只有建立构件后,才能将它们合并,从而得到一个可以运行的系统。当然在系统集成阶段并不是把所有的构件连接在一起就行了,通常设计者都会发现以前设计上的错误。而好的计划能帮助我们快速发现系统错误并改正它们。在系统集成时按阶段构架系统,并且每次只对一部分模块排错,能够更容易地发现并定位错误。只有在系统集成的早期修正这些错误,才能更好地发现并修正那些在系统高负荷、长时间运行时才会出现的复杂的或者含混的错误。我们必须确保在体系结构设计和各构件设计阶段尽可能按阶段集成系统,并相对独立地测试系统功能。
系统集成时要准确定位出现的错误是非常困难的,因为嵌入式系统开发中使用的调试工具有限,比台式计算机少得多。嵌入式系统本身的这一特性,就决定了在系统集成阶段,要准确确定系统为何不能正确工作以及如何对此进行修复是很困难的。在这一阶段,设计者的专业知识和经验将起很大的作用。
嵌入式系统的开发,通常都需要借助开发工具及平台。一个好的开发工具,能够有效地帮助嵌入式系统设计者缩短其产品的开发周期,并帮助提高产品的质量和性能。
嵌入式系统的开发工具主要包括工程项目管理器、编辑器、编译/链接器、调试器、模拟器、分析工具、建模工具等软件工具,以及一些必要的硬件调试、观测设备,如JTAG(Joint Test Action Group,联合测试行动小组)接口仿真器、逻辑分析仪、示波器等。通常,开发软件工具供应商会把多种软件工具集成在一起,构成一个高效的、图形化的嵌入式系统开发平台,这个开发平台被称为嵌入式系统的集成开发环境(Integrated Development Environment,IDE)。也就是说,集成了代码编写功能、分析功能、编译功能、调试功能等工具的开发软件包,都可被称为集成开发环境。
对于不同的嵌入式系统应用需求,可选用的微处理器芯片以及以此芯片为核心开发出的硬件平台通常会不同,因此选用的集成开发环境也不同。嵌入式系统的集成开发环境有许多种,由于本书是以龙芯1B系列芯片为背景来介绍的,因此开发工具的介绍以LoongIDE为主。
LoongIDE是龙芯1x芯片的嵌入式开发工具套件,它内部包含LS1x DTK工具,支持C/C++语言、MIPS汇编语言,可以创建、编译/链接以及调试基于龙芯1x芯片的嵌入式系统应用程序。LoongIDE有以下几个主要特点。
(1)以项目为单位进行源代码管理,具有功能强大的C/C++、MIPS汇编代码编辑器。
(2)实时代码解析引擎,实现光标处头文件、类、变量、函数等定义原型的快速定位。
(3)集成LS1x的RTEMS BSP,提供LS1x 片上设备的驱动程序,支持Posix 1003.1b软件标准。
(4)使用优化的RTEMS GCC for MIPS工具链,支持-mips32/-mips32r2和-mhard-float等编译选项。
(5)支持基于RT-Thread、FreeRTOS、μC/OS裸机项目的开发,自动生成项目框架代码和提供部分libc库函数支持。
(6)基于EJTAG(Enhanced Joint Test Action Group,增强型联合测试行动小组)设备的C、C++和MIPS汇编语言的源代码级的单步调试,并具有基于PMON TCP/IP快速下载待调试项目到目标机的功能。
(7)提供多种Flash的编程方式,方便用户部署项目应用。
LoongIDE与基于龙芯1x 芯片的目标系统之间建立的交叉编译环境如图1-10所示。采用Windows操作系统的主机(即个人计算机或笔记本计算机)是宿主机,其上安装了LoongIDE;龙芯1x开发板是目标机;LxLink是用于芯片级调试的、具有EJTAG接口的仿真器(有的开发板上具有LxLink功能的电路),它与宿主机连接采用USB信号接口,与目标机连接采用EJTAG信号接口。LxLink支持在线调试基于龙芯1x的目标机,并支持NOR Flash芯片的编程。
图1-10 LoongIDE与基于龙芯1x芯片的目标系统之间建立的交叉编译环境
LoongIDE的操作界面由菜单栏、工具栏、项目视图窗口、代码编辑窗口、代码解析窗口、消息提示窗口和状态栏等部分构成。其运行后的操作主界面如图1-11所示。其中代码编辑窗口和消息提示窗口分别用于源代码编辑和源代码调试的操作。
图1-11 LoongIDE运行后的操作主界面
菜单栏集中了用户操作的主要功能,包括文件、编辑、项目、调试、工具、窗口、帮助等菜单。各菜单下又有许多子菜单。
(1)“文件”菜单下的子菜单如图1-12所示。它主要提供新建项目、新建源代码文件,以及打开文件、保存等操作。
图1-12 “文件”菜单下的子菜单
(2)“编辑”菜单下的子菜单如图1-13所示。它主要提供文件编辑中的复制、粘贴、查找、替换等操作。
(3)“项目”菜单下的子菜单如图1-14所示。它主要提供对已经存在的项目进行打开项目、关闭项目、添加文件到项目、从项目删除文件,以及编译等操作。
图1-13 “编辑”菜单下的子菜单
图1-14 “项目”菜单下的子菜单
(4)“调试”菜单下的子菜单如图1-15所示。它主要提供对项目进行调试的操作功能,包括运行、单步进入、单步跳过等调试方式。
(5)“工具”菜单下的子菜单如图1-16所示。它主要提供工具链设置、编辑器选项、NOR Flash编程、NAND Flash编程等操作。
图1-15 “调试”菜单下的子菜单
图1-16 “工具”菜单下的子菜单
(6)“窗口”菜单下的子菜单如图1-17所示。它主要提供把相关窗口或工具栏添加到操作主界面上的功能。
(7)“帮助”菜单下的子菜单如图1-18所示。它主要提供链接各种帮助文档的功能,如LS232 编程参考手册、GNU C/C++语言参考等。
图1-17 “窗口”菜单下的子菜单
图1-18 “帮助”菜单下的子菜单
工具栏提供给用户一种快速操作的手段,它包括文件操作、项目操作、调试操作、界面切换操作等的快捷按钮。
(1)文件操作的快捷按钮包括打开文件、新建文件、保存全部、查找、撤销等,具体如图1-19所示。
(2)项目操作的快捷按钮包括关闭项目、批量添加文件、批量删除文件、编译等,具体如图1-20所示。
图1-19 工具栏中文件操作的快捷按钮
图1-20 工具栏中项目操作的快捷按钮
(3)调试操作的快捷按钮包括开始调试、停止调试、单步跳过、单步进入等,具体如图1-21 所示。
(4)界面切换操作的快捷按钮包括C/C++、Debug等,具体如图1-22所示。
图1-21 工具栏中调试操作的快捷按钮
图1-22 工具栏中界面切换操作的快捷按钮
操作窗口分为“编辑”和“调试”两种显示形式。对于编辑显示形式,操作窗口主要分成4个,即代码编辑窗口、项目视图窗口、代码解析窗口、消息提示窗口,如图1-11所示。其中用于代码编辑的代码编辑窗口不可关闭,而项目视图窗口、代码解析窗口、消息提示窗口可以根据操作需要进行打开或者关闭。调试显示形式的操作窗口将在1.4.4小节中介绍。
(1)代码编辑窗口利用“文本编辑器”对文本文件进行编辑,可以完成C/C++、MIPS汇编语言等源文件和头文件的编辑,支持C/C++语法高亮显示、支持剪贴板操作等。图1-23是一个利用代码编辑窗口进行C语言源文件编辑的示例。
图1-23 代码编辑窗口编辑示例
(2)项目视图窗口以树形目录结构展示当前工程项目的全部文件夹以及文件夹下的文件,其树形目录结构展开后如图1-24所示。
图1-24 项目视图窗口中的树形目录结构
(3)代码解析窗口也以树形目录结构显示当前代码编辑窗口编辑的源代码、头文件的解析结果,但不解析工具链的头文件,其树形目录结构展开后如图1-25所示。
图1-25 代码解析窗口中的树形目录结构
(4)消息提示窗口用于向用户反馈当前操作的状态信息,由“控制台输出”“搜索结果”“编译错误”3个选项卡组成,如图1-11所示。“控制台输出”选项卡用于通用信息交互。“搜索结果”选项卡用于显示菜单栏中“编辑→在文件中查找”的查找结果,并可快速定位。“编译错误”选项卡用于显示项目编译的错误信息,并可快速定位。图1-26是消息提示窗口的应用示例。
(a)“控制台输出”选项卡的示例
(b)“搜索结果”选项卡的示例
(c)“编译错误”选项卡的示例
图1-26 消息提示窗口的应用示例
LoongIDE以项目为单位,对源代码文件以及其他配置、资源文件进行管理,其能够管理的文件类型主要有以下几种。
(1)项目文件,文件的扩展名为.lxp。
(2)用C/C++语言编写的源代码文件,文件的扩展名为.c或.cpp。
(3)用MIPS汇编语言编写的源代码文件,文件的扩展名为.S。
(4)C/C++语言的头文件,文件的扩展名为.h或.hpp。
(5)用于#include的源文件,文件的扩展名为.inl。
(6)项目配置文件,文件的扩展名为.layout。
LoongIDE为了便于用户开发裸机环境下的应用程序,或者开发RT-Thread、FreeRTOS、μC/OS环境下的应用程序,提供了一个名为start.S的启动文件。该文件内部包含应用程序的入口,其不可被改名,因为它是GCC链接时链接的第一个文件,但其内部的语句可以根据具体应用需求进行改动,不过引导应用程序的语句不能随意改动。
另外,LoongIDE提供了具有指定文件名的链接脚本文件,其文件名为ld.script/linkcmds。生成makefile.mk时首先会查找ld.script脚本文件,再查找linkcmds脚本文件。
LoongIDE中新项目建立的操作步骤如下。
(1)在安装了LoongIDE的宿主机上,单击运行LoongIDE.exe程序,即可进入LoongIDE的主界面,如图1-27所示(这个界面是初次运行LoongIDE的界面,若不是初次运行,则界面如图1-11所示)。
图1-27 初次运行LoongIDE的主界面
(2)进入主界面后,在新建项目之前,需要设置一些初始信息,包括语言设置、工作区目录设置、GNU工具链设置等,其操作如下。
● 语言设置:打开菜单“Tools→Environment Options”,进入环境变量设置对话框,如图1-28所示。选择合适的语言后,单击“OK”按钮即可。若设置的语言是“简体中文(Simple Chinese)”,单击“OK”按钮后,界面中的操作菜单等就是简体中文显示。
图1-28 语言设置操作界面
● 工作区目录设置:打开菜单“工具→环境变量设置”,选择“目录(Directories)”选项卡,然后从文件系统中选择工作区目录,作为新建项目的默认存放目录,如图1-29所示。
图1-29 工作区目录设置操作界面
● GNU工具链设置:打开菜单“工具→GNU C/C++工具链”,即可进入图1-30所示的界面。若在初始安装LoongIDE时,已经同时在同一目录下安装了工具链,则在初始运行LoongIDE时,会自动加载工具链;否则,需要通过单击“增加工具链”按钮来加载工具链。操作示意如图1-31所示。
图1-30 GNU工具链设置界面
图1-31 增加工具链的操作示意图
如图1-31所示,需要增加工具链时,单击“增加工具链”按钮,选择工具链所在目录,系统将查找并加载工具链和BSP。然后,从“可用工具链”列表中选中一个,单击“设置默认工具链”按钮,则被选中的工具链在“默认工具链”文本框中显示。同时,在界面右侧,可以看到工具链和BSP的基本信息,其中“符号表”在编程时可引用为C/C++/ASM的宏定义。
(3)初始信息设置好后,就可以单击菜单栏中的“文件→新建→新建项目向导”来创建用户项目框架。新建项目向导的首界面如图1-32所示。然后,向新建项目中添加源代码等文件,实现项目要求的功能。
图1-32 新建项目向导的首界面
图1-32所示为设置项目的基本信息,用户可以在“项目名称”文本框中输入自定义的项目名称(系统会自动加上项目文件的扩展名.lxp),并指定项目的文件夹位置。设置好基本信息后,单击“下一页”按钮,进入下一步操作界面。
(4)根据项目的需求,设置MCU型号、工具链和操作系统等配置选项,其界面如图1-33所示。
图1-33 MCU型号、工具链和操作系统设置界面
图1-33中,MCU型号需要根据项目实际使用的MCU芯片来选择;“工具链”下拉列表框,用来选择项目编译时使用的工具链;“使用RTOS”下拉列表框,用来选择项目是基于裸机编程[None(bare programming)],还是基于某个实时操作系统编程,可选的实时操作系统有μCOS-Ⅱ(正确书写应为μC/OS-Ⅱ)、FreeRTOS、RT-Thread等。完成这个界面的设置后,单击“下一页”按钮,进入下一步操作界面。
(5)完成实时操作系统的组件添加。根据第(4)步在“使用RTOS”下拉列表框中选择的不同实时操作系统,单击“下一页”按钮后,将会进入不同的操作界面。
● 当在第(4)步操作中,在“使用RTOS”下拉列表框中选择裸机编程,或者选择μCOS-Ⅱ,或者选择FreeRTOS后,单击“下一页”按钮将进入图1-34所示的组件界面。根据实际需要在组件列表中进行勾选。
图1-34 选择裸机编程/μCOS-Ⅱ/FreeRTOS时的组件界面
● 当在第(4)步操作中,在“使用RTOS”下拉列表框中选择RT-Thread后,单击“下一页”按钮将进入图1-35所示的组件界面。根据实际需要在组件列表中进行勾选。
图1-35 选择RT-Thread时的组件界面
● 当在第(4)步操作中,在“使用RTOS”下拉列表框中选择相应的RTEMS后,单击“下一页”按钮后将进入图1-36所示的组件界面。项目将使用已移植好的龙芯1x RTEMS板级支持包进行开发。
图1-36 选择RTEMS时的组件界面
完成相关实时操作系统的组件添加后,单击“下一页”按钮,进入下一步操作界面。
(6)新建项目汇总界面如图1-37所示,确认并完成新建项目向导的操作,单击“确定”按钮后,将建立一个新项目的程序框架,如图1-38所示。
图1-37 新建项目汇总界面
图1-38 一个新建项目的程序框架示例
项目新建完成后,可以在项目中新建或添加源代码文件、头文件、库文件等,然后进行编辑、保存文件等操作。
若项目文件已经存在,就不需要再进行新项目的建立操作,而可直接进行打开、添加、保存、关闭等相关操作。
(1)单击菜单“项目→打开项目”或者单击工具栏中的按钮,即可进入图1-39所示的界面,然后选择要打开的项目文件(扩展名为.lxp),单击“打开”按钮,即可打开已有的项目。
图1-39 打开已有的项目文件操作界面
(2)单击菜单“项目→添加文件到项目”或者单击工具栏中的 按钮,可以实现向项目中批量添加文件,其操作界面如图1-40所示。
图1-40 向项目中批量添加文件的操作界面
图1-40中,左边是被选择的源文件夹及源文件的树形目录,右边是项目中的树形目录及相关文件夹下的文件。若要向右边的项目目录中批量添加文件,先在左边的树形目录中选中需要添加的文件夹或文件(可以使用 Ctrl+单击来多选),然后单击界面中部的 按钮,被选中的文件夹或文件就会被添加到当前项目的文件夹中。
(3)单击菜单“文件→保存全部”或者单击工具栏中的按钮,即可进行项目的保存。若项目中的文件被修改过,在关闭项目前将提示是否保存。
(4)单击菜单“项目→关闭项目”或者单击工具栏中的按钮,即可关闭当前打开的项目。
当项目中的源代码编辑完成后,可以进行编译,通过编译操作可以发现项目中的语法错误。若无语法错误,可以生成MIPS ELF格式的可执行程序(扩展名为.exe)。
(1)在正式编译之前,可以对编译器的一些参数进行设置,这些编译参数将决定 GCC(GNU Compiler Collection,GNU编译器套件) 编译器的行为,对最终生成的可执行程序有决定性影响。
当项目打开后,单击菜单“项目→编译选项”可以进入编译参数设置界面,如图1-41所示。
图1-41中,左边是参数设置的树形列表,若需要设置某个参数,则单击树形列表中对应的条目,右边即可显示相应的参数设置界面。例如,若单击树形列表中的“MIPS & BSP Options”条目,则右边显示图1-42所示的参数设置界面。
图1-41 编译参数设置界面
图1-42 MIPS & BSP Options的参数设置界面
(2)单击菜单“项目→编译”,或者单击工具栏中的 按钮,即可启动用户项目的编译。若编译成功,则会在消息提示窗口的“控制台输出”中看到图1-43所示的信息;若编译失败,则会在消息提示窗口的“编译错误”中看到图1-44所示的信息。
图1-43 编译成功时显示的信息
图1-44 编译失败时显示的信息
项目只有编译成功后,才可以进行调试。在进行项目调试前,还需要进行调试参数的设置。
(1)单击菜单“调试→调试选项”,或者单击工具栏中的按钮并在其下拉列表框中选择“调试选项”,即可打开调试选项的操作界面,如图1-45所示。其中有4个选项卡:“主要”“调试器”“启动项”“源代码”。图1-45显示的是“主要”选项卡的内容。
图1-45 调试选项的操作界面
图1-45中,“C/C++应用程序”文本框中显示的是当前将要进行调试的项目应用程序文件名,其他参数根据需求来进行选择。
(2)若要进行调试器参数的设置,单击“调试器”选项卡即可进入其操作界面,如图1-46所示。
图1-46 “调试器”选项卡的操作界面
图1-46中,“调试接口”中选择的是通过LxLink 设备连接 EJTAG 接口,这个选项不要修改,采用默认设置,其他参数根据实际情况进行设置。
(3)若要进行启动项参数的设置,单击“启动项”选项卡即可进入其操作界面,如图1-47所示。
图1-47 “启动项”选项卡的操作界面
图1-47中,“断点自动设置在”文本框用于输入一个函数名称,调试启动后,断点自动设置在该函数的第一条语句处。默认情况下,裸机编程项目对应的函数名称为main,RTEMS编程项目对应的函数名称为Init。其他参数根据实际情况进行设置。
(4)若要进行源代码参数的设置,单击“源代码”选项卡即可进入其操作界面,如图1-48所示。
图1-48 “源代码”选项卡的操作界面
在图1-48中,如果应用程序在链接时使用了项目文件以外的.o目标文件和.a库文件,并且使用了-g参数编译,在此处增加对应.o目标文件和.a库文件的源代码目录,用于调试时自动搜索。
项目的调试操作步骤如下。
(1)单击菜单“调试→运行”,或者单击工具栏中的 按钮,LoongIDE将进入用户调试主界面,如图1-49所示。
图1-49 用户调试主界面
图1-49中主要有4类窗口:文本编辑窗口、断点列表窗口、参数观测窗口(用于观测程序运行断点处的CPU寄存器值)、消息窗口。调试运行时,用户界面会切换到“调试”状态,LoongIDE 将项目应用程序下载到目标机,同时在状态栏上显示项目下载的进度。下载完成后,可以正式开始应用程序调试。
(2)应用程序运行后,调试器将控制程序进入初始断点位置。初始断点位置有两种情况:
● 若在调试选项启动项界面中的“断点自动设置在”文本框中设置了函数名称main(见图1-47),那么初始断点将自动设置在该函数的第一条可执行语句处;
● 若没有设置,则初始断点将设置在项目应用程序的第一条语句处,一般是 start.S 的第一条指令处。
(3)进入初始断点后,即可通过单步运行或者连续运行等操作来进行程序的调试运行。其操作可以通过工具栏中的快捷按钮进行,如图1-50所示。
图1-50 工具栏中用于调试的快捷按钮
在图1-50中,当单击按钮时,会从当前断点处运行到下一个断点处再停止。当单击单步操作相关的按钮时,则能一步一步地运行指令。单击按钮将结束本次调试,用户界面将自动切换到“编辑”状态。
(4)在任何一个断点处,均能实时查看变量值,以及设置断点、设置观察变量等。断点的设置可以通过单击文本编辑器中源代码的行号来实现。单击行号可以把对应行的代码设置为断点,再单击行号就可以把已设好的断点移除,如图1-51所示。
图1-51 断点的设置操作
对于观察变量,右击“观察变量”面板,会弹出图1-52所示的快捷菜单,可单击相关命令来进行增加、编辑、移除观察变量等操作。
图1-52 观察变量的快捷菜单
当需要给某个变量赋一个参数值时,单击“编辑观察变量”命令,进入图1-53所示的界面,在文本框中输入观察变量名称,单击“确定”按钮后,该变量值将被赋给相应变量并带入调试程序中运行。
图1-53 编辑观察变量的操作界面
通过反复地进行编辑、编译、调试等操作,把当前项目程序中的所有错误修正后,项目的开发工作就算完成了。