HPM5E3Y Linux GCC 开发环境搭建、编译与烧录指南
HPM5E3Y Linux GCC 开发环境搭建、编译与烧录指南
HPMicro 的 HPM5E3Y 属于 RISC-V MCU。它的开发方式和普通 Linux 应用不同:代码在 Linux 主机上编写和交叉编译,最终生成的固件运行在开发板芯片上。主机负责构建和烧录,开发板负责执行程序。
这篇文章以 HPM5E3Y / HPM5E00EVK 为例,整理一套不依赖 IDE 的 Linux GCC 工作流。核心工具只有四类:HPM SDK、RISC-V GCC、CMake/Ninja 和 HPM patched OpenOCD。只要理解它们之间的关系,后续迁移到其他 HPMicro 板卡、其他示例工程或 CI 环境也会比较直接。
应用范围
- HPM5E3Y / HPM5E00EVK 裸机工程开发
- Linux 下 RISC-V GCC 交叉编译环境搭建
- HPM SDK 的 CMake 构建系统使用
- Flash XIP 固件生成、写入与校验
- CMSIS-DAP 调试器连接和 OpenOCD 烧录
- 自定义 board 目录、OpenOCD 配置目录和工程模板整理
摘要
HPM SDK 提供芯片驱动、启动文件、链接脚本、板级支持包和 CMake 构建规则;RISC-V GCC 负责编译和链接;CMake 负责把应用工程、SDK、板级配置和工具链参数组合成可执行构建;Ninja 执行实际编译;OpenOCD 通过调试器把 demo.elf 写入 Flash,并在烧录完成后复位运行。
本文先建立完整开发链路,再给出可复用的工程目录、环境变量模板、CMake 配置命令、OpenOCD 烧录命令和常见错误排查表。文中的路径采用变量化写法,读者只需要替换 PROJECT_ROOT、HPM_SDK_BASE 和 OPENOCD 等少数关键路径,就可以应用到自己的工程。
关键词
HPM5E3Y、HPM5E00EVK、HPMicro、RISC-V GCC、HPM SDK、CMake、Ninja、OpenOCD、CMSIS-DAP、Flash XIP、嵌入式 Linux 开发
1. 开发链路总览
1.1 主机、工具链和开发板的关系
嵌入式 Linux 开发环境中的“Linux”通常指开发主机,而不是目标芯片运行 Linux。HPM5E3Y 上运行的是交叉编译生成的裸机固件。
这条链路里最容易混淆的是 CMake、Ninja 和 GCC 的职责:
| 工具 | 角色 | 典型输出 |
|---|---|---|
| HPM SDK | 提供芯片、外设、板级和构建规则 | 驱动源码、启动文件、链接脚本、CMake 模块 |
| CMake | 生成构建系统 | build.ninja、缓存变量、编译参数 |
| Ninja | 执行构建 | 对象文件、链接产物 |
| RISC-V GCC | 编译和链接固件 | demo.elf、demo.bin、demo.map |
| OpenOCD | 连接目标芯片并烧录 | Flash 写入、校验、复位运行 |
1.2 推荐工作流
开发过程中通常不需要反复重新配置 CMake。只要 SDK、板级目录、构建类型不变,日常循环就是“改代码、编译、烧录、观察现象”。
1.3 建议工程结构
为了让工程更容易迁移,建议把应用代码、板级覆盖文件、OpenOCD 配置和文档分开。SDK 可以放在工程外部,作为只读依赖使用。
HPM_Project├── app│ └── gpio│ ├── CMakeLists.txt│ └── src│ ├── gpio.c│ ├── oled_ch1115_i2c.c│ └── oled_ch1115_i2c.h├── board│ ├── hpm5e00evk│ │ ├── board.c│ │ ├── board.h│ │ └── CMakeLists.txt│ └── openocd│ ├── boards│ ├── probes│ └── soc├── docs└── README.md| 目录 | 用途 |
|---|---|
app/gpio/src | 应用层源码 |
app/gpio/CMakeLists.txt | 应用工程入口 |
board/hpm5e00evk | 本工程使用的板级文件 |
board/openocd | OpenOCD probe、SoC、board 配置 |
docs | 原理图、接口说明、测试记录 |
把 SDK 放在工程外部有两个好处:第一,工程仓库不会被 SDK 源码污染;第二,升级 SDK 时边界清楚,能更容易判断问题来自应用代码、板级文件还是 SDK 变化。
2. 安装和检查基础工具
2.1 工具清单
Linux 下最少需要安装这些工具:
| 类型 | 工具 | 说明 |
|---|---|---|
| 构建工具 | cmake、ninja | 生成和执行构建 |
| 交叉编译器 | riscv64-elf-gcc | 编译 RISC-V 裸机固件 |
| C 标准库 | riscv64-elf-newlib | 裸机环境常用 C 库 |
| 烧录工具 | HPM patched OpenOCD | 支持 HPM XPI Flash 算法 |
| 调试器 | CMSIS-DAP | 连接主机和开发板 |
在 Arch Linux / AUR 环境中,可以安装:
riscv64-elf-gccriscv64-elf-newlibhpmicro-openocd-binhpmicro-manufacturing-tool-bin其他发行版也可以使用包管理器安装 cmake、ninja 和 RISC-V GCC。OpenOCD 建议使用 HPMicro 提供或打过 HPM patch 的版本。
2.2 检查 CMake 和 Ninja
cmake --versionninja --version两个命令都能输出版本号即可。CMake 版本过旧时,可能会出现 SDK CMake 脚本不兼容的问题,建议使用发行版较新的稳定版本。
2.3 检查 RISC-V GCC
riscv64-elf-gcc --versionwhich riscv64-elf-gcc正常情况下,能看到 GCC 版本和安装路径。若提示找不到命令,说明工具链没有安装,或者工具链目录没有加入 PATH。
HPM SDK 使用工具链时通常还需要知道工具链根目录。若编译器路径是:
/usr/bin/riscv64-elf-gcc那么常见的工具链根目录就是:
/usr2.4 检查 HPM patched OpenOCD
HPM5E3Y 的 Flash 烧录需要支持 HPM Flash 算法的 OpenOCD。示例路径:
/opt/hpmicro/openocd/bin/openocd --version不要误用系统自带的普通 OpenOCD:
/usr/bin/openocd两者差别在烧录阶段非常关键:
| OpenOCD | 可能结果 |
|---|---|
| HPM patched OpenOCD | 能识别 HPM SoC 和 XPI Flash,支持 hpm_xpi Flash driver |
| 普通 OpenOCD | 可能可以启动,但烧录时报 flash driver 'hpm_xpi' not found |
2.5 检查 CMSIS-DAP 连接
开发板上电并连接调试器后执行:
lsusb若使用 CMSIS-DAP,通常能看到类似设备:
0d28:0204 CMSIS-DAP如果没有识别,优先检查:
- USB 线是否支持数据传输
- 开发板是否上电
- 调试器固件是否正常
- Linux 用户是否有 USB 访问权限
- 是否被其他调试软件占用
3. 环境变量和路径规划
3.1 使用变量替代硬编码路径
教程里最不建议直接复制的是绝对路径。更稳妥的方式是先定义几组变量,再在命令中引用它们。
export PROJECT_ROOT="$HOME/Projects/HPM_Project"export HPM_SDK_BASE="$HOME/Projects/sdk_env_v1.11.0/hpm_sdk"export GNURISCV_TOOLCHAIN_PATH="/usr"export HPM_SDK_TOOLCHAIN_VARIANT="gcc"export OPENOCD="/opt/hpmicro/openocd/bin/openocd"export BOARD="hpm5e00evk"export BOARD_SEARCH_PATH="$PROJECT_ROOT/board"这些变量的含义如下:
| 变量 | 含义 |
|---|---|
PROJECT_ROOT | 当前应用工程根目录 |
HPM_SDK_BASE | HPM SDK 根目录 |
GNURISCV_TOOLCHAIN_PATH | RISC-V GCC 工具链根目录 |
HPM_SDK_TOOLCHAIN_VARIANT | HPM SDK 工具链类型,GCC 环境设为 gcc |
OPENOCD | HPM patched OpenOCD 可执行文件 |
BOARD | 使用的板级配置名称 |
BOARD_SEARCH_PATH | 自定义 board 搜索目录 |
3.2 检查变量是否生效
echo "$PROJECT_ROOT"echo "$HPM_SDK_BASE"echo "$GNURISCV_TOOLCHAIN_PATH"echo "$HPM_SDK_TOOLCHAIN_VARIANT"echo "$OPENOCD"可以进一步检查关键目录和程序是否存在:
test -d "$PROJECT_ROOT" && echo "PROJECT_ROOT OK"test -d "$HPM_SDK_BASE" && echo "HPM_SDK_BASE OK"test -x "$OPENOCD" && echo "OPENOCD OK"若这些变量每次开新终端都需要使用,可以写入 ~/.bashrc、~/.zshrc 或其他 shell 配置文件。
3.3 构建目录命名建议
构建目录建议包含板卡、运行位置、构建类型和工具链信息。例如:
export BUILD_DIR="$PROJECT_ROOT/app/gpio/build/${BOARD}_flash_xip_debug_gcc"这样的命名比简单的 build 更清楚,尤其适合同时维护多个构建配置。
| 构建目录字段 | 示例 | 说明 |
|---|---|---|
| 板卡 | hpm5e00evk | 当前 board |
| 运行方式 | flash_xip | 从 Flash XIP 运行 |
| 构建类型 | debug | Debug 或 Release |
| 工具链 | gcc | GCC、SEGGER、LLVM 等 |
4. CMake 配置和 Ninja 编译
4.1 关键 CMake 参数
HPM SDK 工程的 CMake 配置参数比普通桌面工程更多,因为它需要同时描述板卡、工具链、运行位置和 RISC-V ABI。
| 参数 | 示例 | 说明 |
|---|---|---|
BOARD | hpm5e00evk | 使用哪个 board |
BOARD_SEARCH_PATH | $PROJECT_ROOT/board | 优先搜索本工程 board |
CUSTOM_TARGET_TRIPLET | riscv64-elf | GCC 前缀 |
HPM_BUILD_TYPE | flash_xip | 固件运行位置 |
CMAKE_BUILD_TYPE | debug | Debug/Release |
RV_ARCH | rv32imac_zicsr_zifencei | RISC-V ISA |
RV_ABI | ilp32 | RISC-V ABI |
OPENOCD | $OPENOCD | 烧录工具路径 |
这几个参数里,最容易出错的是 RV_ARCH、RV_ABI 和 HPM_BUILD_TYPE。它们会影响编译参数、链接脚本和启动方式。初学阶段建议先使用 SDK 示例或官方 board 已验证的组合。
4.2 生成构建文件
进入工程根目录:
cd "$PROJECT_ROOT"执行 CMake 配置:
cmake -S app/gpio \ -B "$BUILD_DIR" \ -G Ninja \ -DBOARD="$BOARD" \ -DBOARD_SEARCH_PATH="$BOARD_SEARCH_PATH" \ -DCUSTOM_TARGET_TRIPLET=riscv64-elf \ -DCMAKE_BUILD_TYPE=debug \ -DHPM_BUILD_TYPE=flash_xip \ -DRV_ARCH=rv32imac_zicsr_zifencei \ -DRV_ABI=ilp32 \ -DUSE_CCACHE=0 \ -DOPENOCD="$OPENOCD"配置成功时,通常会看到类似信息:
-- Application: .../app/gpio-- Board (custom board): hpm5e00evk from .../board-- Found toolchain: gnu (/usr)-- hpm_sdk: 1.11.0 (.../hpm_sdk)-- Configuring done-- Generating done-- Build files have been written to: ...可以把这段输出看成一次构建体检:
| 输出项 | 应检查内容 |
|---|---|
Application | 是否指向当前应用目录 |
Board | 是否使用了预期 board |
Found toolchain | 是否找到 GCC |
hpm_sdk | 是否使用了预期 SDK |
Build files | 是否写入正确构建目录 |
4.3 执行编译
cmake --build "$BUILD_DIR"编译成功后,输出目录通常位于:
$BUILD_DIR/output检查输出文件:
ls "$BUILD_DIR/output"常见产物如下:
| 文件 | 用途 |
|---|---|
demo.elf | 带符号信息的 ELF 文件,OpenOCD 烧录和调试常用 |
demo.bin | 裸二进制镜像,适合某些量产或下载工具 |
demo.map | 链接映射文件,用于分析符号和内存占用 |
demo.asm | 反汇编文件,用于底层调试 |
4.4 理解内存占用输出
编译结束时通常会显示类似内存用量:
Memory region Used Size Region Size %age UsedFLASH: ...ILM: ...DLM: ...AXI_SRAM: ...这些信息不只是“编译成功提示”,还可以用于判断固件是否接近资源上限。
| 区域 | 常见含义 |
|---|---|
FLASH | 程序代码、只读数据、XIP 镜像 |
ILM | 指令本地存储,适合放关键代码 |
DLM | 数据本地存储,适合放低延迟数据 |
AXI_SRAM | 片上 SRAM,容量通常更大 |
如果 FLASH 或 SRAM 占用异常,应优先查看 demo.map,而不是只看 C 源码大小。
4.5 重新配置和增量编译
修改普通源文件后,只需要:
cmake --build "$BUILD_DIR"以下情况建议清理或新建构建目录:
- 更换 HPM SDK 版本
- 更换 board
- 更换
HPM_BUILD_TYPE - 更换 RISC-V ABI 或架构参数
- CMake 缓存中出现难以解释的路径残留
清理示例:
rm -rf "$BUILD_DIR"然后重新执行 CMake 配置。
5. OpenOCD 烧录和运行
5.1 OpenOCD 配置文件组成
一个完整的 OpenOCD 连接通常由三类配置组成:
以 CMSIS-DAP + HPM5E00EVK 为例:
| 配置文件 | 作用 |
|---|---|
probes/cmsis_dap.cfg | 指定调试器类型 |
soc/hpm5e00.cfg | 指定 SoC 和 target |
boards/hpm5e00evk.cfg | 指定板级 Flash 和初始化配置 |
如果调试器是 CMSIS-DAP,就不要误用 FT2232/FTDI 配置。探针配置错误时,OpenOCD 往往会在连接阶段就失败。
5.2 手动烧录命令
建议先把 OpenOCD 搜索路径和固件路径定义成变量:
export OPENOCD_SCRIPTS="$PROJECT_ROOT/board/openocd"export FIRMWARE_ELF="$BUILD_DIR/output/demo.elf"烧录命令:
"$OPENOCD" \ -s "$OPENOCD_SCRIPTS" \ -f probes/cmsis_dap.cfg \ -f soc/hpm5e00.cfg \ -f boards/hpm5e00evk.cfg \ -c "init; halt; init_clock; flash probe 0; flash write_image erase $FIRMWARE_ELF; verify_image $FIRMWARE_ELF; reset run; shutdown"这条命令可以拆成几步理解:
| 片段 | 作用 |
|---|---|
-s "$OPENOCD_SCRIPTS" | 指定 OpenOCD 配置搜索目录 |
-f probes/cmsis_dap.cfg | 加载 CMSIS-DAP 配置 |
-f soc/hpm5e00.cfg | 加载 SoC 配置 |
-f boards/hpm5e00evk.cfg | 加载板级配置 |
init; halt | 初始化连接并暂停 CPU |
init_clock | 初始化烧录所需时钟 |
flash probe 0 | 探测 Flash |
flash write_image erase | 擦除并写入固件 |
verify_image | 校验写入内容 |
reset run | 复位并运行 |
shutdown | 退出 OpenOCD |
5.3 烧录成功的典型输出
连接成功时常见输出包括:
Using CMSIS-DAPv2 interface with VID:PID=0x0d28:0x0204JTAG tap: hpm5e00.cpu tap/device found: 0x1000563d[hpm5e00.cpu0] Target successfully examined.clocks has been enabled!写入成功时会看到擦除、写入、校验相关信息。最终执行 reset run 后,开发板会从新固件启动。
5.4 用 alias 或脚本减少重复输入
手动命令适合验证流程,但日常开发不适合反复输入长命令。可以在 shell 中定义一个函数:
hpm_flash() { "$OPENOCD" \ -s "$OPENOCD_SCRIPTS" \ -f probes/cmsis_dap.cfg \ -f soc/hpm5e00.cfg \ -f boards/hpm5e00evk.cfg \ -c "init; halt; init_clock; flash probe 0; flash write_image erase $FIRMWARE_ELF; verify_image $FIRMWARE_ELF; reset run; shutdown"}之后只需要:
hpm_flash工程团队中更推荐把这类命令写入 Makefile、CMakePresets.json、justfile 或项目脚本中,避免每个人维护一份略有差异的本地 alias。
6. OLED I2C 示例验证
6.1 硬件连接
假设工程中包含 CH1115 OLED I2C 示例,且 OLED 接在 I2C2:
I2C2.SCL -> PD02I2C2.SDA -> PD03连接关系如下:
┌────────────────────┐ ┌────────────────────┐│ HPM5E3Y │ │ CH1115 OLED ││ │ │ ││ PD02 / I2C2.SCL ├──────────>│ SCL ││ PD03 / I2C2.SDA ├──────────>│ SDA ││ 3.3V ├──────────>│ VDD ││ GND ├──────────>│ VSS │└────────────────────┘ └────────────────────┘6.2 软件文件
示例相关文件:
app/gpio/src/oled_ch1115_i2c.capp/gpio/src/oled_ch1115_i2c.happ/gpio/src/gpio.c程序启动后会初始化 I2C2,并在屏幕上显示类似内容:
HPM5E3YI2C2 OK6.3 验证路径
OLED 不亮时,不要直接怀疑驱动代码。建议按链路逐段验证:
常见检查项:
| 检查项 | 说明 |
|---|---|
| 固件是否更新 | 旧固件仍在运行时,外设现象会误导排查 |
| OLED 是否为 IIC 版本 | SPI 版本屏幕不能直接套 I2C 驱动 |
| I2C 地址 | 常见为 0x3c,但模块可能不同 |
| SCL/SDA 连接 | 与 pinmux 和板级文件一致 |
| 上拉电阻 | I2C 总线需要合适上拉 |
| RES#/CS/A0/IM | 某些模块需要固定电平进入 I2C 模式 |
7. 常见问题排查
7.1 快速定位表
| 现象 | 可能原因 | 处理方法 |
|---|---|---|
HPM_SDK_BASE is not set yet | 没有设置 SDK 路径 | export HPM_SDK_BASE=... 后重新配置 |
riscv64-elf-gcc: command not found | GCC 未安装或不在 PATH | 安装工具链,检查 which riscv64-elf-gcc |
| CMake 找到错误 board | BOARD_SEARCH_PATH 不正确 | 确认指向工程内 board 目录 |
flash driver 'hpm_xpi' not found | 使用普通 OpenOCD | 改用 HPM patched OpenOCD |
| 无法打开 FTDI | probe 配置错误 | CMSIS-DAP 应使用 probes/cmsis_dap.cfg |
Unable to halt | reset/halt 阶段未能暂停 CPU | 若写入和校验成功,且 reset run 后程序能运行,可结合具体日志判断 |
| 烧录后现象不变 | 烧录的不是当前 demo.elf | 检查 FIRMWARE_ELF 和构建目录 |
| OLED 不亮 | 接线、地址、供电或 pinmux 错误 | 按 6.3 的链路逐项检查 |
7.2 HPM_SDK_BASE is not set yet
报错示例:
HPM_SDK_BASE is not set yet解决方法:
export HPM_SDK_BASE="$HOME/Projects/sdk_env_v1.11.0/hpm_sdk"export GNURISCV_TOOLCHAIN_PATH="/usr"export HPM_SDK_TOOLCHAIN_VARIANT="gcc"然后重新执行 CMake 配置。注意,已经生成过的构建目录可能缓存了旧路径,必要时删除 BUILD_DIR 后重新配置。
7.3 flash driver 'hpm_xpi' not found
这通常表示 OpenOCD 版本不对。检查当前 OpenOCD:
which openocdopenocd --version"$OPENOCD" --version烧录命令中应显式使用 HPM patched OpenOCD,例如:
/opt/hpmicro/openocd/bin/openocd --version不要依赖 PATH 中排在前面的 /usr/bin/openocd。
7.4 CMake 配置成功但编译失败
常见原因包括:
- 应用
CMakeLists.txt没有正确添加源文件 - board 文件与芯片型号不匹配
RV_ARCH/RV_ABI与工程要求不一致- SDK 版本和示例代码不匹配
- 本地 board 覆盖了 SDK 默认 board,但文件不完整
建议先确认 SDK 自带同类示例是否能编译,再对比自己的工程差异。
7.5 烧录成功但程序不运行
优先检查以下项目:
| 检查项 | 说明 |
|---|---|
HPM_BUILD_TYPE | 是否为目标板支持的启动方式 |
| 链接脚本 | Flash/RAM 地址是否正确 |
reset run | 烧录命令是否执行复位运行 |
| 启动模式 | Boot pin 或板上拨码是否正确 |
| 时钟初始化 | board 配置是否完成必要时钟初始化 |
| 外设 pinmux | 程序现象依赖的外设引脚是否配置正确 |
8. 迁移到其他 HPM 工程
8.1 需要替换的参数
把本文流程迁移到其他 HPMicro 工程时,通常只需要替换这些内容:
| 项目 | 当前示例 | 迁移时修改 |
|---|---|---|
PROJECT_ROOT | HPM_Project | 新工程根目录 |
BOARD | hpm5e00evk | 新开发板名称 |
BOARD_SEARCH_PATH | $PROJECT_ROOT/board | 新 board 目录 |
HPM_SDK_BASE | SDK v1.11.0 | 实际 SDK 路径 |
OPENOCD_SCRIPTS | $PROJECT_ROOT/board/openocd | 实际 OpenOCD 配置目录 |
RV_ARCH / RV_ABI | rv32imac_zicsr_zifencei / ilp32 | 目标芯片要求 |
HPM_BUILD_TYPE | flash_xip | Flash、RAM 或其他启动方式 |
8.2 推荐先跑 SDK 官方示例
迁移时不要一开始就把所有自定义代码放进去。更稳妥的顺序是:
这样做的好处是每一步都有明确边界。一旦出错,可以快速判断是工具链、SDK、board、OpenOCD 还是应用代码的问题。
8.3 最小成功检查表
环境是否真正跑通,可以用下面的检查表确认:
| 序号 | 检查命令或动作 | 成功标准 |
|---|---|---|
| 1 | lsusb | 能看到 CMSIS-DAP |
| 2 | riscv64-elf-gcc --version | 能看到 GCC 版本 |
| 3 | "$OPENOCD" --version | 能看到 HPM patched OpenOCD 版本 |
| 4 | echo "$HPM_SDK_BASE" | 指向实际 SDK |
| 5 | CMake 配置 | 生成 build.ninja |
| 6 | cmake --build "$BUILD_DIR" | 生成 demo.elf |
| 7 | OpenOCD 烧录 | 写入和校验成功 |
| 8 | reset run | 开发板运行新固件 |
只要这八项都通过,Linux 下 HPM5E3Y GCC 开发环境就已经具备可持续开发能力。后续工作重点就从“环境是否能跑”转移到 board 配置、驱动质量、外设验证和应用逻辑本身。
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!