尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

ARM Cortex A8核心板(SoM)开发实战:从选型到调试全解析

ARM Cortex A8核心板(SoM)开发实战:从选型到调试全解析 最近盘点了手上几块闲置的开发板发现最有价值、也最值得拿出来聊一聊的反而是那块ARM Cortex A8的System on ModuleSoM核心板。这两年做工业控制相关的项目最后硬件方案定下来的居然是这颗看起来“有点年头的芯片”搭配核心板形态说实话自己一开始也没想到。SoM这类模块把CPU、DDR、eMMC、电源管理这些难啃的硬骨头预先集成好用户拿到的是一块经过验证的核心小板只需要按产品需求设计自己的底板外设就行。对中小团队、个人开发者、以及想快速出原型验证方案的人来说这种模式是真的省心。这篇文章就围绕这个平台把选型逻辑、硬件设计要点、交叉编译环境、调试方法和常见坑位完整梳理一遍给同样在评估Cortex A8 SoM方案的朋友做参考。1. 项目背景与方案选型为什么是Cortex A8 SoM很多人一听到Cortex A8第一反应是“这玩意儿是不是太老了”毕竟现在手机上的ARM核心都已经到Cortex-X系列了。但嵌入式工业产品和消费电子完全是两个节奏。Cortex A8在工控、医疗、电力、物联网网关这些领域还有大量存量市场芯片供货稳定BSP完善资料丰富而且价格早就被摊薄了。加上SoM这种产品形态本身就是为了降低开发门槛而存在的两者结合起来对一个要快速出货的项目来说反而是一条非常务实的路径。1.1 先搞清楚SoM到底解决了什么问题SoM全称System on Module国内通常叫核心板或者模块系统。它和整板设计的核心区别在于SoM把“技术难度高、但差异化价值低”的部分集成到一起比如处理器、DDR颗粒、eMMC/NAND Flash、PMU电源管理单元、时钟晶振甚至网络PHY都会放上去。这些部分恰恰是硬件设计中最容易出问题的区域——DDR布线要等长、阻抗匹配要高精度、电源时序要严格、高速信号要控干扰哪一项做不好都是“能用但偶发死机”这种最难排查的故障。我需要提醒的就是SoM最大的价值不是省那几颗料而是省掉了一整个维度的debug时间。底板设计你只需要关心外围接口RS485电平转换、CAN收发器、继电器驱动、ADC前端采集、以太网变压器座、LCD接口这些难度直接从“高速数字电路”降到了“常规外围电路”的层级。实际上用了SoM之后硬件工程师可以把精力放在产品的差异化部分而不是反复去验证DDR信号完整性和电源纹波。1.2 Cortex A8这颗“老芯片”凭什么还能打Cortex A8是ARM第一代超标量Cortex应用处理器主频通常落在600MHz到1GHz这个区间。在SoM生态里最典型的代表就是TI的AM335x系列基于Cortex A8核心集成了SGX530 GPU、Ethernet MAC、CAN控制器、PRU协处理器等一大堆工业场景需要的功能。相比Cortex A9和A7A8的流水线更深同频性能其实并不差关键是对外的接口非常齐全工业级温宽-40到85度的型号也很多这是很多消费级ARM芯片给不了的。和Cortex A7比A8没有明显劣势在单核性能上反而更好。和A9比A8少一个核心但功耗更低、更稳定。对于单进程处理为主的工控应用比如HMI人机界面、协议网关、数据采集终端A8的性能完全够用。加上AM335x系列的PRU协处理器还能做实时IO控制这在Linux系统下做硬实时扩展很自然是很多纯A8/A9芯片不具备的。1.3 选型时最在意的几个指标我在评估SoM方案时会按下面的优先级来看顺序基本就是决定项目成败的权重排序选型指标为什么重要我的判断标准引脚兼容性核心板换型号/升级不用重画底板同一封装下有多个型号可选引脚pin-to-pin兼容BSP成熟度直接决定软件工程师的存活率官方提供完整U-Boot/内核/文件系统长期维护供货周期工业项目生命周期通常5-10年芯片厂商明确承诺工业级10年供货文档与社区资料遇到问题能否自己解决官方有详细的TRM技术参考手册、勘误表、应用笔记价格与起订量成本复核可行性单颗芯片价格和最小起订量都在可接受范围对Cortex A8这个级别的SoM一般核心板价格在200到500元之间底板自己打样整套硬件成本控制起来非常灵活。如果直接画整板光是DDR3布线要处理的信号完整性问题就够团队喝一壶的。这也是越来越多方案商宁可多花几百块买核心板也不愿意自己去啃高速布线的核心原因。2. 硬件架构与关键电路设计要点确定了SoM方案之后还得知道核心板上到底发生了什么。毕竟软件工程师要写驱动、调设备树对硬件结构没有概念的话做起来会非常吃力。这里以典型的AM335x Cortex A8核心板为例把硬件架构拆开来看。2.1 核心板内部都有什么一个标准的Cortex A8 SoM核心区域通常包含以下几大块处理器AM335x系列Cortex A8内核主频最高1GHz工业级型号可到800MHz。DDR3内存常见配置为256MB到1GB采用128Mb/256Mb×16bit颗粒组合数据总线宽度通常是16bit两颗叠die组成32bit。存储4GB到16GB eMMC或者NAND Flash。eMMC方案是目前的主流原因是软件升级和系统稳定性都更好。PMU电源管理单元典型的如TPS65217提供多路DCDC和LDO输出完成上电时序。以太网PHY很多SoM会直接板载一颗MAC PHY芯片比如AR8031/AR8035引出RJ45接口省掉底板的以太网设计。时钟24MHz主晶振32.768kHz RTC晶振以及DDR颗粒需要的参考时钟。SoM的核心设计理念就是“能放上去的高难度器件都放上去”。底板B2B连接器或者邮票孔焊盘引出的通常是带保护的GPIO、串口、CAN、USB、以太网、LCD信号。这些信号电平在底板上做转换不需要再跑高速DDR信号这就是SoM能保持体积小但可靠性高的原因。2.2 DDR等长布线与电源完整性的那些坑如果你自己去画整板DDR3部分的布线规则是最考察硬件功底的。DDR3工作在400MHz到800MHz信号上升沿非常陡要走Fly-by拓扑尽量缓解反射和同步开关噪声。先说等长DDR3地址/控制信号组要求相对于时钟信号等长偏差一般控制在±20mil以内数据信号组DQ/DQS/DM以字节通道为单位每组内部等长偏差控制在±5mil以内而且DQ到DQS需要做相对时序差补偿。这个活儿用Cadence Allegro或者Altium的Interactive Diff Pair Length Tuning工具调起来很磨人手工拉线经常一拉就是一整天。再说电源完整性DDR3的VDD和VTT供电质量直接影响系统稳定性。核心板通常采用同步降压转换器输出1.5V/1.35V DDR电源VTT基准电压必须从源端经过去耦电阻和磁珠隔离后单独供给。布线时要注意DDR电源层必须有完整的参考平面回流路径不能被分割否则会出现“常温下没事一跑高温就死机”这种诡异故障。如果你选用成熟的SoM模块这些问题都已经由模块厂商解决了。设备树里会看到DDR3的时序参数配置这些参数是基于PCB的布线和芯片datasheet标定好的。你自己做底板时只需要给SoM供电根本不用管DDR信号。这也是为什么我前面强调使用SoM不是浪费钱而是把高速电路设计风险转嫁给模块厂商这比省几百块钱重要得多。2.3 电源树与时序设计的思路Cortex A8核心板的电源树比MCU复杂得多通常有这么多路VDD_CORE核心电压0.9V到1.1V左右动态调压给ARM核和内部逻辑供电。VDD_MPUMPU电压1.1V到1.3V左右专门给Cortex A8处分。VDDS_DDRDDR3供电1.5V或1.35V取决于DDR3L还是DDR3。VDDS_SRAMSRAM待机电压1.8V。VDDS_A模拟电源比如ADC、PLL、USB PHY、以太网PHY等通常3.3V。VDDS_RTCRTC电源独立1.8V或3.3V。PMU芯片的主要工作不是简单降压而是管理上电时序。典型上电顺序为先给RTC电源然后是SRAM电源核心电压再是IO电源最后是DDR电源和模拟电源。顺序错了芯片长期工作会出现内部闩锁Latch-up风险直接烧掉芯片都不是没可能。官方勘误表里专门有一条就是关于电源时序要求的我建议做硬件设计的人把TRM里的Power Sequencing章节完整读一遍这比看100篇博客都有用。从底板设计角度你需要关心的是SoM引出的电源域有哪些。一般SoM会把3.3V和5V的IO电源引到B2B连接器上底板外设直接挂这些电源就行。电源纹波控制在50mV内是基础要求如果外设里有模拟电路或者射频模块还需要额外加LC滤波避免开关频率干扰。3. 软件工具链与交叉编译环境搭建硬件平台确定之后软件才是大头。Cortex A8上跑的是Linux或者裸机程序绝大多数场景都是Linux。既然是ARM处理器所有软件都必须依赖交叉编译在x86的PC上生成ARM架构的可执行文件。这个过程对刚入门的嵌入式工程师来说最容易卡住的地方就是工具链的选择和环境变量的配置。3.1 ARM GNU工具链版本选择的第一课做交叉编译第一步就是选对工具链。对于Cortex A8常见的有三个选择arm-none-eabi-gcc用于裸机开发没有Linux用户空间支持编译出来的程序不依赖操作系统直接跑在硬件上。适合做裸机固件、RTOS应用。arm-linux-gnueabihf-gcc用于带Linux系统的用户空间程序编译支持硬浮点针对ARMv7-A架构。Cortex A8带VFPv3浮点单元用gnueabihf版本能发挥浮点性能。Linaro GCC针对ARM的长期支持工具链版本更新快性能优化好是很多板级SDK的基础。一个很典型的坑是用错了工具链版本编译出来的程序要么段错误要么直接提示Illegal instruction。比如你用arm-none-eabi-gcc去编译Linux用户态程序链接阶段就过不了因为缺少libc和动态链接器。用arm-linux-gnueabi软浮点版去跑硬浮点环境老版本的glibc会出现浮点参数传递不一致的问题。所以选工具链之前先确认目标系统的glibc版本和动态链接器路径再决定工具链版本。我习惯的做法是直接用板卡SDK里自带的工具链或者从Linaro官方下载最新的arm-linux-gnueabihf工具链解压到/opt目录然后手动设置环境变量export PATH/opt/gcc-arm-linux-gnueabihf/bin:$PATH export CROSS_COMPILEarm-linux-gnueabihf- export ARCHarm这三行环境变量算是所有ARM交叉编译的基础。ARCH告诉内核构建系统目标架构是armCROSS_COMPILE指定前缀让Makefile自动调用arm-linux-gnueabihf-gcc、arm-linux-gnueabihf-ld这些工具。3.2 U-Boot与内核编译跟着Makefile走一遍拿到Cortex A8 SoM之后要构建系统镜像核心就三步编译U-Boot引导程序、编译Linux内核、构建根文件系统。U-Boot编译相对简单因为它每个板卡都有单独配置文件。以AM335x为例make am335x_evm_defconfig make -j8编译完会生成MLO和u-boot.img两个文件。MLO是TI特有的二级引导加载器放在SD卡的FAT分区或者eMMC的boot分区里负责初始化DDR和外设再将U-Boot主程序加载到内存。U-Boot主程序再引导内核。内核编译稍微麻烦一些因为需要先选设备树和内核配置make omap2plus_defconfig make zImage make am335x-evm.dtb这里有个细节Cortex A8的DTS设备树源文件会定义板卡上的所有硬件外设比如串口地址、GPIO复用、LCD时序、以太网MAC、CAN控制器等。如果你在底板上新增了一个I2C设备或者换了一个LCD屏都需要修改对应的DTS节点重新编译设备树。设备树写错最典型的症状是“某个外设能识别但驱动加载失败”所以每次修改DTS后我都建议先用dtc工具反编译看实际加载的设备树内容确认节点确实生效了。3.3 根文件系统与Busybox的交叉编译内核跑起来之后必须挂载根文件系统否则系统只能停在Kernel panic - not syncing: VFS: Unable to mount root fs。对于精简的嵌入式系统最常用的做法是使用Busybox构建最小根文件系统。Busybox号称Linux系统的瑞士军刀把ls、cp、sh、init等几百个常用命令合并成一个静态链接的可执行文件大小只有几百KB。交叉编译Busybox的命令如下make ARCHarm CROSS_COMPILEarm-linux-gnueabihf- defconfig make ARCHarm CROSS_COMPILEarm-linux-gnueabihf- menuconfig make ARCHarm CROSS_COMPILEarm-linux-gnueabihf- -j8编译完成后在busybox目录下执行make install会生成一个_install目录里面就是基本的目录结构和busybox软链接。再手动创建一些系统目录加上必要的设备节点用cp命令把交叉编译好的glibc库libc.so、ld-linux.so等拷进lib目录基本上就是一个可启动的根文件系统了。但这里有一个天坑Busybox默认编译配置可能不带动态加载支持如果你后续要在系统里跑Qt等重量级应用动态库依赖会很难处理。更让我头疼的是如果工具链的glibc版本和之前编译内核时用的工具链glibc版本不同从文件系统启动时经常出现“version GLIBC_2.27 not found”这类错误。遇到这种情况要么升级/降级工具链要么直接用Buildroot或Yocto一键生成完整系统镜像少走弯路。3.4 Qt应用在嵌入式Linux上的部署如果产品要做HMI人机界面Qt是绕不开的方案。Cortex A8 SGX530 GPU虽然性能有限但跑Qt的EglFS模式做一个简单的触摸界面还是相当流畅的。Qt的交叉编译比普通C程序复杂得多。你需要先编译Qt库本身再编译你的应用程序。典型的配置步骤./configure -prefix /opt/qt-5.15.2-arm \ -xplatform linux-arm-gnueabihf-g \ -eglfs -opengl es2 \ -no-feature-vnc -no-feature-xcb \ -nomake examples -nomake tests \ -release make -j8 make install重点在于xplatform参数它指定了Qt的交叉编译平台描述文件。如果不指定Qt默认会按x86桌面平台编译生成的库根本没法在ARM上跑。即使交叉编译成功部署时也要注意把Qt的插件目录platforms、imageformats等和动态库完整拷贝到根文件系统对应的路径否则跑起来会直接报qt.qpa.plugin: Could not find the Qt platform plugin eglfs这个经典错误。我对Qt交叉编译的建议是能用Buildroot就别裸编译。Buildroot把工具链、内核、根文件系统、Qt库、应用集成到一条流水线上生成镜像后直接烧录底层的依赖问题大部分都被自动处理了。之前裸着编译Qt浪费了我整整两天时间换成Buildroot之后两小时就出镜像了项目周期紧张的时候效率就是王道。4. 虚拟化调试环境QEMU模拟ARM开发板在拿不到实体板卡之前QEMU模拟器是预研和算法验证的好帮手。尤其对于Cortex A8这种级别性能模拟相对成熟跑一个精简Linux系统完全没问题。很多人在找“ARM开发板模拟器”的时候默认就是QEMU因为它是目前最通用的开源方案。4.1 为什么需要模拟器没有模拟器的时代每次写底层代码都要反复烧写SD卡、刷eMMC那不仅是时间成本还有烧写次数多了导致Flash寿命的问题。当你需要反复验证内核配置、测试根文件系统依赖、调应用程序启动流程时QEMU的启动时间通常只有10几秒比硬件板卡还要快而且可以直接挂接GDB调试内核和应用程序调试体验比实体板还顺。另一个典型场景是跨平台CI。如果你的团队没有足够的实体板卡分配给每个开发人员可以在CI服务器上启动QEMU虚拟机跑自动化测试用例。我就是用QEMU来跑TCP协议网关的压力测试没有给每台开发机配板子服务器上同步用QEMU模拟ARM环境效果很稳定。4.2 QEMU在Cortex A8平台上的实测用法Cortex A8的模拟QEMU支持比较齐全的是TI的AM335x系列对应的机器型号是ti_sitara或者beaglebone等。基本启动命令如下qemu-system-arm -machine beaglebone \ -m 512M \ -kernel zImage \ -dtb am335x-bone.dtb \ -drive filerootfs.ext4,formatraw \ -append consolettyO0,115200 root/dev/mmcblk0 rw \ -serial stdio \ -net nic -net user注意Cortex A8的调试串口在AM335x上叫ttyO0不是ttyS0这个细节直接关系到你能否在串口终端看到内核日志。我第一次用QEMU跑AM335x时append参数里写错了串口名控制台一片空白排查了半天才发现是控制台参数的问题。用QEMU启动之后就能在串口终端里看到完整的Linux启动日志进入shell。我在QEMU里完成过U-Boot启动阶段的测试。方法是先用QEMU加载MLO和u-boot.imgqemu-system-arm -machine beaglebone -m 256M \ -sd sd_image.img \ -serial stdio把U-Boot写到SD卡镜像里QEMU就能从SD卡启动完整模拟ROM → MLO → U-Boot → kernel的启动链路。调试U-Boot阶段这个方式比反复插拔SD卡高效得多。芯片的启动模式拨码开关与SD卡分区结构的配合也能在QEMU里反复验证做板卡生产时就能避免“烧录成功但无法启动”的问题。4.3 模拟器与现实板卡之间容易踩的坑用模拟器调试有个大坑就是感觉“在模拟器上能运行在真板上起不来”的现象。我踩过一次在QEMU里跑得好好的一个内核配置烧到真板之后发现以太网驱动根本不工作。原因很简单QEMU模拟的以太网控制器和真实板卡上的PHY芯片并不是同款驱动模型差别巨大。模拟器只能验证软件逻辑和系统流程没法验证外设驱动的硬件相关性。所以我的习惯是模拟器只用来验证“与硬件无关”的部分比如文件系统完整性、启动脚本、应用程序逻辑一旦涉及外设驱动、时钟配置、DDR时序必须拿到真实板卡上调试。否则就是自己骗自己项目最后一样要花大把时间在真机联调上。5. 常见问题与排查技巧实录在实际开发过程中总会遇到各种千奇百怪的问题这里把几个经典场景的排查过程和解决方案整理出来希望能帮人少走弯路。5.1 Keil中ARM Compiler许可证错误c9555e怎么处理很多做Cortex A8 SoM底板的工程师同一时间还会用Keil MDK做MCU开发。经常遇到的报错是ARM Compiler许可证错误c9555eKeil打开工程直接编译不了。这个错误出现在Keil使用ARM Compiler 5.06时最常见因为编译器授权验证文件过期或者被误删导致IDE认为许可证无效。处理办法分三步先检查许可证状态打开Keil uVision点击File → License Management看能否看到有效的ARM Compiler许可证记录。如果显示invalid或者没有就需要重新激活。其次卸载重装对应版本的ARM Compiler官方下载地址能找到ARM Compiler 5.06 update 7build 960安装后通常能修复c9555e错误。最后如果重装编译器还是不行检查杀毒软件是否把FlexNet的许可证文件当病毒清理了在信任区加白名单一下。这个错误和ARM Cortex A8的Linux交叉编译没什么关系ARM Compiler 5.06是MDK里用来编译MCU程序的很多做ARM开发的人容易把这两个“ARM编译器”混为一谈。实际上一套是ARM自家商业编译器另一套是GNU开源工具链两者针对的目标平台和生态完全不同。5.2 交叉编译工具链的一些“隐形”陷阱交叉编译的坑很多时候不是语法问题而是环境问题。第一个坑是“使用”-static“静态链接但库不完整”。在Cortex A8上跑一个数据采集程序用arm-linux-gnueabihf-gcc编译时加了-static参数编译成功但运行时报Segmentation fault。查下来是因为静态链接了glibc的NSS模块而这个模块在目标板上的/etc/nsswitch.conf和库缓存不匹配。解决办法很简单去掉-static用动态链接方式并把对应的.so库拷贝到目标板。第二个坑是“硬浮点和软浮点的ABI不兼容”。Cortex A8支持硬浮点VFPv3但如果你用了gnueabi软浮点工具链编译的库去链接gnueabihf硬浮点编译的程序链接器会报“selected processor does not support pld”或者直接报错无法解析符号。排查思路是检查工具链前缀和系统内库的编译方式是否一致。第三个坑是“文件系统属性错乱”。每次用root用户交叉编译的文件拷贝到目标板后权限位可能丢掉。别人遇到过启动时提示“-sh: ./app: Permission denied”ls -l看文件权限明明是755。最后用stat命令看了inode属性才发现是ext4的security.capability属性被错误设置用setcap -r命令清理后解决。5.3 ARM平台上的应用软件兼容性问题Cortex A8跑的是ARM架构Linux很多习惯在x86上用的闭源软件在ARM上根本没有对应版本。最常见的就是Navicat在ARM服务器上装navicat基本是装不了的很多地方安装失败就是因为只有x86的deb包强行安装之后会提示Exec format error。遇到这种情况我的原则是“先找替代方案再考虑源码编译”。数据库管理工具在ARM上可以用DBeaver或者命令行客户端代替容器部署的话先确认docker是否有ARM版本镜像。这里要专门说一个点docker desktop本身在ARM Mac上没问题但如果你在中国市场常见的统信UOS等ARM系统上装docker直接用软件源里的版本往往依赖关系残缺我见过有人安装依赖文件后无法运行的大概率是libc6版本和docker二进制不兼容。处理方法是优先用发行版自带仓库的docker.io包或者自己下载对应的arm64版本静态二进制包手动部署。另一个让我印象很深的场景是存储性能测试工具vdbench。很多搞存储的同事习惯在x86服务器上跑vdbench换到ARM服务器上就发现原生的vdbench只有x86版本。其实vdbench是基于Java的只要ARM上有对应架构的JRE就能跑不需要特意找ARM版安装ARM版的JDK8之后直接执行vdbench脚本就行。5.4 常见问题速查表问题现象可能原因排查步骤启动后串口无输出U-Boot烧录位置错误或DDR初始化失败检查MLO分区位置确认启动拨码开关检查DDR电源内核启动到一半停止设备树和硬件不匹配用dtc反编译DTB核对硬件引脚复用交叉编译程序提示Illegal instruction工具链浮点ABI不匹配确认工具链hf/eabi重新编译以太网丢包严重PHY供电纹波过大示波器测PHY供电纹波增加滤波电容Qt程序无法启动eglfs缺少GPU驱动或插件目录不完整检查libQt5EglFs.so是否存在确认SGX驱动加载系统时间每次重启都重置RTC时钟未配置或电池没电确认RTC设备树节点检查RTC电池电压文件系统只读挂载eMMC文件系统坏块过多用fsck检查文件系统考虑换eMMC6. 这个平台后续还能怎么扩展Cortex A8的SoM做完了第一版之后接下来的扩展方向其实很明确。如果你想在同一个底板上做性能升级业内主流做法是找引脚兼容的更高端核心板比如从AM335x升级到AM437x或者AM57x这两款虽然核心不同但很多底板设计是可以平移的。做产品规划的时候从一开始就预留好引脚兼容的扩展位能省掉一次完整的改版成本。如果你的应用开始涉及到图像处理或者轻量级AI推理Cortex A8内置的SGX530 GPU确实有些吃力。此时可以考虑外挂一颗USB接口的NPU加速棒或者换用带NPU的SoM模块比如瑞芯微RK3588S、算能BM1684这类虽然核心不是Cortex A8了但软件框架和交叉编译的思路完全一样。对嵌入式Linux工程师来说工具链的使用、设备树的修改、Uboot的编译流程这些底层技能是通用的换平台只是换个配置而已。从量产角度来看用SoM方案还有一个好处是核心板单独做老化测试底板只负责外围接口生产故障率会低很多。我见过整板方案出货后出现DDR虚焊导致的现象在SoM方案里基本不会出现。这也是为什么很多工业级产品宁愿成本高一点也要用核心板模块厂商在SMT工艺和测试流程上的积累不是一般组装厂能替代的。另外如果你手头正好有闲置的Cortex A8板子建议别急着吃灰拿它来练手Linux驱动开发、学一学设备树语法、跑一跑Buildroot构建系统都是性价比非常高的学习路径。这块“老平台”的文档和资料在网络上非常丰富遇到的问题几乎都有人踩过学习曲线比最新旗舰芯片平滑得多。我在实际使用中发现最终把一个项目做成功的往往不是平台有多新而是你手里这套工具链有多称手、对平台的每个细节有多少把握。
返回列表