当前位置: 首页 > news >正文

AM243x多核MCU启动流程解析与OSPI Flash烧录实战

1. 项目概述与核心挑战

如果你正在接触TI的AM243x这类多核异构MCU,并且被它复杂的启动流程和程序烧录搞得一头雾水,那么这篇文章就是为你准备的。我最近在基于AM243x-LP评估板进行开发时,花了大量时间才把从芯片上电到应用程序跑起来的整个链条彻底打通。这个过程远不止是点一下“编译”和“下载”那么简单,它涉及到芯片内部的电源域管理、多级引导加载器(Bootloader)的协同、以及如何将程序正确地固化到外部Flash中。很多刚接触这类高性能MCU的工程师,往往会在“我的程序怎么烧不进去?”或者“为什么一断电程序就没了?”这类问题上卡很久。今天,我就以最常用的从板载OSPI Flash启动为例,把AM243x的启动原理、SBL(二级引导加载器)的作用、以及如何通过UART将程序烧录到Flash的完整实操过程,掰开揉碎了讲清楚。无论你是软件、硬件还是系统工程师,理解这套流程都是玩转AM243x的必修课。

2. AM243x启动流程深度解析

要烧录和启动,首先必须理解芯片是怎么“醒来”并找到你的程序的。AM243x的启动链可以概括为经典的三级接力:ROM Bootloader (RBL) -> Secondary Bootloader (SBL) -> Application (APP)。但这简单的三步背后,是多核异构架构带来的复杂协同。

2.1 上电与引导模式:一切的起点

AM243x芯片内部有多个电源域,为不同的处理器核心和外设供电。它不是简单的一上电所有部分都工作。上电时序是第一个关键,电源必须按照特定顺序和电压要求稳定,否则芯片可能无法正常复位或启动。在评估板上,这部分通常由电源管理芯片(PMIC)妥善处理,我们只需确保供电正常即可。

当最后一个电源域稳定,MCU_PORz(上电复位)引脚释放时,芯片会做一件至关重要的事:锁存SYS_BOOTMODE[0:15]这组引脚的状态。这16个引脚的状态(通过上下拉电阻配置),直接决定了芯片的启动模式启动介质。这就像是告诉刚睡醒的芯片:“去哪个房间(哪种接口)找你的第一份指令(RBL)”。

注意:在AM243x-LP评估板上,这组Bootmode引脚连接到了一个8位的拨码开关(SW3)上。通过拨动开关,我们可以直观地配置启动模式。设计自己的底板时,必须参考技术参考手册(TRM)中的“Bootmode Pin Map”章节,确保你希望使用的启动接口(如OSPI、UART)对应的引脚没有被其他功能占用,并且正确配置了上下拉电阻。

AM243x支持两大类启动模式:

  • 主机启动模式:芯片作为“从设备”,等待外部主机(如PC)通过UART、Ethernet、USB等接口发送启动镜像。这常用于程序烧录调试阶段。
  • 存储器启动模式:芯片作为“主设备”,主动从外部存储介质(如OSPI Flash、SD卡、eMMC)读取启动镜像。这是产品量产运行时的标准方式。

此外,芯片还贴心地设计了主备份启动机制。如果配置为主启动模式(Primary Boot)的介质读取失败(比如Flash为空或损坏),芯片会自动尝试切换到备份启动模式(Backup Boot)再次尝试。这提高了系统的可靠性。

2.2 ROM引导加载器:芯片的出厂固件

上电复位后,最先运行的是固化在芯片ROM中的代码,即RBL。它的任务是进行最基础的初始化,并根据Bootmode引脚配置,从指定的外部接口寻找并验证下一阶段的引导程序(即SBL)。AM243x的RBL设计比较特别,它分为两部分协同工作:

  1. DMSC ROM Code:这是运行在一个专用Cortex-M3核心(称为DMSC,设备管理与安全控制器)上的固件。它是启动过程的“总指挥”。它的工作包括:

    • 管理整个芯片的电源、时钟和安全状态。
    • 配置系统级的基础设施,如防火墙、安全代理等。
    • 最重要的,它控制着所有R5F应用核心的复位释放。也就是说,在DMSC完成它的初始化之前,R5F核心是“沉睡”的。
  2. Public ROM Code:这部分是运行在第一个R5F核心(R5FSS0-0)上的固件。在DMSC释放其复位后,它开始工作。它的核心职责是:

    • 根据Bootmode配置,驱动对应的外设(如OSPI控制器、UART控制器)。
    • 从外部介质(如Flash)或主机接口(如UART)接收SBL镜像数据。
    • 将接收到的数据提交给DMSC进行完整性校验(使用SHA-512算法)。这是安全启动的第一道关口。
    • 如果校验通过,则配置PLL,并将SBL镜像加载到指定的RAM地址(通常是0x70000000),然后跳转到那里执行。如果主启动失败,则尝试备份启动。

实操心得:理解RBL的工作范围很重要。它只负责最基础的初始化和加载SBL。它支持复杂的文件系统、也不负责加载多核APP。这些高级功能都需要由我们开发者提供的SBL来完成。因此,如果你的SBL镜像本身格式不对、签名无效(对于安全器件)或加载地址错误,RBL就会卡住,表现为芯片“没反应”。

2.3 二级引导加载器:承上启下的关键

SBL是我们开发者可以定制和编译的程序。它的核心使命是建立完整的软件运行环境,并加载最终的用户应用程序。一个典型的SBL(如SBL_OSPI)会执行以下操作:

  1. 初始化基础外设:例如,初始化用于打印调试信息的UART控制台。
  2. 加载系统固件:调用Bootloader_socLoadSysFw()函数,将TI提供的系统固件镜像加载到DMSC的RAM中并启动它。这个SYSFW包含了芯片所有底层资源的驱动和管理策略,是多核通信、电源管理、时钟管理等服务的提供者。没有它,多核应用无法正常运行。
  3. 初始化启动介质:例如,对OSPI Flash控制器进行更复杂的配置(如DDR模式、调优),使其能以更高性能工作。
  4. 解析并加载应用镜像:从Flash的固定偏移地址(例如0x80000)读取多核应用镜像。这个镜像文件(.appimage)是一个复合镜像,内部包含了每个核心(R5FSS0-0, R5FSS0-1, R5FSS1-0, R5FSS1-1, M4F)各自的代码、数据以及描述其加载地址和入口地址的元数据。
  5. 分发应用:SBL解析这些元数据,将每个核心的代码段、数据段拷贝到它们各自指定的内存地址(如DDR或片上RAM)。
  6. 释放其他核心:SBL通过DMSC的IPC(进程间通信)服务,请求释放其他所有应用核心的复位信号。
  7. 跳转执行:最后,SBL引导所有核心从各自的入口地址开始执行用户应用程序,完成启动接力。

注意事项:SBL自身的链接地址(Entry Point)是固定的,由RBL决定(通常是0x70000000)。在编译SBL工程时,必须在链接器命令文件中正确设置-e参数指向这个地址。同时,SBL通常只运行在R5FSS0-0核心上,因此需要在代码起始处将其他R5核心置于WFI(等待中断)状态,防止它们跑飞。

3. 开发环境搭建与SBL镜像生成

理论清楚了,我们开始动手。要让AM243x从OSPI Flash启动,我们需要准备两样东西:SBL镜像和APP镜像。这里先讲SBL。

3.1 软件与工具准备

你需要以下软件环境:

  1. Code Composer Studio:TI主推的集成开发环境,用于编译工程。
  2. MCU+ SDK:针对AM243x的软件开发包,包含了所有外设驱动、示例和必要的工具链。请从TI官网下载对应版本。
  3. OpenSSL:用于生成镜像签名。即使你的芯片不启用安全启动,RBL也要求SBL镜像必须是经过签名的格式(.tiimage)。从 slproweb.com 下载Win64 OpenSSL Light版本安装即可。安装时记得勾选“将OpenSSL DLL复制到Windows系统目录”。
  4. Python 3:用于运行UART烧录脚本。从官网下载安装,务必在安装向导中勾选“Add Python to PATH”。

安装后,将OpenSSL的bin目录(如C:\Program Files\OpenSSL-Win64\bin)添加到系统的PATH环境变量中,并在命令行验证python --versionopenssl version能否正确执行。

3.2 编译与生成SBL镜像

SDK中提供了多种SBL示例,我们选择SBL_OSPI

  1. 导入工程:在CCS中,选择Project -> Import CCS Projects...,导航到SDK路径下的\examples\drivers\boot\sbl_ospi文件夹,导入工程。
  2. 编译工程:直接编译该工程。这会在项目的DebugRelease输出目录下生成一个.out文件(如sbl_ospi_am243x-lp_r5fss0-0_nortos_ti-arm-clang.out)。
  3. 转换与签名.out文件不能直接用于启动,需要经过两步转换:
    • 转换为裸二进制:使用ARM工具链中的objcopy(CCS在编译时通常已自动生成同名的.bin文件),将ELF格式的.out文件转换为纯二进制的.bin文件。
    • 签名生成TI镜像:这是关键一步。我们需要使用SDK提供的签名脚本。打开Windows PowerShell(注意不是CMD,且可能需要以管理员身份运行),导航到签名脚本目录:
      cd C:\ti\mcu_plus_sdk_am243x_xx_xx_xx_xx\tools\boot\signing
    执行签名命令,这里需要替换为你自己的.bin文件路径和名称:
    .\x509CertificateGen.ps1 -b .\sbl_ospi_am243x-lp_r5fss0-0_nortos_ti-arm-clang.bin -o sbl_ospi_mine.tiimage -c R5 -l 0x70000000 -k .\rom_degenerateKey.pem -d DEBUG -j DBG_FULL_ENABLE -m SPLIT_MODE
    • -b: 输入的.bin文件。
    • -o: 输出的.tiimage文件名。
    • -c: 核心类型,R5。
    • -l: 加载地址,必须与SBL工程链接地址一致(0x70000000)。
    • -k: 签名密钥,使用SDK提供的默认测试密钥即可。
    • -d,-j,-m: 调试和模式参数,保持默认。

执行成功后,你会得到sbl_ospi_mine.tiimage文件,这就是可以被RBL识别和加载的SBL镜像。

避坑指南

  • 路径问题:建议先将生成的.bin文件拷贝到signing目录下再执行命令,避免因路径包含空格或特殊字符导致脚本执行失败。
  • PowerShell执行策略:公司电脑可能限制PowerShell脚本执行。如果报错,可以尝试以管理员身份运行PowerShell,并执行Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser临时更改策略(操作后请改回)。
  • 镜像版本:SDK的\tools\boot\sbl_prebuilt\am243x-lp\目录下已有预编译好的SBL镜像(如sbl_ospi.release.tiimage)。在初次验证时,可以直接使用预编译镜像以排除自己编译引入的问题。

4. 应用程序镜像生成与配置

SBL准备好后,我们需要一个最终要运行的用户程序,这里以ADC单次采样例程为例。

4.1 编译应用程序

  1. 导入ADC例程:在CCS中,导入SDK中的ADC示例工程,路径通常为\examples\drivers\adc\adc_singleshot\am243x-lp\r5fss0-0_freertos
  2. 编译工程:编译后,在输出目录(如Debug)下,除了常见的.out文件,你会找到一个非常重要的文件:adc_singleshot_am243x-lp_r5fss0-0_freertos_ti-arm-clang.appimage
    • .appimage文件:这是通过SDK提供的tiarmimagegen工具生成的多核应用镜像。它内部打包了所有使能核心的程序代码、数据以及一个描述各段信息的文件头。SBL正是通过解析这个文件头,才知道该把哪段代码加载到哪个地址、并启动哪个核心。

4.2 理解镜像的存储布局

现在我们有了一前一后两个镜像:SBL.tiimageAPP.appimage。它们需要被烧录到OSPI Flash的特定位置:

  • SBL镜像:必须烧录到Flash的起始地址0x0)。因为RBL固定从启动介质的0地址开始加载数据。
  • APP镜像:默认烧录到偏移量0x80000(512KB)的位置。这个偏移量是SBL代码里写死的查找地址。你可以在SBL的源代码(通常是sbl_main.c或相关的配置文件)中修改这个地址,但必须保证SBL和APP的存储区域没有重叠。

这种布局确保了启动过程的确定性:RBL从0读SBL,SBL从0x80000读APP。

5. 通过UART烧录OSPI Flash全流程实操

这是最核心的实操环节。我们将使用评估板自带的XDS110调试器提供的UART接口,配合Python脚本,将SBL和APP镜像烧写到板载的OSPI Flash中。

5.1 硬件连接与板卡配置

  1. 连接线缆
    • 将评估板的Micro-USB口(标记为XDS110)连接到电脑。这个接口同时提供调试和UART串口功能。
    • 将评估板的USB Type-C口连接到电源适配器或电脑的USB口供电。建议使用能提供5V/2A以上电流的电源。
  2. 配置启动模式:将评估板上的拨码开关SW3设置为UART启动模式。根据板卡手册,这通常是SW3.1 = OFF (0), SW3.2 = ON (1), SW3.3 = OFF (0), SW3.4 = ON (1),其余位保持默认。设置完成后,给板卡重新上电(或按下SW1复位键)。
  3. 识别串口:在Windows设备管理器中,查看“端口(COM和LPT)”,你会看到XDS110 Class Application/User UART对应的COM号(例如COM17)。记下这个号码。

5.2 准备烧录脚本与文件

手动敲命令容易出错,我习惯创建一个批处理文件来组织所有操作。在你的ADC例程工程目录下,新建一个文件夹,比如叫FlashProgram

  1. 收集必要文件

    • 将之前生成的或预编译的sbl_ospi.release.tiimage(SBL镜像)拷贝进来。
    • 从SDK的\tools\boot\目录拷贝uart_uniflash.py脚本文件进来。
    • 从SDK的\tools\boot\sbl_prebuilt\am243x-lp\目录拷贝sbl_uart_uniflash.release.tiimage文件进来。这个文件非常关键,它是一个特殊的SBL,运行后不引导APP,而是作为一个“Flash烧写服务器”,通过UART接收来自PC的烧录指令和数据。
    • 将ADC例程编译生成的adc_singleshot_am243x-lp_r5fss0-0_freertos_ti-arm-clang.appimage(APP镜像)也放在方便引用的位置(比如上一级目录的Debug文件夹)。
  2. 创建配置文件:在FlashProgram文件夹内,创建一个文本文件,命名为ospi_sbl_app.cfg,内容如下。这个文件告诉烧录脚本要做什么。

    # 首先指定烧写器镜像(即那个特殊的SBL) --flash-writer=sbl_uart_uniflash.release.tiimage # 操作1:烧写OSPI PHY调优数据(可选,但建议进行以确保Flash性能) --operation=flash-phy-tuning-data # 操作2:在偏移量0x0处烧写主SBL镜像 --file=sbl_ospi.release.tiimage --operation=flash --flash-offset=0x0 # 操作3:在偏移量0x80000处烧写应用程序镜像 --file=../Debug/adc_singleshot_am243x-lp_r5fss0-0_freertos_ti-arm-clang.appimage --operation=flash --flash-offset=0x80000

    注意--file参数后的路径需要根据你实际的文件存放位置进行修改。

  3. 创建批处理文件:在同一目录下,创建program.bat文件,内容如下:

    @echo off echo ======================================== echo 开始烧写 QSPI Flash... echo ======================================== echo. python uart_uniflash.py -p COM17 --cfg=ospi_sbl_app.cfg echo. echo ======================================== echo 烧写完成! echo ======================================== echo. pause

    COM17替换为你设备管理器中看到的实际COM端口号。

5.3 执行烧录

  1. 确保AM243x-LP板卡已配置为UART模式并重新上电。
  2. 双击运行program.bat文件。
  3. 观察命令行窗口的输出。脚本会依次执行以下动作:
    • 通过UART发送sbl_uart_uniflash.tiimage到板卡并运行。此时板卡上的RBL会加载这个镜像。
    • 该镜像运行后,会在串口打印信息,等待主机连接。
    • Python脚本与之建立连接,然后根据.cfg文件指令,依次将PHY调优数据、SBL主镜像、APP镜像通过UART发送给板卡上的“烧写服务器”。
    • “烧写服务器”将这些数据写入到OSPI Flash的指定地址。
  4. 看到“烧写完成!”的提示,且没有报错,即表示成功。

5.4 验证启动

  1. 切换启动模式:将评估板拨码开关SW3改回OSPI启动模式(根据手册,通常是SW3.1 = ON (1), SW3.2 = OFF (0), SW3.3 = OFF (0), SW3.4 = ON (1))。
  2. 复位或重新上电:按下SW1(MCU_PORz)复位键,或者重新拔插Type-C电源线。
  3. 观察串口输出:打开一个串口终端软件(如Tera Term、Putty),连接到之前识别到的那个COM口,波特率设置为115200。你应该会看到类似以下的输出:
    [SBL] Starting Secondary Bootloader... [SBL] Loading SysFw... [SBL] SysFw Loaded Successfully. [SBL] Opening OSPI Flash... [SBL] Reading App Image from offset 0x80000... [SBL] Jumping to Application... [ADC Demo] ADC Single Shot Example Started. [ADC Demo] Raw Value: xxxx, Voltage: x.xx V.
    这表明RBL成功加载了SBL,SBL成功加载并跳转了ADC应用程序,整个RBL -> SBL -> APP的启动链条完美运行。

6. 常见问题排查与调试技巧

在实际操作中,你可能会遇到各种问题。这里分享几个最常见的坑和排查思路。

6.1 串口无任何输出

  • 检查供电:确认Type-C电源已连接且LD9红灯没有常亮。用万用表测量板卡上3.3V等关键电源点电压是否正常。
  • 检查启动模式最常犯的错误。确认拨码开关SW3的设置与你想使用的启动模式完全一致,并且在上电或复位前已设置好。可以对照评估板手册反复核对。
  • 检查串口连接
    • 确认使用的是“User UART”对应的COM口。
    • 确认终端软件参数:波特率115200,8数据位,1停止位,无校验,无流控。
    • 尝试拔插USB线,让系统重新识别端口。
  • 检查SBL镜像:如果是在OSPI启动模式下无输出,可能是SBL镜像本身有问题。尝试使用SDK预编译的sbl_ospi.release.tiimage进行烧录,以排除自己编译、签名出错的可能。

6.2 烧录脚本执行失败

  • Python环境与依赖:确保Python已正确安装并加入PATH。在管理员CMD中运行pip install pyserial xmodem tqdm确保依赖包齐全。
  • COM端口占用:关闭所有可能占用该串口的终端软件、CCS调试会话等。
  • 板卡状态:确保执行脚本前,板卡已处于UART启动模式并完成复位。可以观察串口是否有类似Waiting for flash writer...的提示输出。
  • 文件路径错误:仔细检查.cfg文件和.bat文件中的路径是否正确,尤其是相对路径..的使用。建议初期使用绝对路径避免混淆。

6.3 SBL启动后卡住,无法加载APP

  • 串口有SBL打印,但无APP打印:这通常是APP镜像烧录位置或镜像本身问题。
    • 检查烧录偏移量:确认烧录APP时使用的--flash-offset与SBL代码中查找APP的偏移量是否一致(默认都是0x80000)。
    • 检查APP镜像:确认烧录的是.appimage文件,而不是.out.bin文件。只有.appimage才包含多核加载信息。
    • 检查SBL调试信息:在SBL源代码中增加更详细的日志,打印出读取Flash的地址、镜像大小、校验结果等信息,有助于定位是读取失败还是镜像解析失败。

6.4 调试手段进阶

  • 使用CCS连接调试:在SBL或APP的代码中设置断点,通过CCS连接XDS110调试器,可以单步执行,查看变量、内存和寄存器状态,这是定位复杂问题的终极手段。
  • 查看内存内容:如果怀疑Flash内容不对,可以在CCS的Memory Browser中直接查看OSPI Flash映射的内存地址范围(例如0x60000000开始),对比写入的数据和预期的镜像文件是否一致。
  • 利用ITM/SWO输出:对于更深层次的、串口初始化前的调试,可以配置芯片通过ITM(Instrumentation Trace Macrocell)和SWO(Serial Wire Output)引脚输出调试信息,需要额外的硬件(如J-Link)和支持。

整个流程走通后,你会发现AM243x的启动虽然步骤繁多,但逻辑清晰。关键在于理解每一级加载器的职责,以及镜像文件的正确生成和放置位置。掌握了这套方法,你就能 confidently 将你的应用程序部署到Flash中,实现产品的独立上电运行。

http://www.jsqmd.com/news/824133/

相关文章:

  • 从单仓到多租户GitOps:DeepSeek支撑200+业务线的分层仓库架构(含Git Submodule+OCI Registry双模设计图)
  • 2026年4月服务好的涂胶机公司推荐,单双向预浸机设备/碳纤维预浸料设备/碳纤维预浸料/涂膜机/涂胶机,涂胶机厂商推荐 - 品牌推荐师
  • PNG转Windows鼠标指针:开源工具png-to-cursor全解析
  • 生态系统碳循环模型CENTURY建模方法应用——以柠条灌木林生产力模拟为例
  • 嵌入式Python库CI/CD实战:Travis CI自动化测试与发布
  • 第12章:C++ 编译链接原理
  • AI时代文科复兴论:社会约束的客观性与认知训练的偏移
  • 2026年塑胶品牌曝光渠道哪些值得推荐怎么判断:江外江适用场景与选型对比清单 - 广州矩阵架构科技公司
  • OpenClaw-NVIDIA-NIM-API:简化大模型推理部署的中间层实践
  • Pro Workflow:基于SQLite持久化记忆的AI编程助手智能协作系统
  • 贵州异形沙发定制技术解析与合格厂家参考 - 奔跑123
  • AI Agent 六大趋势怎么看
  • Snip:基于React DevTools与Source Maps的浏览器到IDE视觉化调试工具
  • 高效管理抖音内容:开源下载工具完整使用指南
  • 魔百盒M301H-ZN代工_HI3798MV300H芯片_8822CS无线模块-深度定制与刷机实战指南
  • OpenClaw插件开发实战:无缝集成Claude Code超能力到本地AI工作流
  • 从零构建课堂教学过程管理系统——数据库原理课程设计全记录
  • 70行代码实现MCU性能热点分析:基于Cortex-M中断采样的轻量级Profiler
  • 树莓派机械爪控制:从PWM原理到软硬件集成实践
  • DataCleaner:企业级数据质量管理的开源利器
  • 第13章:C++ 静态分析工具
  • 硬件产品出海必读:从Type A到Type O,不同国家电源插头标准与适配设计要点
  • 2025年CMS怎么选?从传统到无头再到AI原生,一份深度选型指南
  • 深入解析主权身份:DID与可验证凭证构建去中心化数字身份
  • 贵阳高评价沙发定制厂家盘点 工程级实力客观对比 - 奔跑123
  • 电气噪声抑制实战:从原理到电磁屏蔽的电子系统稳定性设计
  • 基于OpenClaw构建智能家居环境感知系统:从传感器到自动化规则
  • 大语言模型底层逻辑:从LM到Agent的完整工作流解析!
  • 贵州酒店家具厂家实力排行:工程定制维度实测 - 奔跑123
  • Midjourney v6.2建筑专属更新深度拆解:仅0.3%用户掌握的--tile+--style raw+--sref三重空间锚定技术