User Tools

Site Tools


tech:embedded:embedded_guide

嵌入式开发指南

此页面内容陈旧,需要更新:!:

在线调试器(ICD)

早期的嵌入式开发是非常依赖于ICD的,这种设备一端通过JTAG口与目标开发板连接,另一端接到PC机的通信端口上(串口或并口等),从而,运行于PC 机上的软件可以与目标板上的处理器进行通信,读写处理器的寄存器和存储空间,单步执行程序代码。ICD软件一般是与包含有编译工具链、编辑器的集成开发环境绑定在一起的,它们可能由处理器的生产商提供,也可能是第三方的商家所开发。

以下是笔者在开发过程中曾经使用过的若干开发环境(及附带仿真软件):

  • Silicon Lab IDE:该开发环境包含51系列MCU的仿真软件,由Silicon Laboratories公司提供,该公司同时生产51核的MCU。
  • Keil C:可能是最强大的51开发环境了,由Keil公司出品,该公司还提供ARM、philips LPC、Infineon C16x等处理器的开发环境。
  • Code Composer Studio:这是TI为其DSP芯片开发的集成开发环境,初次接触该软件是在2001年的跟踪器项目中,为其强大的功能所折服,自以为绝不亚于 Microsoft的VisioStutio。

随着板上嵌入式OS的成熟,开发过程对ICD的依赖性开始降低。以基于ARM处理器的开发为例,购买一块Intel的Assabet开发板在嵌入式 Linux的环境中进行应用开发,整个过程可以完全脱离ICD。于是,ICD的应用环境也渐渐限于板卡硬件开发过程中的调试和验证了。

程序的烧写

程序的载体必须具备一个最起码的特征,即系统掉电后程序不会丢失,否则,每次启动系统都需要重新从外部载入程序,这对用户来说是无法忍受的。RAM显然不是合适的选项,虽然在系统的运行过程中常常确实有代码存储于其中。

在早期的嵌入式系统中,最常用的程序载体是EPROM或EEPROM,这种载体满足以上的不易失特征,但它是只读的,因而无法在线写入程序,唯一的方法是利用编程器对其进行离线编程,然后将已经烧入程序的芯片接入电路中。这种情况下,程序每次发生改动,开发者都需要将大而笨的ROM芯片从插座上拔下,装到编程器上编程,然后再插回到插座上。当然,在仿真器的帮助下,开发者也可以将程序直接写到RAM中,经过调试确认无错后再决定使用编程器(然而,若干年前笔者还是接触过许多贫穷而执着的开发者,他们可以完全利用编程器和板上的LED显示灯完成许多并不算简单的开发,敬佩中)。

Flash这种设备出现后,除了利用编程器进行离线编程,在线编程也成为一种烧写程序的方法。Jflash便是一种Flash在线编程软件,它最初是为小型arm-linux板lart设计的,可以通过arm处理器的JTAG口将程序写入处理器总线上的Flash中。

那么,我们还需要编程器吗?

什么是Boot Loader

boot loader不是必须的,比如早期基于51MCU的开发,烧入程序的不易失存储设备映射到处理器的指令空间中,处理器直接从不易失存储设备中取指执行。

然而,在很多情况下,处理器并非直接从EEPROM或FLASH等不易失存储设备中取指执行,有时候是考虑到传输速度的因素,有时候硬件的设计使处理器无法从不易失存储设备中读取指令(例如指令空间和数据空间相互独立的处理器无法从映射在数据空间的不易失存储设备中取指),因而,需要首先将程序代码转移到合适的存储位置(一般是RAM中,对于指令空间和数据空间相互独立的处理器,该RAM要求位于指令空间),然后开始执行。Boot Loader就是完成这个任务的程序。

以下据几个boot loader过程的实例:其一来自2001年的跟踪器项目,采用TMS320C5402处理器,无板上嵌入式OS:该处理器采用的是哈佛结构,具备相互独立的指令空间、数据空间和IO空间。其中,映射到指令空间的片内ROM中存放有厂商提供的boot loader程序,该程序可以将数据空间的数据传输到指令空间。因此,存放程序的不易失存储设备应当映射到数据空间中,在系统加电后由boot loader程序转移到映射到程序空间的片内RAM或片外扩展RAM。其二来自智能终端项目:在装有WinCE的PDA上运行程序bootblaster,通过串口从主机将boot loader程序(这里是bootldr)写入PDA的Flash中,再次开机时boot loader程序会自动运行。需要注意的是,该程序需要首先通过串口从主机拷贝linux内核的Image文件并写入Flash,之后才将Image转移到RAM中,完成其boot loader的任务。

从第二个例子看出,对于拥有板上OS的系统,其boot loader程序的功能也有了很多扩展,除了负责把可执行的代码拷贝到RAM中之外(boot loader的基本功能),它还可以从通信端口接收二进制数据并写入Flash,这其实实现了程序的在线烧写。除了上面的bootldr,针对arm- linux的boot loader程序还有blob和Uboot,其中blob也是来源于lart。

交叉编译工具链

首先需要理解“交叉”的概念。由于构成嵌入式系统的处理器及外围设备能力有限,包括编译器、编辑器等应用程序的开发环境不可能在嵌入式系统中运行,便产生了目标机(target)和宿主机(host)的概念。宿主机中运行集成开发环境,如编辑器、编译器等,目标机中运行宿主机生成的代码,这样的开发方式形成了一个“交叉”的环境。

交叉编译工具链产生运行于目标机上的代码,包括编译器、链接器、库工具、其他二进制工具以及一系列标准的和非标准的二进制库。通常,交叉编译工具链是由厂商提供的,如仿真器的提供商一般会提供含有交叉编译工具链的开发环境,而开发板的提供商也会把交叉编译器、链接器等工具和相应的二进制库放到产品附带的光盘里(购买Assabet的朋友们是不必为交叉编译工具链的问题担心的)。某些情况下我们也可以自己构建交叉工具链,比如linux环境下的嵌入式开发,虽然整个过程比较繁琐,但总是可以实现的。不过,个人的观点是,当我们拥有现成的、正规途径获得工具链时,我们大可不必去做那项工作,除非对它有特别的兴趣。linux下构造arm交叉工具链的过程可以参考200405251_r.html。

嵌入式开发需要的知识

  • 如果从头做起——我指的是设计、制作自己的电路板,而非仅仅在开发板上运行“hello world”,数字逻辑方面的知识是必不可少的,诸如组合电路的知识、读写时序等,这些是让处理器能够正常访问存储器和某些外设的关键;
  • 其次是处理器方面的知识,如系统总线、寻址、输入输出、DMA、定时器、中断等,从200402052.html能够得到一个的关于处理器的简单介绍;
  • 不要求能够编写汇编代码,但读懂它是非常重要的;
  • 要熟悉一种嵌入式的操作系统——如果企图设计的不是一个红绿灯的控制装置或电子表,常见的操作系统如Linux、WinCE、 Ecos、Psos、Vxworks、TinyOS等,他们中有些是开源的,有些是商业化的,有些是实时的,有些不是实时的,具体的选择依赖于具体的项目。(但笔者个人不喜欢WinCE。)
tech/embedded/embedded_guide.txt · Last modified: 2014/11/10 08:22 (external edit)