Zig 工具链编译 STM32 开发指南

Zig 工具链编译 STM32 开发指南

参考仓库 :ZigEmbeddedGroup/stmicro-stm32

本项目为 STM32 提供 Zig 嵌入式开发支持,全程使用 Zig 原生工具链,无需额外安装 ARM GCC 交叉编译器。

目录

  1. 环境准备
  2. [仓库与 build.zig 简介](#仓库与 build.zig 简介)
  3. 编译官方示例工程
  4. 固件烧录(ST-Link)
  5. [基于 build.zig 创建自定义工程](#基于 build.zig 创建自定义工程)
  6. [调试:OpenOCD + Zig GDB](#调试:OpenOCD + Zig GDB)
  7. 常见问题
  8. 参考资料

1. 环境准备

1.1 安装 Zig

访问 Zig 官网下载对应操作系统的 Zig 二进制包,推荐使用仓库兼容的稳定版本。

Zig 内置交叉编译能力,不需要单独安装 arm-none-eabi-gcc。

验证安装:

bash 复制代码
zig version

1.2 克隆 stmicro-stm32 仓库

bash 复制代码
git clone https://github.com/ZigEmbeddedGroup/stmicro-stm32.git
cd stmicro-stm32

仓库目录结构:

text 复制代码
stmicro-stm32/
├── build.zig           # 核心构建脚本
├── build.zig.zon       # 依赖清单
├── src/                # 芯片寄存器定义、启动文件、底层支持
├── examples/           # 示例项目(blink 点灯等)
└── README.md

2. 仓库与 build.zig 简介

build.zig 是 Zig 的构建脚本,作用等同于 C/C++ 开发中的 CMakeLists.txt 或 Makefile。仓库内 build.zig 主要完成以下工作:

  • 定义嵌入式目标架构 :ARM Cortex-M(thumbv7m-none-eabi)
  • 加载链接脚本 :引入 .ld 文件,配置 Flash、RAM 内存地址布局
  • 引入底层文件:加载芯片启动汇编文件、寄存器定义
  • 设置编译选项:配置无标准库(freestanding)、优化等级、链接垃圾回收
  • 自动生成固件 :输出 .elf 和 .bin 文件

注意:嵌入式环境为 freestanding,不依赖 libc。


3. 编译官方示例工程

bash 复制代码
# 指定示例 blink + 指定芯片 stm32f103c8t6
zig build -Dexample=blink -Dchip=stm32f103c8t6

参数说明:

  • -Dexample=xxx:选择 examples/ 目录下的示例名称
  • -Dchip=xxx:指定 STM32 芯片型号

3.2 编译产物说明

编译输出目录位于 zig-out/firmware/:

  • firmware.elf:带调试信息的 ELF 文件,用于 GDB 调试
  • firmware.bin:纯二进制固件,用于烧录到芯片 Flash

查看产物命令:

bash 复制代码
ls zig-out/firmware/

4. 固件烧录(ST-Link)

安装 stlink 工具集后,使用 st-flash 进行烧录。

bash 复制代码
# 将 bin 固件烧录到 STM32 Flash 起始地址 0x08000000
st-flash write zig-out/firmware/firmware.bin 0x8000000

# 复位芯片,运行程序
st-flash reset

备选方案:也可以使用 OpenOCD 进行烧录。


5. 基于 build.zig 创建自定义工程

新建工程最简 build.zig 模板如下:

zig 复制代码
const std = @import("std");

pub fn build(b: *std.Build) void {
    // 嵌入式目标配置 Cortex-M3
    const target = b.standardTargetOptions(.{
        .default_target = .{
            .cpu_arch = .thumb,
            .cpu_model = .{ .explicit = &std.Target.arm.cpu.cortex_m3 },
            .os = .freestanding,
            .abi = .eabi,
        },
    });
    const optimize = b.standardOptimizeOption(.{ .default = .ReleaseSmall });

    // 创建可执行固件
    const exe = b.addExecutable(.{
        .name = "my_firmware",
        .root_source_file = b.path("src/main.zig"),
        .target = target,
        .optimize = optimize,
        .strip = false,
    });

    // 嵌入式关键配置
    exe.setLinkerScript(b.path("stm32f103.ld"));
    exe.addAssemblyFile(b.path("src/startup_stm32f103.s"));
    exe.link_gc_sections = true;
    exe.link_data_sections = true;

    // 生成 .bin 文件
    const bin = b.addObjCopy(exe, .{
        .format = .bin,
    });
    bin.step.dependOn(&exe.step);
    b.installArtifact(bin);

    // 安装 ELF
    b.installArtifact(exe);
}

6. 调试:OpenOCD + Zig GDB

第一步:启动 OpenOCD

在新终端中运行以下命令:

bash 复制代码
openocd -f interface/stlink.cfg -f target/stm32f1x.cfg

第二步:启动 Zig GDB

在另一个终端中运行:

bash 复制代码
zig gdb zig-out/firmware/firmware.elf

第三步:GDB 调试指令

进入 GDB 交互界面后,依次执行:

text 复制代码
(gdb) target remote :3333
(gdb) monitor reset halt
(gdb) load
(gdb) continue

7. 常见问题

7.1 链接报错:找不到内存区域

原因 :检查链接脚本 .ld 中的 Flash/RAM 大小是否和你实际使用的芯片匹配。

7.2 烧录成功,芯片不运行

原因:

  • 确认启动文件 startup 汇编、中断向量表配置是否正确。
  • 确认 Flash 起始地址是否为 0x08000000。

7.3 编译提示无法使用 libc 函数

原因:嵌入式是 freestanding 环境,没有 libc,必须使用 Zig 无标准库写法。


8. 参考资料

相关推荐
国科安芯1 小时前
卫星推进与轨道维持系统中脉冲调制控制器的精确时序与抗辐射可靠性研究
嵌入式硬件·抗辐射·卫星姿轨控·as32x601·在轨服务
黑妹天下第一乖1 小时前
第 04 讲:阿加犀 AIMO 模型优化平台与 Model Farm 模型广场实战
人工智能·嵌入式硬件·矩阵·架构·iot
黑妹天下第一乖1 小时前
第08讲 · 视觉与相机流水:Spectra ISP 与实时检测
人工智能·嵌入式硬件·数码相机·机器人·接口隔离原则·iot
yuehuaxin011 小时前
LP3710S 原边 PSR|3C 认证适配器 Peak‑Load 瞬时冲击、EMI 传导骚扰样机避坑解析
嵌入式硬件·适配器模式·智能硬件
sukalot2 小时前
Windows 驱动实例分析系列:libwdi 驱动分析 - 应用篇(一)
windows·驱动开发
恒锐丰科技林技术员2 小时前
EG3014S 半桥驱动芯片:无刷电机与功率变换的优选栅极驱动器件
经验分享·嵌入式硬件·硬件工程
Carl_奕然3 小时前
【智能体】Loop 的四种设计模式之:Event-Driven Loop(2026 最新版)
人工智能·驱动开发·python·设计模式
沐欣工作室_lvyiyi3 小时前
基于单片机的智能提醒药盒设计(论文+源码)
单片机·嵌入式硬件
常州晟凯电子科技3 小时前
sigmaStar SSC8836Q/SSC8826Q开发笔记之环境搭建和SDK编译
笔记·嵌入式硬件·物联网·视频编解码