You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于CMake实现STM32双核心项目的跨核心启动调试?

解决STM32H757I-Eval双核项目在Visual Studio中通过CMake复现跨核心启动逻辑的方案

核心思路调整

放弃将CM4设为库并静态链接到CM7的方案——这种方式会把CM4代码合并到CM7固件中,不符合双核独立执行的原生逻辑。正确的做法是:

  • 单独编译CM4生成独立的二进制镜像(.bin/.hex)
  • 让CM7在启动阶段将CM4镜像加载到其专属内存区域,再触发CM4启动
  • 通过CMake构建流程建立CM7对CM4产物的依赖,同时在调试配置中复现CubeIDE的跨核心加载逻辑

具体CMake配置步骤

1. 根目录CMakeLists.txt组织项目

用add_subdirectory分别引入CM4和CM7子项目,明确构建依赖关系:

cmake_minimum_required(VERSION 3.20)
project(STM32H7_DualCore_Project)

# 引入CM4子项目,指定构建目录
add_subdirectory(CM4 ${CMAKE_BINARY_DIR}/CM4)
# 引入CM7子项目,依赖CM4构建完成
add_subdirectory(CM7 ${CMAKE_BINARY_DIR}/CM7)
add_dependencies(CM7_Project CM4_Project)

2. CM4子项目配置:生成独立二进制镜像

将CM4设为可执行目标,编译后用arm-none-eabi-objcopy生成.bin文件,供CM7使用:

# CM4/CMakeLists.txt
add_executable(CM4_Project ${CM4_SOURCES} ${CM4_INCLUDES})
target_link_libraries(CM4_Project ${CM4_LIBRARIES})

# 生成CM4二进制镜像
add_custom_command(TARGET CM4_Project POST_BUILD
    COMMAND ${CMAKE_OBJCOPY} -O binary $<TARGET_FILE:CM4_Project> ${CMAKE_CURRENT_BINARY_DIR}/CM4_Project.bin
    COMMAND ${CMAKE_OBJCOPY} -O ihex $<TARGET_FILE:CM4_Project> ${CMAKE_CURRENT_BINARY_DIR}/CM4_Project.hex
    COMMENT "Generating CM4 bin/hex images"
)

# 为CM4指定专属工具链参数
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mcortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -T${CMAKE_CURRENT_SOURCE_DIR}/STM32H757IITX_CM4.ld")

3. CM7子项目配置:嵌入CM4镜像并添加启动逻辑

将CM4的.bin文件转换为C头文件嵌入CM7项目,同时在CM7代码中实现CM4的加载与启动逻辑:

# CM7/CMakeLists.txt
add_executable(CM7_Project ${CM7_SOURCES} ${CM7_INCLUDES})
target_link_libraries(CM7_Project ${CM7_LIBRARIES})

# 将CM4 bin文件转为C头文件,方便嵌入
set(CM4_BIN_PATH ${CMAKE_SOURCE_DIR}/CM4/build/CM4_Project.bin)
add_custom_command(OUTPUT cm4_bin.c
    COMMAND xxd -i ${CM4_BIN_PATH} cm4_bin.c
    DEPENDS ${CM4_BIN_PATH}
    COMMENT "Generating CM4 bin header file"
)
target_sources(CM7_Project PRIVATE cm4_bin.c)

# 为CM7指定专属工具链参数
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mcortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -T${CMAKE_CURRENT_SOURCE_DIR}/STM32H757IITX_CM7.ld")

在CM7的启动代码或初始化函数中添加CM4启动逻辑:

#include "cm4_bin.h"
#include "stm32h7xx_hal.h"

void launch_cm4(void) {
    // 1. 使能CM4时钟
    __HAL_RCC_CM4_CLK_ENABLE();
    
    // 2. 将CM4镜像复制到其专属Flash起始地址(0x8000000)
    memcpy((void*)0x8000000, cm4_bin, cm4_bin_len);
    
    // 3. 设置CM4的向量表偏移
    *((volatile uint32_t*)0xE00ED008) = 0x8000000;
    
    // 4. 触发CM4启动:设置栈顶指针,跳转至复位向量
    __DSB();
    __ISB();
    ((void (*)(void))(*((volatile uint32_t*)0x8000004)))();
}

4. 工具链模块调整

修改gcc-arm-none-eabi.cmake和st-project.cmake,支持按子项目区分核心配置:

  • 在子项目中通过set覆盖全局的CMAKE_C_FLAGS、CMAKE_EXE_LINKER_FLAGS等参数,确保CM4和CM7使用各自的CPU架构、FPU配置和链接脚本

复现跨核心调试配置

在Visual Studio中创建launch.json,配合OpenOCD实现类似CubeIDE的跨核心调试:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "STM32H7 Dual Core Debug",
            "type": "cppvsdbg",
            "request": "launch",
            "program": "${workspaceFolder}/CM7/build/CM7_Project.elf",
            "stopAtEntry": true,
            "cwd": "${workspaceFolder}",
            "MIMode": "gdb",
            "miDebuggerPath": "${env:ARM_GCC_PATH}/bin/arm-none-eabi-gdb.exe",
            "setupCommands": [
                {"text": "target extended-remote localhost:3333"},
                {"text": "monitor reset halt"},
                {"text": "load ${workspaceFolder}/CM7/build/CM7_Project.elf"},
                {"text": "load ${workspaceFolder}/CM4/build/CM4_Project.elf 0x8000000"},
                {"text": "monitor arm7 semihosting enable"},
                {"text": "monitor arm4 semihosting enable"},
                {"text": "break launch_cm4"},
                {"text": "continue"}
            ],
            "preLaunchTask": "Build All",
            "postDebugTask": "Stop OpenOCD"
        }
    ]
}

同时配置tasks.json启动/停止OpenOCD:

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "Start OpenOCD",
            "type": "shell",
            "command": "${env:OPENOCD_PATH}/bin/openocd.exe -f interface/stlink.cfg -f target/stm32h7x.cfg",
            "isBackground": true,
            "problemMatcher": {
                "pattern": {
                    "regexp": "."
                },
                "background": {
                    "activeOnStart": true,
                    "beginsPattern": "Info : Listening on port 3333 for gdb connections",
                    "endsPattern": "."
                }
            }
        },
        {
            "label": "Stop OpenOCD",
            "type": "shell",
            "command": "taskkill /f /im openocd.exe"
        },
        {
            "label": "Build All",
            "dependsOn": [
                "Start OpenOCD",
                "Build CM4",
                "Build CM7"
            ]
        }
    ]
}

关键注意事项

  • 确保CM4和CM7的链接脚本内存布局无重叠,CM4默认使用0x8000000起始的Flash区域,CM7使用0x08020000及以上区域(根据板卡Flash大小调整)
  • 调试时使用最新版本的OpenOCD,确保支持STM32H7的双核调试
  • 启动CM4前必须完成时钟使能和向量表配置,否则CM4无法正常运行

内容的提问来源于stack exchange,提问作者Kelv

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 16:32:54