这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 【EEPW-Let'sdesign】SHT43DemoBoard固件编译指南

共1条 1/1 1 跳转至页

【EEPW-Let'sdesign】SHT43DemoBoard固件编译指南

菜鸟
2026-10-21 14:37:37     打赏

一、项目背景

SHT43 DemoBoard 是一块 Sensirion 的温湿度评估板,上面跑一颗 STM32WB55 做 BLE 通信, 把 SHT43 传感器读数通过 两条路暴露出去。

板卡目标芯片:STM32WB55(Cortex-M4 @ 128MHz + Cortex-M0,dual-core,CubeWPA BLE 协议栈) 主机:Ubuntu 24.04 x86_64,无 sudo 权限本文档记录了从 0 到 1 在受限主机上把整个 BLE 固件编译通过的完整路径。

  • BLE 广播(Manufacturer Specific Data,AD type 0xFF)—— 不连也能空口监听

  • BLE GATT(Temperature/Humidity 服务)—— 需连接,读 float32 特征值

固件是 C + C++ 混合,用 CMake + Ninja 构建,依赖 STM32 HAL(CubeWB)+ ST 官方 BLE 协议栈 (CubeWPA,已内置在仓库 lib/ 目录,不需要单独下载)。

仓库里没有提供现成的编译环境,README 默认你已装好 arm-none-eabi-gcc、CMake、Ninja, 或直接用他们给的 docker 镜像。本文档走主机本地、免 root 的路线。

96ff4ef627126caa3d071dac3179a7a2.jpg


二、编译产物

编译成功后在 build/release/ 下生成三个文件:

文件用途



SHT43_DB-<ver>.elf带符号,给 GDB / 调试器用
SHT43_DB-<ver>.bin裸二进制,给 OpenOCD / ST-Link 烧录用(CM4 核,0x08000000)
SHT43_DB-<ver>.hexIntel HEX,给一些烧录工具用

实测占用:FLASH 13.8%(68 KB / 484 KB),RAM1 7.3%。


三、编译环境

使用Hermes主理的主机没有 sudo,所有工具都走 apt-get download + dpkg-deb -x 解包到用户目录的路线, 最终集中在 /home/genvex/.armtool/ 下,由一个 env.sh 统一导出。

3.1 目录布局

/home/genvex/.armtool/
├── env.sh              # 一键 source, 导出 PATH/LD_LIBRARY_PATH/CPATH
├── staging/            # apt 包解包后的统一根 (usr/bin, usr/lib, usr/include)
│   ├── usr/bin/arm-none-eabi-*
│   ├── usr/lib/...
│   └── usr/include/newlib/   # string.h/ctype.h 等 target 头 (来自 libnewlib-dev)
└── cmake-official/     # Kitware 官方 cmake (完整 Modules, 不是 apt 裁剪版)

3.2 需要哪些包

包作用大小




gcc-arm-none-eabiARM GCC 编译器(13.2)57 MB
binutils-arm-none-eabild / objcopy / ar3 MB
libnewlib-arm-none-eabinewlib C 运行时库49 MB
libstdc++-arm-none-eabi-newlibC++ 标准库(newlib 版)463 MB
libnewlib-devnewlib 头文件(string.h 等)140 KB
cmake(apt 版,其实没用)—11 MB
ninja-build构建工具129 KB

3.3 安装步骤(可复现)

# 1. 拉包 (清华源已配好)
mkdir -p ~/armtool/armtool && cd ~/armtool/armtool
DEBIAN_FRONTEND=noninteractive apt-get download \
  gcc-arm-none-eabi binutils-arm-none-eabi \
  libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib \
  libnewlib-dev ninja-build

# 2. 解包到统一 staging
mkdir -p /home/genvex/.armtool/staging
for d in *.deb; do dpkg-deb -x "$d" /home/genvex/.armtool/staging; done

# 3. 补 cmake 运行依赖 (librhash / libjsoncpp)
DEBIAN_FRONTEND=noninteractive apt-get download librhash0 libjsoncpp25
for d in librhash0*.deb libjsoncpp25*.deb; do
  dpkg-deb -x "$d" /home/genvex/.armtool/staging
done

3.4 cmake 必须换官方 prebuilt

apt 的 cmake_3.28.3-1build7_amd64.deb 是个裁剪版——只装 debtoolchainfilegen, 没有真正的 cmake 二进制 + Modules/ 目录。cmake --version 能跑但一执行项目配置就报Could not find CMAKE_ROOT。

解决:用 Kitware 官方 release 包(走 gh-proxy,本机直连 GitHub 会被拦):

cd /home/genvex/.hermes/cache/scratch   # 任意临时目录
curl -fL -C - -o cmake_official.tar.gz \
  "https://gh-proxy.com/https://github.com/Kitware/CMake/releases/download/v3.28.3/cmake-3.28.3-linux-x86_64.tar.gz"
tar xzf cmake_official.tar.gz -C /home/genvex/.armtool/cmake-official --strip-components=1
# 验证
/home/genvex/.armtool/cmake-official/bin/cmake --version   # 应显示 3.28.3 + 无 CMAKE_ROOT 报错

3.5 一键环境脚本 env.sh

# /home/genvex/.armtool/env.sh
export ARMTOOL=/home/genvex/.armtool/staging
export PATH="$ARMTOOL/usr/bin:$PATH"
export LD_LIBRARY_PATH="$ARMTOOL/usr/lib/x86_64-linux-gnu:$ARMTOOL/usr/lib:$LD_LIBRARY_PATH"
# 官方 cmake 优先 (PATH 顺序靠后但放前面, 压过 apt 的裁剪版)
export PATH="/home/genvex/.armtool/cmake-official/bin:$PATH"
# newlib 标准头 (string.h/ctype.h/...) 喂给交叉 gcc
export CPATH="$ARMTOOL/usr/include/newlib:$CPATH"

四、本地适应编译改造

坑 #1:没有 ARM 工具链,没有 sudo

→ 全走 apt-get download + dpkg-deb -x 解包到用户目录。见 3.3。

坑 #2:apt 的 cmake 是裁剪版,缺 Modules

→ 换 Kitware 官方 prebuilt cmake。见 3.4。

坑 #3:newlib 头文件 + multi-arch 路径错位(最隐蔽)

解完包后编译直接报 fatal error: string.h: No such file or directory。 两层原因:

a. 头文件缺失。 libnewlib-arm-none-eabi 只带 .a 库,不带 .h。 newlib 头文件在单独的 libnewlib-dev 包里(路径 usr/include/newlib/)。 要额外 apt-get download libnewlib-dev 并解包,然后用 CPATH 指给它(见 env.sh)。

b. gcc 的 multi-arch 目录 ≠ newlib 的 multi-arch 目录。

  • arm-none-eabi-gcc -print-multi-directory 对 cortex-m4 + hard-float 期望的是thumb/v7e-m+fp/hard

  • 但 newlib 实际把库放在 arm-none-eabi/newlib/thumb/v8-m.main+fp/hard/

两套子目录布局不一致,导致链接阶段 ld 找不到裸的 crt0.o 和 -lc_nano。 症状:ld: cannot find crt0.o / cannot find -lc_nano。

解法:把 newlib 的 hard-float 库软链进 gcc 期望的 multi-dir:

GD=/home/genvex/.armtool/staging/usr/lib/gcc/arm-none-eabi/13.2.1/thumb/v7e-m+fp/hard
ND=/home/genvex/.armtool/staging/usr/lib/arm-none-eabi/newlib/thumb/v8-m.main+fp/hard
for f in crt0.o libc_nano.a libc.a libm.a libnosys.a libstdc++_nano.a; do
  [ -f "$ND/$f" ] && ln -sf "$ND/$f" "$GD/$f"
done

冒烟验证(hello world 交叉编译,bare-metal 下 undefined _exit/_isatty 是良性的):

echo 'int main(){return 0;}' > /tmp/h.c
arm-none-eabi-gcc -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 \
  -specs=/home/genvex/.armtool/staging/usr/lib/arm-none-eabi/newlib/nano.specs \
  /tmp/h.c -o /tmp/h

坑 #4:_sbrk 重复定义,链接失败

工程在 st_app/sysmem.c 里强定义了自己的 _sbrk(heap 分配器), 而 newlib 的 libnosys.a 里也有一个弱定义。默认 CMakeLists 链接行带 -lnosys, 于是两个定义都进链接,报 multiple definition of _sbrk。

解法:把 CMakeLists 里的 -lnosys 去掉(让工程自己的 sysmem.c 提供 _sbrk)。 见下节 5.2。


五、项目本身需要的两处 CMakeLists 改动

仓库 CMakeLists.txt 有两处默认值在"非 root + 自定义 staging"环境下不适用, 必须改(已改好并保留在仓库里):

5.1 -specs=nano.specs → 绝对路径

原来写的是相对引用 -specs=nano.specs,gcc 在自己的默认搜索路径找不到。 改成指向 staging 里 newlib 的全路径:

# CMakeLists.txt (linker options)
-specs=/home/genvex/.armtool/staging/usr/lib/arm-none-eabi/newlib/nano.specs

5.2 去掉 -lnosys

# 原来: -lc -lm -lnosys
# 改为: -lc -lm
# 原因: st_app/sysmem.c 提供 _sbrk, 无需 libnosys; 且 libnosys.a 的弱 _sbrk 会撞
-lc -lm

六、编译方法

cd /home/genvex/sht43-demoboard-ble-firmware
source /home/genvex/.armtool/env.sh

# configure (README 推荐配方)
cmake -B build/release \
  -DCMAKE_MAKE_PROGRAM=ninja \
  -DCMAKE_BUILD_TYPE=release \
  -G Ninja

# 全量编译
cmake --build build/release

成功输出(关键几行):

[109/109] Linking C executable SHT43_DB-1_0_1-develop.elf
Memory region         Used Size  Region Size  %age Used
           FLASH:       68479 B       484 KB     13.82%
            RAM1:       14312 B     196600 B      7.28%
BUILD rc=0

增量 / 干净重编

# 增量: 只重编改动的文件
cmake --build build/release

# 改过 CMakeLists 后 (链接行有缓存): 删 build 目录重来
rm -rf build/release
cmake -B build/release -DCMAKE_MAKE_PROGRAM=ninja -DCMAKE_BUILD_TYPE=release -G Ninja
cmake --build build/release

debug 配置

cmake -B build/debug -DCMAKE_MAKE_PROGRAM=ninja -DCMAKE_BUILD_TYPE=debug -G Ninja
cmake --build build/debug

七、烧录

固件要同时烧两个核(STM32WB55 是双核,CM4 跑应用,CM0 跑 radio 协处理器)。 本仓库构建只产出 CM4 主核 的 .bin。本次只是理论性探讨,还没找到烧录的入口。 

f206a43e35b4911c75dd6041e32135c2.jpg

用 OpenOCD + ST-Link(CM4 @ 0x08000000)

openocd -f interface/stlink.cfg -f target/stm32wb55.cfg \
  -c "program build/release/SHT43_DB-1_0_1-develop.bin 0x08000000 verify reset exit"

用 ST 官方 STM32_Programmer_CLI

STM32_Programmer_CLI -c "connect" -w build/release/SHT43_DB-1_0_1-develop.bin 0x08000000

用 Sensirion 官方 docker (难度也不一定小)

# 见仓库 README "Local build using docker" 一节
docker pull sensirion/sht43-demoboard-ble-firmware-build:latest
# docker 里工具链全齐, 直接一条命令出 bin

八、为什么选 CMake+Ninja 而不是别的

仓库只支持 CMake 构建(没有 Makefile、没有 PlatformIO)。 Ninja 比 make 快,且 README 明确推荐 -G Ninja。 STM32 的 CubeWPA 协议栈是预编译好的 .a 大库(lib/ 目录里), 所以编译时间主要花在工程自身的 ~60 个 .c 文件上,整体 1-2 分钟。


参考

  • 固件仓:github.com/Sensirion/sht43-demoboard-ble-firmware

  • 硬件仓(可选):github.com/Sensirion/sht43-demoboard-hardware

  • 官方构建文档:仓库 README.md § "Building the application"

  • 官方 docker:仓库 README.md § "Local build using docker"






关键词: EEPW-Let     SHT43     sdesign     De    

共1条 1/1 1 跳转至页

回复

匿名不能发帖!请先 [ 登陆 注册 ]