资讯详情

6 步让 i.MX RT1180 双核跑起来:RT-Thread 多核 BSP 完整指南,从 CM33 拉起 CM7 到 RPMsg-Lite 通信

📅 2026/11/4 6:13:35 | 华诺云谱 👁 阅读
6 步让 i.MX RT1180 双核跑起来:RT-Thread 多核 BSP 完整指南,从 CM33 拉起 CM7 到 RPMsg-Lite 通信
6 步让 i.MX RT1180 双核跑起来RT-Thread 多核 BSP 完整指南从 CM33 拉起 CM7 到 RPMsg-Lite 通信【免费下载链接】rt-threadRT-Thread is an open source IoT Real-Time Operating System (RTOS). https://rt-thread.github.io/rt-thread/项目地址: https://gitcode.com/gh_mirrors/rt/rt-thread本文以 RT-Thread 仓库里的 i.MX RT1180 EVK BSP 为例围绕双核独立编译与核间通信两大能力走通 CM33 主核出 banner、六步拉起 CM7 从核、RPMsg-Lite 共享内存 ping-pong 验证以及外设按需裁剪的完整链路。 动手前环境与双工程布局i.MX RT1180 把两颗内核塞进同一颗芯片800MHz 的 Cortex-M7 和 240MHz 的 Arm Cortex-M33。BSP 给它们的分工是CM7 跑算力密集的业务CM33 带 TrustZone 安全扩展负责系统管理、安全启动与网络侧事务主核身份落在 CM33CM7 是 remote 从核。芯片另带双千兆以太网与 EtherCAT 等工业接口定位工业控制和电机驱动场景详见 README_zh.md。落到代码目录两颗核是两套互不依赖的工程各自拥有 applications、board、rtconfig.h 与 IDE 模板文件bsp/nxp/imx/imxrt/imxrt1180-nxp-evk/ ├── README.md / README_zh.md ├── cm33/ # 主核工程 │ ├── applications/ # main.c, multicore_thread.c, mnt.c │ ├── board/ # MCUX_Config, linker_scripts, ports │ ├── xip/ # FlexSPI NOR XIP 启动配置 │ └── rtconfig.h / rtconfig.py / template.* └── cm7/ # 从核工程目录结构与 cm33 一致把两套 rtconfig.h 摆在一起对比差异一眼可见对比项cm33 工程cm7 工程架构宏ARCH_ARM_CORTEX_M33ARCH_ARM_CORTEX_SECUREARCH_ARM_CORTEX_M7ARCH_ARM_CORTEX_FPU控制台设备RT_CONSOLE_DEVICE_NAME uart1RT_CONSOLE_DEVICE_NAME uart12对应串口LPUART1LPUART12RX/TX DMA 通道0 / 122 / 23内核版本RT_VER_NUM 0x50300同左默认外设QSPIFLASH、DMA、GPIO、LPUART1QSPIFLASH、DMA、GPIO、LPUART12也就是说CM33 的日志从 UART1 出CM7 从 UART12 出两路互不干扰BSP 出厂只开了最小串口其余外设全部靠后面的 Kconfig 开关解锁。⚡ 跑通主核CM33 端 5 步出 banner结论先行拉包、生成工程、接线、下载、看串口五步闭环。第 1 步拉取软件包。目的BSP 依赖PKG_USING_NXP_IMXRT_DRIVER这个 NXP 驱动包缺库编译必挂。在 BSP 目录下用 ENV 执行pkgs --update看到命令正常结束、无报错即代表依赖就位。第 2 步生成工程。三条命令对应三种构建方式任选其一scons --targetiar生成 IAR 工程scons --targetmdk5生成 Keil 工程scons -j8则是直接用 GCC 后台编译、不需要 IDE。这里展开 Keil 路径scons --targetmdk5工具链与链接参数取自 rtconfig.py默认CROSS_TOOLgcc可用环境变量RTT_CC覆盖。看到 cm33/ 目录下生成 Keil 工程文件即代表成功。第 3 步接线供电。用数据线把开发板连到 PC打开电源开关。看到 PC 识别到板载调试口即代表连接正常。第 4 步CMSIS-DAP 下载。工程默认配置就是 CMSIS-DAP 下载方式连接建立后直接点下载按钮。看到下载流程走完且无报错即代表程序已写入 Flash。第 5 步串口验证。终端按 115200-8-1-N 打开 UART1 对应的串口号复位设备应看到启动 banner\ | / - RT - Thread Operating System / | \ 5.2.2 build May 15 2026 17:19:35 2006 - 2024 Copyright by RT-Thread team随后 main.c 打印MIMXRT1180_CM33 Hello_World并用GET_PIN(4, 27)驱动的板载 LED 以 500ms 周期翻转。三样都看到即代表 CM33 主核已正常跑通。 唤醒从核CM33 拉起 CM7 的六步链路整条 kickoff 链路写在 cm33 的 multicore_thread.c 里。multicore_init()用INIT_APP_EXPORT在应用初始化阶段创建multicore线程栈 2048、优先级 10、时间片 5线程前半段按下面六步执行对应BSP_USE_MULTICORE_KICK_OFF开关MCMGR_Init()初始化多核管理单元确立 CM33 的 master 身份返回值不是kStatus_MCMGR_Success就当场返回-RT_ERROR后面都不做。MCMGR_RegisterEvent()先注册kMCMGR_RemoteApplicationEvent回调回调只干一件事——把事件值写进RPMsgRemoteReadyEventData。源码注释明确要求注册动作发生在启动从核之前。BOARD_GetCore1ImageAddrSize()board.c 中逐容器扫描 Flash校验IMAGE_TAG_NUM签名从 CM7 可执行镜像条目里取回源地址、目的地址、大小、启动地址四个值线程会把它们全部打印出来供你核对。BOARD_PrepareCore1()若启动地址不在 CM7 ITCM 范围内即镜像驻留 NOR Flash、XIP 运行先调Prepare_CM7初始化 TCM 与 ECCTCM ECC 熔丝使能时还会把向量表前两字拷到 0x0 充当假向量表解决 ROM 上电后 VTOR 定死的问题。MCMGR_StartCore()以kMCMGR_Start_Synchronous同步方式启动kMCMGR_Core1。注意第三个参数是rpmsg_lite_base的基址——这次调用顺带把 RPMsg 共享内存地址交给了从核没它从核找不到通信区。轮询等就绪while (1 ! RPMsgRemoteReadyEventData)循环内rt_thread_mdelay(10)每 10ms 查一次从核经MCMGR_TriggerEvent上报的 ready 信号。串口出现CM7 core is ready!即代表六步链路全部走完。 打通通道RPMsg-Lite 配置与 ping-pong 验证RPMsg-Lite 是基于共享内存的轻量消息协议由BSP_USE_MULTICORE_RPMSG_LITE控制打开 Multicore 菜单后默认即为 y。共享内存段的三家写法。rpmsg_lite_base[]默认 6144 字节但不同编译器落段方式不同必须与链接脚本对得上源码里一次写全#if defined(__ICCARM__) #pragma location rpmsg_sh_mem_section static char rpmsg_lite_base[SH_MEM_TOTAL_SIZE]; #elif defined(__CC_ARM) || defined(__ARMCC_VERSION) static char rpmsg_lite_base[SH_MEM_TOTAL_SIZE] __attribute__((section(rpmsg_sh_mem_section))); #elif defined(__GNUC__) static char rpmsg_lite_base[SH_MEM_TOTAL_SIZE] __attribute__((section(.noinit.$rpmsg_sh_mem))); #else #error RPMsg: Please provide your definition of rpmsg_lite_base[]! #endif一句话点破三家IAR 用 pragma 定位到rpmsg_sh_mem_sectionKeil 用 section 属性写同名段GCC 落到.noinit.$rpmsg_sh_mem。master 侧四步。rpmsg_lite_master_init()以共享内存基址、大小、link ID 和RL_NO_FLAGS完成身份初始化接着rpmsg_queue_create()建接收队列再rpmsg_lite_create_ept()建本地端点地址取LOCAL_EPT_ADDR接收回调是rpmsg_queue_rx_cb最后rpmsg_ns_bind()绑定名称服务回调app_nameservice_isr_cb把远端端点地址写进remote_addr线程随即忙等它变非零——等的就是 CM7 侧的服务广播。remote 侧四步握手。对照 cm7 的 multicore_thread.c先MCMGR_GetStartupData()从 CM33 拿回第 5 步传过去的共享内存基址再做platform_patova()地址变换、rpmsg_lite_remote_init()初始化然后MCMGR_TriggerEvent()发 ready 事件主核第 6 步轮询的数据源rpmsg_lite_wait_for_link_up()阻塞到链路建立rpmsg_ns_announce()广播服务字符串主核的等待到此结束。ping-pong 验证。主核先以RL_DONT_BLOCK发出首条THE_MESSAGE{DATA}随后进入msg.DATA 100的循环rpmsg_queue_recv()阻塞收 pong、DATA、再发 pingCM7 侧收到即加一后原路回发。两端串口都打出Ping-pong communication completed!即代表上百轮往返无丢包。可配置参数一览。Kconfig 里的取值经 rtconfig.h 传入源码源码侧用#ifndef兜底默认值参数CM33 默认CM7 默认说明RPMSG_LITE_LINK_ID00链路 ID即RL_PLATFORM_IMXRT1180_M33_M7_LINK_IDRPMSG_LOCAL_EPT_ADDR4030本地端点地址取值范围 0~65535RPMSG_NS_ANNOUNCE_STRINGrpmsg-openamp-demo-channel同左从核广播服务用的名称服务字符串RPMSG_SHARED_MEM_SIZE6144字节无此项共享内存区大小仅主核工程提供✂️ 按需裁剪外设开关与三种内存布局出厂配置只留最小串口其余外设在menuconfig里逐项打开开关集中在 cm33 的 board/Kconfig重点项如下开关宏一句话作用BSP_USING_LPUART1~BSP_USING_LPUART12每路串口独立使能RX/TX DMA 通道可分别指定0~32BSP_USING_SPI1~BSP_USING_SPI4LPSPI1~4每路可开 DMA 并设独立通道BSP_USING_I2C1/2/3/6LPI2C100kHz/400kHz 波特率二选一默认 100kHz可开 DMABSP_USING_USBCherryUSB 协议栈选 OTG1/OTG2 与 Device/Host 角色Host 下可加鼠标 shell 演示BSP_USING_SDIOSDIO 控制器下设CODE_STORED_ON_SDCARD让 SD 卡充当启动设备BSP_USING_ETHNETC 双千兆以太网自动选中 SAL/netdev/lwIPNETC_USE_SWT0EP0 直连、1switch 模式PHY 默认开启BSP_USING_FS文件系统入口SD 卡 FATFS或 QSPI Flash LittleFS后者依赖 FAL 及分区表BSP_USING_QSPI_FLASHFlexSPI1 NOR Flash 读写驱动XIP 与文件系统的地基BSP_USE_HYPERRAM把板载 HyperRAM 挂成扩展内存BSP_USE_MULTICORE多核总开关其下 KICK_OFF 与 RPMSG_LITE 默认均为 yimxrt 家族的 Kconfig 菜单结构基本一致下图截自 imxrt1052-fire-pro 的 board/Kconfig可作结构参考三种内存布局怎么选。Kconfig 末尾的 Linker Script Selection 给出三选一选项链接结果BSP_LINKER_SCRIPT_RAM镜像全部放内部 SRAM 运行BSP_LINKER_SCRIPT_FLEXSPI_NOR默认代码驻留外部 NOR FlashXIP 执行BSP_LINKER_SCRIPT_FLEXSPI_NOR_HYPERRAMXIP HyperRAM 作附加 RAM同步机制在 rtconfig.py生成工程时先扫 rtconfig.h 里的BSP_LINKER_SCRIPT_*宏选定linker_scripts/下对应的.ld/.scf/.icf再由update_keil_active_target()把 project.uvoptx 的当前 Target 改写成rtthread_ram/rtthread_flexspi_nor/rtthread_flexspi_nor_hyperram。所以只需在 menuconfig 切换选项并重新生成工程Keil Target 自动跟上不用手工改。避坑与延伸现象scons 一跑就报缺 NXP 头文件。原因PKG_USING_NXP_IMXRT_DRIVER还没拉取。解法先在 BSP 目录的 ENV 里执行pkgs --update再编译。现象只下载了一个工程第二个核毫无动静。原因CM33 与 CM7 是两套独立工程、各出各的镜像主核是从容器头部解析从核镜像信息后才启动它的。解法按文档分别编译下载两套工程或用 MCUXpresso Secure Provisioning Tool 生成一份可启动的双核镜像。现象主核 banner 正常怀疑从核挂了其实只是没接对串口。原因两核控制台不同CM33 走 UART1CM7 走 UART12。解法对照两套 rtconfig.h 的RT_CONSOLE_DEVICE_NAME各自接对应串口均按 115200-8-1-N 打开。现象menuconfig 里换了链接布局Keil 编译却还是旧 Target 的产物。原因Target 只在生成工程时同步一次。解法改完配置后重跑scons --targetmdk5重新生成。现象主核日志停在等待 CM7 名称服务广播处不再前进。原因两工程 RPMsg-Lite 参数没对齐link ID、广播字符串或端点地址不一致。解法逐项核对两边 Kconfig 参数注意 CM33 端点 40 与 CM7 端点 30 不同属设计使然不要改一样。写在最后imxrt 家族还有 imxrt1021-nxp-evk、imxrt1052-nxp-evk、imxrt1060-nxp-evk、imxrt1064-nxp-evk、imxrt1170-nxp-evk 等工程外设开关的思路一脉相承可横向对照选型。multicore_thread.c 里的 100 轮 ping-pong 只是演示信道真正做业务时把它换成自己的命令/数据通道即可。更多板级细节直接翻同目录的 README_zh.md。【免费下载链接】rt-threadRT-Thread is an open source IoT Real-Time Operating System (RTOS). https://rt-thread.github.io/rt-thread/项目地址: https://gitcode.com/gh_mirrors/rt/rt-thread创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑