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

资讯详情

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

Toradex Colibri嵌入式模块开发全流程:从选型到Yocto镜像构建

Toradex Colibri嵌入式模块开发全流程:从选型到Yocto镜像构建 “colibri”这个词西班牙语里是蜂鸟。蜂鸟的标签就俩小快。你要是留意过嵌入式行业这几年冒出来的各种计算机模块会发现Toradex家Colibri系列也是同一个路子——板子面积不大性能却够你跑完整Linux系统、跑Qt界面、跑各种协议栈而且模块化设计能把硬件开发的周期和风险同时压下来。这篇文章就围绕Colibri系列模块把从选型、开发环境搭建、载板设计到Yocto构建镜像的整个流程捋一遍也把我实际调试中踩过的坑摊开来讲清楚。适合谁看两类人。一类是做产品选型的硬件工程师想搞清楚CoM方案和自己画核心板到底怎么选另一类是刚拿到Colibri模块准备开发应用的软件工程师需要快速跑通环境、定制系统、解决启动和外设问题。内容不追求面面俱到但凡是涉及关键决策和常见死坑的地方都会尽量展开说明白。1. Colibri到底是个什么家底选型和定位先搞清楚1.1 一条产品线覆盖四种典型需求Toradex的Colibri系列是标准的计算机模块Computer on Module核心是把CPU、内存、存储、电源管理这些最难的硬件全部集成在一小块模块上通过金手指连接器引出所有功能引脚。用户只需要设计自己的载板Carrier Board把外设接口画在载板上就能快速组成一套可跑Linux的完整系统。当前Colibri系列主力型号大概可以分为四档选型时可以先对照这个表模块型号主控SoCCPU核心定位与侧重点Colibri iMX6ULLNXP i.MX 6ULL单核 Cortex-A7低功耗、成本敏感、轻量LinuxColibri iMX7NXP i.MX 7Dual双核 Cortex-A7 Cortex-M4异构处理、实时控制、低功耗Colibri iMX8M MiniNXP i.MX 8M Mini四核 Cortex-A53多媒体、HMI人机界面、较高性能Colibri iMX8XNXP i.MX 8X四核 Cortex-A35 Cortex-M4F工业级、高可靠、安全启动这几个型号不是简单的性能高低排列而是各有各的使用场景。iMX6ULL适合做串口服务器、工业网关、数据采集终端这类对算力要求不高但对功耗敏感的设备跑起来经常整板功耗都在几瓦以内iMX7最特别的地方是它有一个独立的Cortex-M4核可以在Linux之外跑一个裸机或RTOS任务专门用于实时控制这是很多工业现场非常看重的功能iMX8M Mini算力明显上了一个台阶跑QT界面、嵌入式HMI、视频解码都游刃有余iMX8X则是为那些要求超高可靠性的场景准备的比如医疗设备、电力监控、轨道交通等它的工业级设计保证了长生命周期供货。有一点很多人容易忽略这几款模块虽然SoC各不相同但硬件外形和连接器定义基本一致。也就是说你可以先设计一套兼容的载板前期用iMX6ULL做功能验证后期如果发现算力不够直接换用性能更高的模块载板布局大概率不用做大改动。我实际做项目时就靠这个特性省过一次完整改版的成本初始产品用iMX6ULL验证逻辑市场反馈需要HMI界面后直接切到iMX8M Mini结构件和载板基本沿用。1.2 为什么很多人干脆选模块而不是自己画核心板这是做嵌入式产品最先要面对的选择。很多团队一开始都想过自己画核心板觉得SoC都买得到了板子为什么还要外购但算清楚账之后大多数人还是选择了CoM方案。自己画核心板最核心的难点在于DDR和电源。现代MPU基本都配DDR3L或DDR4DDR走线要求等长、差分、阻抗匹配两层板根本不可能实现四层板也只是勉强通常要做到六层甚至八层。这意味着PCB成本直接上一个台阶而且DDR布线、终端匹配、软件调优整个流程走下来没有几周时间搞不定。如果赶上批量生产时某颗粒缺货还要面临换料后的重新验证。相比之下Colibri模块把DDR、PMIC、存储全部封装在模块内部载板设计难度直接降为“画外设接口”四层板就能搞定大部分应用。软件生态也是个重要考量。自己画核心板意味着BSP、内核、设备树、文件系统全部要自己维护仅是让U-Boot稳定起来就够折腾一阵子。Colibri模块有现成的Yocto BSP集合、预编译好的测试镜像、完善的硬件文档用户拿到手先烧一个官方镜像系统就能跑起来然后在此基础上改设备树、加应用开发效率完全不在一个量级上。成本这件事要分两面看。模块单价确实比一颗裸SoC加周边物料要贵但如果把研发人力成本、PCB层数增加的成本、调试失败的风险成本、长期维护BSP的隐性成本全部算进去对于中小批量产品来说CoM方案的综合成本往往更低。我见过不止一个项目自己画核心板画到一半发现DDR不稳定、电源上电时序不对一查就要重新打样周期和费用都失控。模块方案最大价值就是用一个可控的成本把这些风险提前买掉。1.3 这些模块都跑在哪里典型应用场景从实际落地来看Colibri模块覆盖的场景非常广我经手的和听同行聊过的案例大致集中在几个方向工业HMI是iMX8M Mini的重头戏。很多设备需要一块带触摸屏的人机界面显示实时数据、报警状态、工艺参数背后还要跑Modbus、CANopen、OPC UA这类工业协议。Colibri模块配合LVDS或HDMI显示接口运行QT应用整体方案可以做得很紧凑。工业网关与边缘采集是iMX6ULL最擅长的领域。模块本身串口资源丰富扩展出RS485、RS232、CAN等接口后可以同时采集多路仪表数据处理之后通过以太网或4G模块上报到平台。这类应用不追求高算力但对稳定性和功耗有要求iMX6ULL正好卡在这个需求点上。医疗设备是Colibri iMX8X经常出现的领域。医疗器械开发周期长、认证严格、设备生命周期普遍在十年以上选择一颗有长期供货保障的工业级SoC和模块对产品合规和售后维护都有很大帮助。铁路、能源、水务等基础设施也是这类模块的传统优势区域。这些行业的特点是设备部署在偏远场合、环境恶劣、维护困难CoM方案成熟稳定、可快速更换的特点刚好匹配需求。2. 从零跑通一套Colibri开发环境烧录、启动、U-Boot2.1 先搞清楚镜像从哪里来拿到Colibri模块之后第一件事不是直接编译系统而是先用官方镜像把模块跑起来。Toradex官网会针对每个模块型号提供发布版BSP镜像一般包含U-Boot、内核、设备树、根文件系统。模块出厂时通常已经预置了一个以追加热叫“Easy Installer”的刷机环境简单说就是一个精简的带图形界面的恢复系统运行在模块上通过USB线连到PC就能用浏览器打开管理界面选择镜像烧写。这种方式对开发前期非常友好不用先折腾调试工具一条USB线就能解决烧录问题。主机环境方面Windows和Linux都支持不过我建议直接用Ubuntu 20.04或22.04 LTS后面编译Yocto时依赖更顺。使用Linux时要注意装好必要的基础工具包包括build-essential、gawk、chrpath、texinfo、python3等这些在Yocto官方文档里都会列全。如果有条件我建议开发机用SSD内存至少16GB编译Yocto时体验会好很多。刚开始做实验不用编译完整BSP直接用预先发布好的镜像文件就行。2.2 首次烧写两种常用方式烧写方式主要有USB OTG和SD卡两种。USB OTG方式操作起来最直观。先把模块和一张载板接好给载板供电用USB线把模块的OTG口连到电脑按住模块上标有烧写模式的按键再上电等待电脑识别出一个USB设备。然后打开浏览器访问Easy Installer提供的页面选择要烧录的镜像包确认后等待写入完成。整个过程有点像给家用路由器刷固件界面化操作很省心。SD卡方式适合需要批量烧录或设备上没有USB口的场景。先把官方提供的SD卡烧录镜像用工具写入一张SD卡Windows下可以用Win32DiskImager或balenaEtcherLinux下直接dd写然后把SD卡插到载板卡槽按照硬件手册指定的启动方式设置启动源上电后系统就会从SD卡引导。SD卡方式还有一个好处可以保留一个救援入口母板eMMC里的系统坏了插上SD卡还能把模块救回来。这里有一个容易踩的坑不同SoC版本进入烧写模式的方式并不完全一样有的要先切换拨码开关有的要按住某个按键还有的需要同时配合USB连接顺序。不要凭经验硬试动手之前先翻一遍对应载板和模块的硬件参考手册看清楚启动源配置。2.3 进入U-Boot之后系统跑起来之后频繁打交道的就是U-Boot。不管是改启动参数、切启动设备还是排查启动问题都得在U-Boot里操作。连接方式是串口一般使用载板上的Debug UART接口Linux下用minicom或screen连接Windows下用MobaXterm或PuTTY。波特率大多数模块默认是115200但个别模块可能不同连接后如果看到乱码先排查波特率。进入U-Boot命令行后几个高频操作可以提前掌握# 列出当前板子上所有存储设备 mmc list # 查看环境变量 env print # 修改启动参数 setenv bootargs consolettymxc0,115200 root/dev/mmcblk0p2 rw rootwait # 保存环境变量到存储设备 saveenv # 把eMMC映射为U盘插到电脑上直接读写 ums 0 mmc 1其中fastboot和ums这两个命令在生产调试时特别有用。ums 0 mmc 1会把eMMC设备映射成U盘模式主机上直接就能挂载分区不用拆机就能拷贝文件fastboot则是Android生态里常见的烧写协议也可以用来单独烧写某个分区。启动参数里的console参数需要注意不同模块对应的串口设备名不一样。iMX6ULL系列一般是ttymxc0iMX8系列部分型号默认使用ttyS0或ttymxc1具体以官方提供的环境变量为准。改设备树或者替换内核之前先确认当前模块用的console设备名否则会看到“启动卡住没有输出”的假象。3. 载板设计模块只是半边江山另一半在你手里3.1 先善待MXM3连接器Colibri模块通过MXM3连接器与载板连接。这个连接器看起来和笔记本内存条很像但是金手指间距更小、引脚更密焊接和布局都有一定讲究。设计载板时第一件事是去官方下载模块的引脚定义表把所有用到的信号逐个确认。模块引脚资源非常丰富GPIO、UART、I2C、SPI、USB、Ethernet、PCIe都从连接器引出来了。这里容易犯一个错误只看原理图符号里的网络标号不核对引脚编号结果做板回来发现信号错位。MXM3这种连接器一旦定义搞错飞线都很难补。布线的时候凡是高速信号都需要特别注意。USB的DP/DM要走差分对阻抗控制在90欧姆左右以太网的TX/RX差分对阻抗100欧姆并且在PHY和连接器之间做好共模电感和ESD防护如果用到PCIe更要按照PCIe规范处理差分对和AC耦合电容。这些在模块内部已经处理过了但在载板这一段如果偷懒照样会把信号质量搞差。3.2 3.3V主电源与复位时序载板设计中最重要的一环是电源。大多数Colibri模块只需要一路3.3V主电源输入模块内部会自行产生核电压、IO电压、DDR电压。这不代表载板的电源设计就可以随便画。模块启动瞬间电流很大如果电源输出能力不足或者走线压降过大会出现上电后模块无反应或者启动一半死机的现象。我给载板做电源的时候习惯用一个余量比较大的DC-DC输出电流至少按模块资料推荐值的1.5倍来选同时在模块电源入口多放几颗电容通常至少220µF钽电容加若干0.1µF陶瓷电容。这样做的目的是应对模块深度睡眠后突然唤醒的瞬态电流尖峰有些系统在深睡眠状态下电流极低一旦收到外部中断唤醒电流会在几毫秒内飙高电源来不及响应就会复位。复位时序同样不能忽视。模块上电后载板如果接了外部看门狗或者复位芯片要确保复位信号的脉冲宽度和释放时序符合模块要求。常见问题是看门狗复位时间过长把模块卡在反复重启的循环里。最好在原理图阶段就把复位路径理清是仅由模块自己控制复位还是由外部看门狗控制这两者的时序要求完全不一样。3.3 以太网、USB、串口与CAN的接入心得外设接入这块不同模块情况不一样需要看具体型号是已经把PHY集成进了模块还是需要在载板上外接PHY。以太网部分如果模块没有内部PHY载板上需要设计PHY电路。百兆方案常用的是LAN8710A这类单口PHY千兆方案则可以选择RTL8211系列。设计时PHY地址不要和模块默认设置冲突常见的PHY地址跳线需要根据数据手册设置。软件上还需要在设备树里对应修改PHY地址和phy-mode这块内容后面在调试部分会细说。USB方面模块通常提供USB Host或OTG接口。Host接口会引出一对DP/DM差分线载板上需要加USB专用的ESD保护器件防止静电损坏模块内部的主控。OTG接口除了数据线还要处理ID检测和VBUS供电设计时要看清模块输出的信号定义别把ID脚当普通GPIO随意接。串口和CAN最容易踩的是电平转换。模块出来的UART默认是3.3V TTL电平直接接RS232或RS485设备是不可行的。RS485方案要在载板上加收发器芯片例如MAX3485并且把方向控制引脚和UART的RTS或某个GPIO连好这部分若控制不当会出现只能收不能发或者只能发不能收的问题。CAN接口则建议使用带隔离的CAN收发器比如ISO1050工业现场长线通信时隔离能解决很大一部分共地干扰问题。4. 用Yocto构建一套自己的系统镜像4.1 搭建BSP构建环境Toradex的BSP基于Yocto开源构建框架这意味着你可以像拼乐高一样定制内核、文件系统、应用程序最终生成一个完全符合自己需求的系统镜像。构建环境推荐使用Ubuntu 20.04或22.04 LTS磁盘可用空间建议100GB以上内存16GB以上。Toradex官方在GitHub上提供了完整的meta层集合包括meta-toradex、meta-toradex-nxp、meta-toradex-demos等。构建流程一般是先初始化repo清单同步所有需要的meta层和openembedded-core然后配置构建环境。核心的构建环境初始化大致是这样mkdir ~/colibri-bsp cd ~/colibri-bsp git clone -b kirkstone https://github.com/toradex/oe-core.git # 按官方wiki指引放置meta层 cd oe-core source oe-init-build-env初始化完成后编辑conf/local.conf把目标机器的MACHINE变量设置为对应模块型号比如使用Colibri iMX6ULL时配置为MACHINE colibri-imx6ull使用iMX8M Mini时配置为MACHINE colibri-imx8mm。执行镜像构建bitbake tdx-image-fulltdx-image-full是Toradex提供的完整镜像目标包含了图形界面、开发工具、常用应用常用于开发初期的验证。等到产品后期需要精简镜像时可以改用tdx-image-minimal之类的精简目标然后手动添加自己需要的包。第一次构建非常耗时几个小时到十几个小时都是正常的。如果公司网络带宽有限建议配置好sstate缓存目录把编译好的中间产物复用起来同一套BSP构建其它模块镜像时能快很多。还有一个小建议经常整理旧构建目录不要把所有临时文件都留在磁盘上时间久了几个版本的构建记录能占用几百GB空间。4.2 往镜像里塞进你自己的应用系统镜像只有内核和基础文件系统还不够产品真正进入开发阶段后需要把应用代码一起打进镜像。Yocto的做法是创建自定义的meta层在层里编写recipe描述应用的源码、依赖和安装方式。创建自定义层bitbake-layers create-layer meta-myapp bitbake-layers add-layer meta-myapp在meta-myapp里新增一个recipe文件假设应用名叫myapp新建recipes-myapp/myapp/myapp_1.0.bb内容类似SUMMARY Demo application for Colibri LICENSE MIT SRC_URI file://myapp \ file://myapp.service S ${WORKDIR} inherit systemd do_install() { install -d ${D}${bindir} install -m 0755 ${WORKDIR}/myapp ${D}${bindir}/myapp install -d ${D}${systemd_system_unitdir} install -m 0644 ${WORKDIR}/myapp.service ${D}${systemd_system_unitdir}/myapp.service } SYSTEMD_SERVICE:${PN} myapp.service这段recipe做的事情很简单把编译好的可执行程序myapp和用于开机自启动的myapp.service文件安装到目标系统里同时用inherit systemd让Yocto自动启用这个systemd服务。myapp.service是一个标准的systemd服务文件[Unit] DescriptionMy Demo Application Afternetwork.target [Service] ExecStart/usr/bin/myapp Restarton-failure [Install] WantedBymulti-user.target最后在local.conf或镜像recipe里加入IMAGE_INSTALL:append myapp重新执行bitbake之后生成的根文件系统里就会包含myapp应用并且开机自动启动。这种方式很适合产线批量烧录每台设备拿到手就是完整的可运行系统不需要再单独部署应用。4.3 分区、OTA与系统更新的考虑产品真正上市之后OTA升级是躲不开的话题。Colibri模块支持SD卡和eMMC启动常规做法是在eMMC上划分多个分区用同一个系统镜像里保留一个可用的恢复分区和主运行分区。比较常见的方案是双分区A/B也就是同一时刻只有一套系统在运行另一套可以作为回滚版本。U-Boot在启动时会检查两个分区里的系统状态标记如果主系统启动失败就自动切换到备份分区。软件升级时新版本写入未运行的那个分区写入完成后修改标记下次重启进入新版本。一旦新系统异常U-Boot还能通过标记回滚到旧版本。系统更新工具方面swupdate是Yocto生态里比较成熟的开源方案支持增量更新、加密校验、回滚机制。Toradex官方也提供了对应的集成方式。如果项目开始时没有精力直接实现完整OTA可以先用一个折中方案利用U-Boot的fastboot协议在设备维护模式下连接电脑手动升级先把升级道路打通再慢慢完善自动化流程。另外建议把module自带的Easy Installer分区保留住。这个分区相当于一个万能保险即使产品在客户现场挂掉了也可以通过进入Easy Installer重新烧写系统恢复成本低很多。5. 调试实录这些坑我帮你踩过了5.1 串口无输出的三板斧串口无输出大概是使用过程中最常遇到的问题。我遇到这种问题时的排查顺序基本固定先量模块电源是否正常再查串口线序最后检查波特率。模块上电后串口完全没有任何输出首先怀疑硬件层面。用万用表确认载板的3.3V是否送到模块不能只看指示灯亮不亮有些载板指示灯接的是别的电平。如果电源正常但依然无输出检查串口的TX和RX线序是否交叉开发板上的调试串口通常已经在载板内做好了交叉但自己做载板时很容易漏掉这一步。波特率问题比较隐蔽有时候线序和电源都没问题只是波特率设错了屏幕上满屏乱码还以为系统没起来。如果硬件都正常但还是没输出可以在U-Boot的设计阶段考虑是否要加早期打印比如检查U-Boot的DEBUG_UART配置。另外不要让U-Boot和内核里配置的console设备名不一样否则会看到U-Boot输出正常一到内核阶段就没声音了。5.2 网络不通与PHY排查以太网不通是另一个高频问题特别是自己设计载板外接PHY的情况下。症状往往是系统启动后ifconfig -a能看到eth0设备但插上网线后链路就是不up或者显示up却Ping不通对端。排查可以从底层往上走。先看PHY是否被内核正确识别启动日志里通常会打印PHY的ID和地址。如果看到类似“unrecognized PHY”的错误说明设备树里PHY地址和实际电路不一致。载板上的PHY地址通常由硬件引脚电平决定比如地址0到3的跳线电阻设备树里reg值必须与此一致。设备树里还有两个关键参数不能搞错phy-mode和max-speed。百兆PHY通常配phy-mode rmii千兆PHY要用rgmii-id或rgmii-rxid等模式这个要根据模块主控的MAC和PHY的实际连接方式来确定。曾经遇到一个项目模块主控支持千兆载板用了百兆PHY但设备树里忘了改phy-mode导致协商一直在百兆和千兆之间反复跳日志里满是link down/up信息。排除软件因素后再用硬件手段确认。示波器量PHY的TX差分对在link up之后是否有时钟信号万用表确认PHY电源和复位是否正常。按经验网络问题十有八九是设备树配置和硬件实际不一致剩下那一两成才是硬件本身焊接问题。5.3 显示与触摸的几个小坑HMI应用最怕显示和触摸出问题。LCD屏幕没有画面先区分是背光问题还是信号问题。如果背光不亮查背光电源和使能脚如果背光亮但屏幕没内容重点查LVDS或RGB信号线连接以及屏参是否配置正确。LVDS屏参在设备树的panel节点里配置包括分辨率的hactive、vactive、像素时钟频率、行场同步极性等参数。这些参数错一个现象可能完全不同有的是黑屏有的是画面偏色有的是图像偏移。调试时先对照屏幕数据手册把参数逐项确认再往设备树里填。触摸方面最常见的是触摸点漂移或乱跳。一种原因是触摸屏的I2C信号受到干扰需要在触摸芯片的电源和I2C线上加滤波电容中断引脚也要加上拉电阻另一种是触摸屏本身未校准对于电阻屏需要做校准对于电容屏一般不需要。用evtest工具可以实时查看触摸事件如果事件坐标明显不规律跳动基本可以判定是硬件干扰而非系统问题。还有一个小细节触摸屏的复位脚如果和主控某个GPIO共用而这个GPIO在设备树里又被中间层复用会出现开机找不到触摸芯片的情况。建议触摸芯片的复位脚独立控制不要在系统运行中被其他驱动拉低。5.4 五个常用调试命令调试过程中有几个高频命令值得单独列出来# 查看内核启动日志 dmesg | grep -i err # 查看网络链路状态 ethtool eth0 # 查看存储设备分区 cat /proc/mtd # SPI NOR 或 NAND 时 lsblk # 查看systemd管理的服务状态 systemctl status myapp.service # 实时查看串口设备输入事件 evtest /dev/input/event0其中dmesg基本每次排查都要用到。内核崩溃时优先查看启动日志最后几十行再配合设备树里bootargs加earlycon或panic_print参数往往能拿到比默认输出多很多的有效信息。5.5 常见问题速查表症状可能原因快速定位方法上电后串口完全无输出电源未正常建立或串口线序错误万用表量3.3V检查TX/RX交叉串口输出乱码波特率不匹配依次尝试115200/57600/921600U-Boot有输出内核无输出console参数或设备树串口配置错误检查bootargs里ttymxcX参数网线插入不识别PHY地址/模式与设备树不一致启动日志查PHY ID核对dts配置触摸漂移乱跳I2C干扰或上拉不足evtest观察事件坐标检查硬件滤波显示黑屏但背光亮屏参或信号极性错误对照屏手册核验panel节点配置系统启动后经常死机电源纹波大或时序问题示波器量3.3V纹波检查模块唤醒瞬态修改设备树后启动失败设备树编译错误或引脚冲突dmesg查pinctrl冲突undo确认变更点每个人踩坑的位置都不一样但排查思路大致相同先硬件后软件先电源后信号先bootloader后kernel。只要把串口日志、电源波形、设备树配置这三样东西抓在手里绝大多数问题都能定位出来。从我最早用Colibri iMX6ULL做串口服务器到现在尝试iMX8M Mini上的HMI方案最大的体会是CoM这套玩法真的是把复杂留给了模块、把简单留给了用户。硬件设计重心从“把DDR跑稳”变成了“把外设接口做好”软件重心从“移植BSP”变成了“写好自己的应用”整个项目节奏快了很多。最后分享一个我自己的小习惯模块载板第一次打样回来先不急着焊所有外设只把电源、调试串口、SD卡这几路必备接口焊好跑通系统再逐步添加外设。这样一旦出问题排查范围小不会一上来就被一堆因素干扰。
返回列表