1. 项目概述:深入解析AM1806 ARM微处理器
在嵌入式系统开发领域,选对一颗处理器往往意味着项目成功了一半。这颗芯片不仅要能满足当前的功能需求,还得在功耗、成本、外设资源和长期供货稳定性之间找到最佳平衡点。我接触过不少ARM9时代的经典芯片,而德州仪器(TI)的AM1806绝对是其中让人印象深刻的一款。它基于成熟的ARM926EJ-S内核,但真正让它脱颖而出的,是TI在那颗“大脑”周围精心构建的一整套“感官系统”和“神经网络”——从高速USB OTG到灵活的视频接口,再到独特的可编程实时单元。这不仅仅是一颗CPU,更像是一个为特定应用场景量身定制的片上系统(SoC)。无论是十年前的数据集中器、工业网关,还是如今一些对成本和功耗敏感的新型物联网设备,AM1806的设计思路依然有很高的参考价值。今天,我就结合自己的实际使用经验,把这颗芯片里里外外拆解一遍,重点聊聊它的核心特性、那些丰富到让人眼花缭乱的接口,以及在具体项目中如何让它们协同工作。
2. 核心架构与设计思路拆解
2.1 ARM926EJ-S内核:经典与效率的平衡
AM1806的核心是一颗ARM926EJ-S RISC处理器。可能现在听起来这已经是“上古”架构了,但在当时乃至现在很多实时性要求高、成本控制严的应用里,它依然是一员悍将。这颗内核属于ARMv5TEJ架构,支持32位的ARM指令集和16位的Thumb指令集。这里有个关键点:Thumb指令集。在开发中,尤其是存储空间紧张的场合,用Thumb指令编译代码,体积能比纯ARM指令减少30%左右,虽然牺牲了一点性能,但换来了宝贵的Flash空间,性价比很高。内核主频有两个版本:375MHz(核心电压1.2V)和456MHz(核心电压1.3V)。选择哪个版本,不仅仅是性能差异,更直接关系到电源设计和散热考虑。我个人的经验是,对于大多数控制类和轻量级数据处理应用,375MHz版本完全够用,而且功耗和发热更友好。
内核内部集成了内存管理单元(MMU),这是能运行像Linux这类复杂操作系统的硬件基础。MMU负责虚拟地址到物理地址的转换,提供了内存保护机制,防止应用程序错误地访问内核或其他进程的空间,极大地提高了系统的稳定性和安全性。此外,它还有16KB的指令缓存(I-Cache)和16KB的数据缓存(D-Cache),都是4路组相联的。缓存策略上,数据缓存支持写通(Write-Through)和写回(Write-Back)两种模式,可以通过MMU的页表项来按内存区域配置。对于频繁修改的数据,设置为写回模式能显著减少对外部内存的访问,提升效率。
注意:ARM926EJ-S的MMU只支持一种页表遍历方式,且TLB(转译后备缓冲器)是统一的。在编写底层启动代码或进行内存映射配置时,需要仔细参考ARM架构手册和芯片的数据手册,确保页表设置正确,否则会导致内存访问异常或性能低下。
2.2 低功耗设计哲学:不止是制程与频率
“低功耗应用处理器”这个名号,AM1806并非浪得虚名。它的低功耗设计体现在多个层面,不仅仅是依靠更先进的半导体工艺。首先,芯片内部集成了电源与睡眠控制器(PSC)。这个模块非常关键,它允许软件动态地关闭或时钟门控(Clock Gating)各个外设模块甚至整个子系统的时钟。比如,当系统处于待机状态,只需要RTC(实时时钟)工作时,你可以通过PSC关掉ARM核心、大部分外设甚至DDR控制器的时钟,让芯片进入极低功耗的睡眠模式。在实际项目中,我们就是利用这个特性,让设备在无操作时功耗降到毫瓦级别。
其次,可编程实时单元子系统(PRUSS)可以独立开关。PRUSS是两个独立的小型RISC核心,用于处理超高实时性的任务(比如电机PWM控制、高速串行协议解析)。当你的应用不需要它时,可以通过软件彻底关闭其电源域,实现零功耗。最后,芯片的I/O电压支持1.8V和3.3V两种标准。在满足电平兼容的前提下,尽量使用1.8V的I/O电压,可以显著降低芯片整体功耗,尤其是当有大量GPIO频繁切换时,效果更明显。
2.3 外设集成策略:为何如此“拥挤”?
打开AM1806的框图,第一感觉就是外设“堆料”很猛。USB 2.0 OTG、LCD控制器、视频端口、两个McASP、两个McBSP、三个UART、两个SPI、两个I2C、eHRPWM、eCAP……几乎涵盖了当时嵌入式设备所需的所有主流接口。TI这么做的逻辑很清晰:面向确定性的应用市场进行高度集成。例如,打印机、销售终端(ePOS)、工业HMI(人机界面)这些设备,都需要显示(LCD)、用户输入(USB、UART)、打印控制(GPIO、PWM)、音频反馈(McASP)等功能。AM1806通过单芯片集成,让客户省去了大量外围扩展芯片,不仅降低了整体BOM成本,更减少了PCB面积和设计复杂度,提高了系统可靠性。
这种高集成度也带来了挑战,那就是引脚复用(Pin Muxing)。芯片的361个Ball(球栅阵列引脚)需要承载所有外设信号,因此几乎每个引脚都有2到4种甚至更多的功能选项。在硬件设计初期,就必须根据产品功能清单,仔细规划每个引脚的功能,并在软件中正确配置相应的复用控制寄存器。一旦画错PCB,可能就是灾难性的。我建议的做法是,先用Excel或专门的引脚规划工具,列出所有必需的外设信号,然后对照数据手册的“Pin Multiplexing”章节,逐一分配,并标记出冲突点,优先保证关键高速信号(如USB、DDR)的布线优化。
3. 关键外设接口深度解析与实操要点
3.1 双外部内存接口:DDR2/mDDR与EMIFA的取舍
AM1806提供了两个独立的外部存储器接口,这是它的一大亮点。一个是DDR2/mDDR控制器,支持16位总线宽度,最高时钟频率可达156MHz(DDR2)或150MHz(mDDR),寻址空间256MB。DDR2接口性能高,适合作为系统的主内存,运行操作系统和应用程序。另一个是EMIFA(异步外部存储器接口),它更像一个“万能”接口,可以连接8位或16位宽的NOR Flash、NAND Flash、异步SRAM,甚至16位的SDRAM。
如何选择?这取决于你的存储架构。一个典型的配置是:用一片16位的DDR2 SDRAM(比如128Mb或256Mb)作为系统主内存(SDRAM),再用一片8位的NOR Flash(比如4Mb或8Mb)通过EMIFA连接,用于存储启动代码(Bootloader)。NOR Flash支持片上执行(XIP),可以让ARM核心直接从Flash中取指运行,简化了启动流程。而NAND Flash(通常通过EMIFA连接)容量大、成本低,适合存储文件系统或大量数据,但需要额外的坏块管理和ECC校验软件。
实操心得:DDR2的PCB布线是硬件设计的关键难点。必须严格遵循数据手册的布线指南,控制数据线、地址控制线和时钟线的等长与时序。对于两层或四层板,建议使用TI提供的参考设计,并利用其仿真工具进行信号完整性预分析。EMIFA的时序配置相对灵活,需要通过寄存器设置建立(Setup)、选通(Strobe)和保持(Hold)时间,以匹配不同速度的存储器芯片。调试时,可以先用最简单的读写测试(如写入再读回一个已知模式,如0xAA55AA55)来验证接口是否正常工作。
3.2 USB 2.0 OTG:集成PHY带来的便利
AM1806集成了一个完整的USB 2.0 OTG控制器,并且内置了物理层收发器(PHY)。这一点非常省心。很多其他处理器需要外接一颗USB PHY芯片,既占面积又增加成本。集成PHY意味着你只需要在PCB上连接USB连接器的D+、D-、VBUS和ID引脚到芯片对应管脚,并做好阻抗匹配(通常要求差分线90欧姆阻抗)和ESD保护即可。
这个USB控制器支持全速(12 Mbps)和高速(480 Mbps)模式,既可以作为设备(Device)被电脑枚举,也可以作为主机(Host)连接U盘、鼠标等外设,还可以支持OTG协议进行点对点通信。在Linux系统下,对应的驱动通常是musb-hdrc,需要在内核配置中正确启用OTG支持以及相应的角色切换逻辑。
常见问题:USB通信不稳定,经常枚举失败。排查步骤:1. 检查硬件,确保VBUS(5V)供电稳定,D+/D-差分线等长且无过孔,靠近芯片端串接的匹配电阻(通常22欧姆)值正确。2. 测量时钟,确保给USB模块的参考时钟(通常由内部PLL产生)频率精准。3. 检查软件配置,确认USB工作模式(主机/设备)、PHY的复位和时钟初始化序列正确。我曾遇到一个问题,USB只能识别为全速设备,无法进入高速模式。最后发现是芯片配置寄存器中强制全速(Forced Full-Speed)的位被误置位了。
3.3 显示与视频接口:LCD控制器与VPIF的协同
AM1806的显示子系统由两个部分构成:LCD控制器(LCDC)和视频端口接口(VPIF)。LCDC是一个典型的RGB数字接口控制器,支持高达24位色深(实际数据位宽可通过引脚复用选择),能驱动常见的TFT LCD屏。它内置了DMA引擎,可以直接从帧缓冲区(通常位于DDR2内存中)读取像素数据并发送给屏幕,无需CPU干预。
VPIF则是一个更灵活的视频输入/输出接口。它包含两个独立的通道,每个通道可以配置为8位BT.656(标清视频)输入或输出,或者组合成一个16位通道。VPIF特别适合连接视频解码芯片(如TVP5150)或编码芯片,用于实现视频采集或播放功能。例如,你可以用VPIF接一个摄像头模块采集图像,存入内存,然后通过LCD控制器显示出来,或者通过USB传走。
配置要点:LCDC的时序参数(如行同步、场同步、前沿、后沿等)需要根据具体LCD屏的数据手册来精确计算和设置。VPIF的配置则与视频标准密切相关,比如BT.656是嵌入同步信号的,而Raw Data模式则需要额外的行场同步信号。在Linux驱动中,通常需要为LCDC编写FrameBuffer驱动,为VPIF编写V4L2(Video for Linux 2)驱动。
3.4 可编程实时单元子系统(PRUSS):硬实时任务的守护者
PRUSS是AM1806里一个非常有趣且强大的部分。它包含两个独立的可编程实时单元(PRU)核心,每个核心是一个32位的RISC处理器,运行频率可达芯片主频的一半(例如,ARM跑375MHz时,PRU可跑约187.5MHz)。与ARM核心运行Linux这类复杂、非确定性的操作系统不同,PRU核心运行的是简单的、单任务的固件程序,直接从其私有的4KB指令RAM和512B数据RAM中运行,指令执行时间是严格确定的。
这意味着什么?意味着你可以把对实时性要求极高的任务剥离出来,交给PRU去做。例如:
- 高速脉冲生成与测量:用eHRPWM模块生成精密的电机控制PWM波,用eCAP模块捕获编码器信号。PRU可以处理这些外设的中断,并进行复杂的脉冲计数、位置环计算,响应延迟可以控制在几十纳秒级别,这是运行Linux的ARM核心无法保证的。
- 自定义串行协议:实现一个Linux内核不直接支持的工业总线协议,如特殊的串行通信协议。PRU可以直接操作GPIO或McBSP的底层数据流,实现位级别的精确控制。
- 辅助数据搬运:配合EDMA(增强型直接内存访问控制器),实现复杂的数据搬移和预处理,减轻ARM核心的负担。
PRU的程序开发需要用TI提供的汇编器或C编译器(较新版本工具链支持),编写代码后编译成二进制文件,由ARM核心通过配置PRU的Control寄存器加载到其指令RAM中,然后启动它。两者之间通过共享的内存区域(一部分片上RAM被映射到两者的地址空间)和中断机制进行通信。
避坑指南:PRU的编程模型和ARM完全不同,更像传统的单片机开发。要特别注意其内存映射,区分本地数据RAM、共享RAM、以及访问ARM系统总线上资源(如外设寄存器)的方式。PRU访问系统外设需要通过一个特殊的“Constant Table”进行映射,初学时容易混淆。建议从TI的PRU软件包中的示例程序开始,理解其基本框架。
4. 系统启动与底层软件实操流程
4.1 启动模式配置:硬件的第一道指令
AM1806不支持直接从NAND或NOR Flash上电执行代码。芯片上电复位后,ARM核心会从一个固定的内部ROM(64KB)开始执行。这段ROM代码是TI固化在芯片里的引导加载程序(RBL, ROM Bootloader)。RBL的工作是读取芯片的启动配置引脚(BOOT[7:0])的状态,根据配置从指定的外部设备(如SPI Flash、MMC/SD卡、USB、UART等)加载用户的一级引导程序(如U-Boot)到内部RAM或DDR中,然后跳转执行。
启动配置引脚(BOOT Pin)通常在复位信号的上升沿被采样。这些引脚大多与GPIO或其他功能复用,因此需要在硬件设计时,通过上拉或下拉电阻将其固定在所需电平。例如,将BOOT[3:0]配置为0101,可能代表从MMC/SD0通道启动。具体编码必须严格查阅数据手册中“Boot Modes”章节的表格。这是硬件和软件衔接的第一步,配置错了,芯片就无法启动。
4.2 时钟与电源管理初始化
成功加载一级引导程序后,首先要初始化的就是锁相环(PLL)和时钟发生器。AM1806内部有多个PLL(如PLL0给ARM子系统,PLL1给外设),用于将外部输入的晶振时钟(例如24MHz)倍频到各个模块所需的高频。初始化顺序通常是:使能PLL的旁路模式(Bypass)-> 配置倍频系数(M/N/P)-> 等待PLL锁定 -> 切换时钟源到PLL输出。必须注意,在提高ARM核心时钟频率前,有时需要先提高其核心电压(CVDD),这涉及到电源管理芯片(PMIC)的时序控制,需要参考芯片的推荐操作条件(Recommended Operating Conditions)。
接下来是电源与睡眠控制器(PSC)的初始化。PSC管理着几十个电源域和时钟域。上电后,除了少数必要模块(如RTC),大部分模块都处于关闭或复位状态。你需要遍历所有你计划使用的外设模块(如UART0、SPI1、USB0等),向对应的PSC寄存器写入“使能”命令,并等待其状态变为“使能成功”,才能去配置该外设的寄存器。这一步很容易遗漏,导致后续外设寄存器读写无效。
4.3 内存控制器与内存映射配置
在运行复杂的操作系统之前,必须正确初始化外部内存控制器。对于DDR2/mDDR控制器,这通常是一个比较繁琐的过程,称为DDR初始化序列。这个序列包括:
- 使能控制器时钟(通过PSC)。
- 配置PHY(物理层)参数,如阻抗校准(ZQ calibration)。
- 配置内存时序参数:行地址选通脉冲周期(tRAS)、行预充电时间(tRP)、行到列延迟(tRCD)、CAS延迟(CL)等。这些参数必须与你使用的具体DDR2芯片型号完全匹配,在其数据手册中可以找到。
- 执行内存初始化命令序列:预充电所有存储区(Precharge All)-> 多次自动刷新(Auto Refresh)-> 设置模式寄存器(Load Mode Register)。
- 最后使能内存控制器进入正常工作状态。
这个过程通常由Bootloader(如U-Boot)中的板级初始化代码完成。如果配置错误,系统可能在访问DDR时立即崩溃。调试时,可以先用最简单的读写测试函数,在内存的起始和结束地址写入不同的数据模式并读回验证。
内存映射(Memory Map)是软件视角的“地址地图”。AM1806的地址空间是统一的,ARM核心通过这个映射访问所有资源。你需要清楚几个关键区域:
0x8000 0000 - 0x8001 FFFF:128KB的片上RAM,速度最快,适合放中断向量表或关键代码。0xC000 0000 - 0xCFFF FFFF:DDR2内存区域,256MB空间,是操作系统和应用程序的主要舞台。0x01C1 0000等:外设寄存器区域,每个外设都占据4KB或更小的地址窗口,通过读写这些寄存器来控制外设。
4.4 外设驱动开发与集成示例:以UART和GPIO为例
在裸机或RTOS环境下,驱动开发就是直接操作外设寄存器。以最简单的UART0打印“Hello World”为例,步骤清晰:
- 引脚复用配置:查表找到UART0的TXD和RXD引脚(例如,可能是
SPI0_SCS[4]和SPI0_SCS[5]复用模式)。找到对应的引脚控制寄存器(PINMUX寄存器组),将其功能模式设置为UART。 - 使能模块时钟:通过PSC模块使能UART0的时钟。
- 配置UART寄存器:
- 设置波特率除数(DLL和DLH寄存器)。例如,输入时钟频率为48MHz,想要115200波特率,除数 = 48e6 / (16 * 115200) ≈ 26.04,取整为26。则DLL=26,DLH=0。
- 设置线路控制寄存器(LCR):数据位8位,无奇偶校验,1位停止位。
- 使能FIFO(如果使用)。
- 发送字符:查询线路状态寄存器(LSR)的“发送保持寄存器空”位(THRE),为1时向发送保持寄存器(THR)写入字符数据。
对于GPIO操作,同样先配置引脚复用为GPIO模式,然后方向寄存器(DIR)设置为输入或输出,通过数据寄存器(SET_DATA, CLEAR_DATA)或直接写DATA寄存器来控制输出电平,通过读DATA寄存器获取输入电平。GPIO中断的配置稍复杂,需要设置触发边沿、使能中断,并正确配置ARM核心的中断控制器(INTC)。
在Linux环境下,这些底层操作都由内核驱动完成。开发者更多的工作是在设备树(Device Tree)中描述硬件资源。例如,为一个UART设备在设备树中需要定义:
- 兼容性(compatible):
"ti,am1806-uart"或类似字符串,用于匹配内核驱动。 - 寄存器地址和大小(reg)。
- 时钟信息(clocks)。
- 中断号(interrupts)。
- 引脚复用配置(通过pinctrl子系统)。
内核启动时会解析设备树,自动加载并初始化对应的驱动。这种“描述硬件”的方式,使得同一份内核镜像可以适配不同的硬件板卡,大大提高了软件的可移植性。
5. 常见问题排查与调试技巧实录
5.1 系统无法启动:从电源到Bootloader的逐级排查
这是最令人头疼的问题。可以按照以下流程,像侦探一样逐级缩小范围:
- 电源与复位:首先用万用表和示波器确认所有电源轨(CVDD, DVDD18, DDR_VREF等)的电压是否在容差范围内,且上电时序是否符合数据手册要求。检查复位信号(RESET)是否在电源稳定后产生了足够长时间的低电平,然后稳定拉高。
- 时钟:测量外部晶振(OSCIN)引脚是否有24MHz(或你使用的频率)的正弦波或方波?振幅是否足够?测量芯片的CLKOUT引脚(如果配置输出)是否有时钟输出?这能反映内部PLL是否工作。
- 启动模式:用万用表测量BOOT配置引脚的电平,确认与硬件设计意图一致。这是最常见的错误来源之一。
- Bootloader加载:如果使用UART启动,可以在UART TX引脚上连接一个USB转串口工具,用PC串口助手(如Putty、SecureCRT)以最低波特率(如9600)监听,看RBL是否会打印出任何调试信息(如
CCCC)。如果使用SD卡启动,确认SD卡格式化为FAT32,并且一级引导程序(如MLO, U-Boot的SPL格式)位于第一个分区且文件名正确。 - DDR初始化:如果Bootloader能运行但卡在DDR初始化,可能是时序参数错误。可以尝试使用更保守(更慢)的时序参数,或者检查PCB布线质量。有时需要借助仿真器(如JTAG)单步跟踪Bootloader的初始化代码,查看在哪一步出错。
5.2 外设访问异常:寄存器读写失败
当代码访问某个外设寄存器时,如果读回的值总是0xFF或0x00,或者写入后读回不一致:
- 检查PSC:99%的问题出在这里。确认你已经通过PSC使能了该外设模块的时钟和电源域。读取PSC对应模块的状态寄存器,确认其状态为“Enable”或“SyncReset”,而不是“Disable”或“SwRstDisable”。
- 检查引脚复用:确认该外设功能对应的引脚,其复用控制寄存器(PINMUX)已正确设置为该外设模式,而不是GPIO或其他功能。
- 检查内存保护单元(MPU):AM1806有MPU可以限制对某些内存区域的访问。确认当前运行的代码(如ARM核心)有权限访问目标外设的地址空间。在初始化阶段,可以暂时配置MPU为允许所有访问,以排除此问题。
- 检查地址映射:确认你访问的寄存器地址绝对正确。数据手册中的地址通常是字节地址,而你的代码可能是以32位(字)为单位访问,要注意偏移量计算。
5.3 通信接口不稳定:以SPI和I2C为例
SPI通信数据错位或丢失:
- 时钟极性(CPOL)和相位(CPHA):这是SPI最经典的配置问题。主设备和从设备必须严格匹配(模式0,1,2,3)。用示波器同时抓取SCLK、MOSI和CS信号,检查数据在时钟的哪个边沿采样,与配置是否一致。
- 时钟频率:初始调试时,请将SPI时钟频率降到最低(如100kHz),确保通信稳定后再逐步提高。
- FIFO与中断/DMA:如果使用FIFO和中断或DMA,要确保FIFO的触发阈值设置合理,并且及时处理中断或正确配置DMA传输链。否则可能导致FIFO溢出或下溢。
I2C总线锁死或无应答:
- 上拉电阻:I2C是开漏输出,必须在SDA和SCL线上接上拉电阻(通常4.7kΩ到10kΩ)。电阻值过大会导致上升沿太慢,在高速模式下容易出错;过小则增加功耗。
- 总线电容:总线过长或连接的设备过多,会导致总线的等效电容过大,同样会减慢上升沿。可以尝试减小上拉电阻值,或降低通信速率。
- 软件复位:如果总线锁死(SCL被某设备持续拉低),标准的恢复方法是:软件控制GPIO模拟几个SCL时钟脉冲(通常9个),直到SDA被释放。AM1806的I2C控制器可能没有硬件自动恢复功能,需要你在驱动中实现这个恢复序列。
5.4 实时任务响应不及时:PRU与中断的优化
当把实时任务放在ARM上运行Linux时,可能会因为内核调度、中断屏蔽等原因导致响应延迟达到毫秒级,无法满足要求。
- 方案一:使用内核线程并提高优先级。将实时任务放在一个内核线程中,并使用
sched_setscheduler将其设置为SCHED_FIFO实时策略,并赋予最高优先级。这能获得较好的响应性,但仍受内核本身活动的影响。 - 方案二:使用用户空间实时扩展(如PREEMPT_RT)。给Linux内核打上PREEMPT_RT补丁,可以极大减少内核的不可抢占区域,将中断处理线程化,能获得微秒级的响应延迟。但配置和调试相对复杂。
- 方案三:使用PRU。这是最根本的解决方案。将实时性要求最高的任务(如精确的PWM生成、高速脉冲计数)卸载到PRU上执行。ARM Linux核心通过共享内存与PRU交换数据和命令。PRU的响应是确定性的,延迟在指令周期级别。你需要编写PRU的固件,并通过
prussdrv或rpmsg等用户空间库与ARM侧通信。
PRU调试技巧:PRU没有像ARM那样方便的JTAG调试接口。常用的调试方法是“printf调试法”,即让PRU通过写共享内存的某个位置来输出状态信息,ARM侧轮询或中断读取并打印出来。TI的PRU软件包也提供了一些基于日志的调试工具。
5.5 功耗高于预期:静态与动态功耗分析
如果实测功耗比数据手册给出的典型值高很多,需要分两部分排查:
静态功耗(待机功耗):
- 检查未使用的引脚:按照数据手册“Unused Pin Configurations”章节的建议,将所有未使用的I/O引脚配置为输出低电平或输入模式并内部上拉/下拉,避免浮空引脚产生漏电流。
- 检查外设模块电源:确认通过PSC关闭了所有未使用的外设模块的时钟和电源域。特别是PRUSS、USB PHY、视频接口等,都是耗电大户。
- 检查外部电路:测量芯片各个电源引脚对地的电阻,排除外部元件(如去耦电容)短路或漏电的可能。
动态功耗(运行功耗):
- 降低主频:如果性能允许,尝试降低ARM核心和总线时钟频率。功耗与频率大致呈线性关系。
- 优化软件:减少不必要的内存访问和计算密集型循环。让CPU在空闲时进入WFI(等待中断)状态。
- 优化外设使用:例如,LCD控制器如果持续刷新,功耗会很高。可以在显示内容不变时,降低其刷新率或进入自刷新模式。对于GPIO,驱动LED时使用PWM调光而不是简单的开关,也能降低平均电流。
6. 进阶应用与系统设计考量
6.1 构建一个基础的Linux系统
以运行Linux为例,一个完整的软件栈包括:
- 一级引导程序(SPL):通常由U-Boot的SPL部分担任,负责初始化最基础的时钟、DDR和存储控制器,然后从存储设备加载完整U-Boot。
- 二级引导程序(U-Boot):功能强大的Bootloader,负责初始化更多硬件,提供命令行环境,并从网络、USB或存储设备加载Linux内核和设备树(DTB)到内存,最后跳转到内核入口。
- Linux内核:需要为AM1806配置和编译内核。关键配置包括:CPU类型(ARM926EJ-S)、平台(TI DaVinci)、以及所需的外设驱动(如串口、MMC/SD、USB、网络等)。设备树文件(.dts)是硬件描述的核心,必须准确描述内存布局、时钟、引脚复用以及所有启用外设的信息。
- 根文件系统:包含系统运行所需的库、工具和应用程序。可以使用BusyBox构建简单的ramdisk,也可以使用Buildroot或Yocto构建更复杂的文件系统,并挂载在SD卡或NAND Flash上。
构建流程简述:
- 获取TI的SDK或社区维护的U-Boot/内核源码(如旧版的
linux-davinci内核)。 - 配置U-Boot:
make am1806evm_defconfig然后make menuconfig进行微调,编译生成MLO(SPL)和u-boot.img。 - 配置Linux内核:选择相近的默认配置,重点检查设备树支持、串口驱动、MMC驱动、USB驱动等。编译生成
zImage和am1806-evm.dtb。 - 制作SD卡:将SD卡分区,第一个分区为FAT32,存放
MLO,u-boot.img,zImage,am1806-evm.dtb;第二个分区为ext4,存放根文件系统。 - 上电启动,在U-Boot命令行设置启动参数(bootargs),指定根文件系统位置,然后启动内核。
6.2 多外设协同工作案例:简易工业HMI
假设我们要用AM1806设计一个简单的工业人机界面(HMI),功能包括:显示图形界面(LCD)、触摸屏输入(通过SPI接口的触摸控制器)、记录数据到U盘(USB Host)、通过串口与下位机PLC通信(UART)、以及通过以太网(需外接MAC+PHY芯片,通过EMIFA或MII接口连接)上传数据。
资源分配与冲突解决:
- 显示:使用LCD控制器驱动RGB接口的TFT屏。帧缓冲区放在DDR2中。这会占用大量内存带宽。
- 存储:使用USB Host接口连接U盘,使用内核的USB Mass Storage驱动。文件系统可以挂载为Vfat或Ext。
- 通信:UART0用于调试信息输出,UART1用于与PLC通信。需要配置正确的波特率、校验位。
- 网络:外接的以太网芯片通过EMIFA的异步总线或MII接口连接。需要在设备树中描述这个“慢速”外设的寄存器地址、中断号等。Linux内核需要有对应的驱动(如
davinci_emac的移植版本或通用MAC驱动)。 - 潜在冲突:LCD控制器的数据线可能与某些GPIO或UPP引脚复用。在引脚规划时,必须确保LCD所需的16或24位数据线、时钟、同步信号等一组引脚都能完整地分配到同一功能上,没有与其他必需功能冲突。如果EMIFA被用于连接以太网芯片,那么它就不能再用于连接NOR Flash启动。可能需要改用SPI Flash或SD卡启动。
性能考量:ARM926EJ-S @ 375MHz运行Linux和图形界面(如Qt/Embedded)会有些吃力。需要优化:
- 使用轻量级图形库(如DirectFB)或简化Qt的组件。
- 启用DMA传输:LCD控制器使用DMA从内存读取数据,USB和网络数据搬移也尽量使用EDMA,解放CPU。
- 合理设置CPU频率调节策略(cpufreq),在空闲时降频。
6.3 生命周期与替代方案思考
AM1806是一款发布于2010年左右的产品,基于更早的ARM9架构。对于全新设计,需要认真考虑其生命周期。虽然它依然稳定可靠,且在某些存量市场有应用,但TI可能已将其列为“不推荐用于新设计”(NRND)或生命周期末期。这意味着长期供货和新技术支持可能存在风险。
对于新项目,可以考虑性能更强、能效比更高、软件生态更活跃的替代平台:
- TI Sitara系列:如AM335x(Cortex-A8)、AM437x(Cortex-A9),性能更强,集成度更高(如自带千兆以太网MAC),且软件支持更好(主线Linux内核支持良好)。
- NXP i.MX系列:如i.MX6UL/6ULL(Cortex-A7),同样是低功耗应用处理器的热门选择,外设丰富,社区支持活跃。
- 国产替代:一些国内厂商也提供了基于ARM Cortex-A系列的内核,并兼容类似外设集的处理器,在供货和成本上可能有优势。
然而,如果你正在维护一个基于AM1806的成熟产品,或者对成本极其敏感,且现有性能足够,那么继续使用AM1806并建立一定的芯片库存,仍然是一个务实的选择。它的优势在于极高的集成度和经过市场验证的稳定性,相关的软硬件资料也相对齐全。