ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

先楫 HPM6E8Y开发环境的搭建(二)

2026/8/6 18:16:06 拓冰建站 浏览量
先楫 HPM6E8Y开发环境的搭建(二)

摘要

本文围绕 HPMicro HPM6E8Y 自定义开发板的基础开发流程,系统整理了一个已在 Segger Embedded Studio(SES)中成功运行的 LED 闪烁工程,从 RAM 调试模式迁移至外部 QSPI NOR Flash 的完整过程。工程初始状态下,程序能够在 RAM 模式中正常编译、下载和运行,但切换至flash_xip构建类型后,先后出现链接脚本参数未定义、SES 工程未生成、Flash 下载阶段卡死等问题。通过检查自定义开发板 YAML 文件的层级结构、清理旧构建目录、补充 OpenOCD 板级 CFG 文件中的 XPI Flash 描述与复位初始化逻辑,最终实现了程序的正常烧写、调试和断电后独立启动。

本文进一步分析了hpm_led.cfgflash bankreset-initgdb-attach等配置项的作用,并说明了 YAML、CFG、链接脚本和 BootROM Flash 配置之间的关系。该过程可作为 HPM6E8Y 自定义开发板从最小 GPIO 验证向定时器、PWM、ADC 及电机控制开发过渡的基础参考。

关键词:HPM6E8Y;Segger Embedded Studio;OpenOCD;Flash XIP;QSPI NOR Flash;自定义开发板;HPM SDK

1. 引言

在 HPM6E8Y 自定义开发板的早期验证阶段,RAM 调试通常是最简单且最直接的方式。程序通过调试器下载到片内 RAM 后即可运行,适合验证:

  • MCU 与调试器之间的 JTAG 连接;
  • 时钟初始化;
  • GPIO 引脚复用;
  • 基础代码结构;
  • LED 等简单外设功能。
    然而,RAM 中的程序在断电后会丢失,无法实现独立启动。因此,在完成基础硬件验证后,需要将工程迁移到外部 QSPI NOR Flash,并使用 XIP(Execute In Place)方式运行。
    本次工程的最终目标为:
  1. 保留已经成功运行的 SES LED 闪烁工程;
  2. 将构建类型从ram切换至flash_xip
  3. 将程序烧写到 16 MiB 外部 QSPI NOR Flash;
  4. BOOT0=0、BOOT1=0的实际板级配置下,实现断电重新上电后 LED 自动闪烁。

2. 实验平台与工程基础

本次实验使用的主要硬件条件如下:

项目配置
主控 MCUHPMicro HPM6E8Y
SoC 配置HPM6E80
外部 Flash16 MiB QSPI NOR Flash
Flash 类型qspi-nor-flash
外部 RAM32 MiB SDRAM
调试器FT2232
调试接口JTAG
LED 引脚PA9
启动电平BOOT0=0,BOOT1=0

2.2 软件环境

项目配置
HPM SDK Envv1.12.1
IDESegger Embedded Studio
调试服务OpenOCD
构建系统CMake + Ninja
RAM 构建类型ram
Flash 构建类型flash_xip

2.3 初始工程状态

在迁移前,工程已经满足以下条件:

  • SES 工程能够正常打开;
  • LED_B 对应 PA9;
  • 程序在 RAM 模式下能够正常运行;
  • LED 每 500 ms 翻转一次;
  • JTAG 下载和单步调试均正常。

因此,后续问题可以明确限定在:

外部 Flash 的链接、烧写和启动链路,而不是 GPIO、时钟或主程序逻辑本身。

3. RAM 模式与 Flash XIP 模式的区别

3.1 RAM 调试模式

RAM 模式的基本流程为:

SES / GDB ↓ OpenOCD ↓ JTAG ↓ 程序直接写入片内 RAM ↓ CPU 从 RAM 执行

其特点是:

  • 下载速度快;
  • 调试方便;
  • 不依赖外部 Flash;
  • 断电后程序丢失;
  • 不适合作为最终产品运行方式。

3.2 Flash XIP 模式

程序链接到 0x80000000 ↓ OpenOCD 通过 XPI 控制器访问外部 Flash ↓ 擦除、写入并校验程序 ↓ MCU 上电后由 BootROM 初始化 Flash ↓ CPU 直接从外部 Flash 映射区取指运行

与 RAM 模式相比,Flash XIP 模式额外依赖:

  • 外部 Flash 容量配置;
  • XPI 控制器配置;
  • OpenOCD Flash 驱动;
  • 板级 CFG 文件;
  • BootROM 能识别的 NOR Flash 配置;
  • 正确的启动模式。

4. 从 RAM 工程切换到 Flash XIP 工程

4.1 修改YAML配置文件

向YAML配置文件添加如下内容:

board:name:hpm_ledsoc:HPM6E80device:HPM6E80xGNxopenocd-soc:hpm6e80-single-coreopenocd-probe:ft2232on-board-ram:type:sdramsize:32Mwidth:16biton-board-flash:type:qspi-nor-flashsize:16M

4.2 YAML 的作用

  • HPM SDK 项目生成工具;
  • CMake;
  • 链接脚本生成;
  • 板级资源识别;
  • OpenOCD 配置文件选择。
    其中:
on-board-flash:type:qspi-nor-flashsize:16M

用于告诉构建系统:

  • 该开发板存在外部 QSPI NOR Flash;
  • 可用容量为 16 MiB;
  • 链接脚本可以为flash_xip工程分配对应的地址空间。

2. OpenOCD CFG 文件配置

最终使用的hpm_led.cfg内容如下:

# Copyright (c) 2024 HPMicro # SPDX-License-Identifier: BSD-3-Clause # HPM6E8Y custom board # External QSPI NOR Flash: # Device: MX25L12833F # Capacity: 16 MiB # XPI controller: XPI0 # XIP base address: 0x80000000 flash bank xpi0 hpm_xpi 0x80000000 0x01000000 1 1 $_TARGET0 0xF3000000 0x7 proc init_clock {} { mww 0xF4000800 0xFFFFFFFF mww 0xF4000810 0xFFFFFFFF mww 0xF4000820 0xFFFFFFFF mww 0xF4000830 0xFFFFFFFF echo "clocks has been enabled!" } $_TARGET0 configure -event reset-init { init_clock } $_TARGET0 configure -event gdb-attach { reset halt }

3. CFG 文件逐项分析

3.1flash bank命令

核心配置为:

flash bank xpi0 hpm_xpi 0x80000000 0x01000000 1 1 $_TARGET0 0xF3000000 0x7

该命令用于向 OpenOCD 声明一个可编程的外部 Flash Bank。
其通用结构可以理解为:

flash bank <名称> <驱动> <映射地址> <容量> <芯片宽度> <总线宽度> <目标CPU> <控制器参数> <Flash配置参数>

各字段含义如下:

3.1.1xpi0
xpi0

表示 OpenOCD 内部的 Flash Bank 名称。

它只是该 Flash 设备在 OpenOCD 中的逻辑名称,不是寄存器名。

3.1.2hpm_xpi
hpm_xpi

表示使用 HPMicro 提供的 XPI Flash 驱动。

该驱动负责通过 HPM6E8Y 的 XPI 控制器访问外部 QSPI NOR Flash。

3.1.30x80000000
0x80000000

表示外部 Flash 的 XIP 映射基地址。

flash_xip工程中,程序代码会被链接到该地址附近,CPU 可以直接从该映射区域取指执行。

3.1.40x01000000
0x01000000

表示 Flash 容量为 16 MiB。

3.1.51 1
1 1

这是 OpenOCDflash bank命令中的芯片宽度和总线宽度参数。

3.1.6$_TARGET0
$_TARGET0

表示 HPM6E80 单核 OpenOCD 配置中创建的 CPU 调试目标。

3.1.70xF3000000
0xF3000000

用于告诉hpm_xpi驱动当前访问的是 HPM6E8Y 的 XPI0 控制器。

3.1.80x7
0x7

该值是传递给 HPM XPI Flash 驱动的 Flash 配置选项。

在当前工程中,它用于配合 SFDP 方式识别和初始化 Flash,并与 BootROM 侧的 NOR Flash 配置保持一致。

3.2init_clock函数

CFG 中定义了:

proc init_clock {} { mww 0xF4000800 0xFFFFFFFF mww 0xF4000810 0xFFFFFFFF mww 0xF4000820 0xFFFFFFFF mww 0xF4000830 0xFFFFFFFF echo "clocks has been enabled!" }

其中:

proc

表示定义 Tcl 函数。

而:

mww

表示向目标 MCU 地址写入一个 32 位数据,可理解为:

*(volatileuint32_t*)address=value;

这四条写操作用于在 OpenOCD 复位初始化阶段打开 Flash 下载算法所需的相关时钟。

最后:

echo "clocks has been enabled!"

仅用于在 OpenOCD 日志中输出提示,不影响硬件功能。

3.3reset-init事件

$_TARGET0 configure -event reset-init { init_clock }

其含义为:

当 OpenOCD 执行目标复位初始化时,自动调用init_clock

流程如下:

OpenOCD 复位 MCU ↓ 触发 reset-init ↓ 执行 init_clock ↓ 打开相关时钟 ↓ 准备执行 Flash 擦写算法

3.4gdb-attach事件

$_TARGET0 configure -event gdb-attach { reset halt }

其含义为:

当 SES 中的 GDB 连接到 OpenOCD 时,立即复位并暂停 CPU。

流程如下:

SES 启动调试 ↓ GDB 连接 OpenOCD ↓ 触发 gdb-attach ↓ 执行 reset halt ↓ CPU 复位并停住 ↓ 开始擦除、下载和调试

这可以避免 Flash 中旧程序继续运行并干扰调试器接管。

4. YAML、CFG、链接脚本与 BootROM 的协同关系

整个 Flash XIP 启动流程涉及多个不同层级的文件。

4.1 YAML 文件

hpm_led.yaml面向:

  • 项目生成工具;
  • CMake;
  • 构建类型筛选;
  • 链接脚本生成;
  • 板载存储容量识别。

其作用是:

告诉构建系统“程序应该如何链接”

4.2 CFG 文件

hpm_led.cfg面向:

  • OpenOCD;
  • SES;
  • GDB;
  • 外部 Flash 擦除和下载。

其作用是:

告诉调试器“程序应该如何写入 Flash”

4.4 完整链路

hpm_led.yaml ↓ 生成 flash_xip 链接布局 ↓ 程序被链接到 0x80000000 ↓ hpm_led.cfg ↓ OpenOCD 通过 XPI0 擦除并写入外部 Flash ↓ MCU 断电重新上电 ↓ BootROM 根据启动模式和 NOR 配置初始化 Flash ↓ CPU 从 0x80000000 对应区域取指 ↓ LED 程序独立运行

6. Flash XIP 工程生成与下载

6.1 选择构建类型

在 HPM SDK 项目生成工具中,将构建类型从:

ram

修改为:

flash_xip

编译类型继续保持:

debug

新的工程输出目录应类似:

D:\HPW\workspace\hpm_led\user_app\hpm_led_flash_xip_debug

而原 RAM 工程目录为:

D:\HPW\workspace\hpm_led\user_app\hpm_led_ram_debug

两个目录必须分开保留,不能相互覆盖。

6.2 进行生成后,打开IDE


编译后进行下载运行,开发板上灯按照500ms间隔闪烁。配置成功。