环境搭建与编译工具链
本文档说明 Jieli AW31N BLE SDK(fw-AW31N_BLE_SDK)的开发环境搭建步骤与编译工具链组成,涵盖杰理 clang 工具链的安装与验证、顶层/板级 Makefile 构建系统、Code::Blocks 与 VS Code 编译方式、烧录工具链以及常见编译故障的排查方法。
Purpose and Scope
本页面聚焦于从零搭建开发环境到产出可烧录固件的完整链路:环境前提条件、工具链安装、构建系统架构、编译命令、产物(.hex)与烧录工具衔接。
本页面覆盖的内容:
- Windows 与 Linux 平台的环境前提条件
- 杰理编译工具链(clang)的下载、安装路径约定与验证方法
- 顶层
Makefile构建入口与全部 target - 板级
board/bd47目录下的编译配置(Makefile、.cbp、全局编译配置头文件) - Windows 命令行环境入口
tools/make_prompt.bat - 编译产物与烧录工具的对应关系
留给兄弟页面的内容:
- 应用层开发(BLE 透传、HID 等)的代码结构,参见各应用工程页面(
apps/demo/transfer、apps/demo/hid) - 固件烧录与 OTA 升级的详细操作,参见「烧录与升级」相关页面
- 芯片型号与板级外设配置细节,参见板级配置相关页面
Overview
fw-AW31N_BLE_SDK 是杰理科技为 AW31N 系列芯片提供的通用蓝牙 SDK,基于裸机操作系统,包含完整的 BLE 协议栈与示例工程。SDK 采用「源码 + 预编译静态库(lib.a)」的混合发布模式,因此编译环境必须与官方工具链匹配。
SDK 支持两套构建入口,对应两类主流开发环境:
| 平台 | 推荐方式 | 构建入口 |
|---|---|---|
| Windows | Code::Blocks IDE | *.cbp 工程文件 |
| Linux | Makefile 命令行 | 顶层 Makefile |
| Windows/Linux | VS Code | .vscode/tasks.json 预定义任务 |
编译的核心依赖是杰理自研 clang 工具链。Linux 下工具链约定安装于 /opt/jieli,且必须保证 /opt/jieli/common/bin/clang 存在(注意目录层次);Windows 下通过 tools/make_prompt.bat 将 tools/utils 目录注入 PATH,从而在命令行直接调用编译器与辅助工具。
构建系统的调用链为:顶层 Makefile → 板级 Makefile → clang 工具链 → .hex 固件。所有受支持的产品 target 都定义在顶层 Makefile 开头的注释中,当前包括 aw31n_transfer(BLE 透传/数传)与 aw31n_hid(HID 人机交互)两个目标。
Architecture
下图展示了环境搭建与编译工具链的完整架构:工具链层为构建提供编译器与辅助工具,构建入口层将开发者指令翻译为具体的编译动作,产物层负责把固件送到目标板。
flowchart TD
subgraph sg_Toolchain["工具链层"]
Clang["clang 编译器<br/>(/opt/jieli/common/bin/clang)"]
Utils["Windows 辅助工具<br/>(tools/utils)"]
end
subgraph sg_Entry["构建入口层"]
TopMake["顶层 Makefile"]
BoardMake["板级 Makefile<br/>(apps/demo/*/board/bd47)"]
CBP["Code::Blocks 工程<br/>(*.cbp)"]
VSCode["VS Code tasks.json"]
PromptBat["make_prompt.bat"]
end
subgraph sg_Output["产物与烧录层"]
Hex["固件 .hex"]
USBUpgrade["USB 升级工具"]
ProdBurn["生产烧写工具"]
end
TopMake -->|"make -C board/bd47"| BoardMake
BoardMake -->|"调用编译/链接"| Clang
CBP -->|"调用编译/链接"| Clang
VSCode -->|"触发任务"| TopMake
PromptBat -->|"注入 PATH"| Utils
Utils --> BoardMake
Clang --> Hex
Hex --> USBUpgrade
Hex --> ProdBurn
架构说明:
- 工具链层:
clang是 SDK 唯一官方支持的编译器(Linux 下安装于/opt/jieli/common/bin/);Windows 下tools/utils目录存放了make_prompt.bat所依赖的命令行辅助工具,必须出现在PATH中编译才能正常进行。 - 构建入口层:四个入口殊途同归——顶层 Makefile 把
make命令分发到具体板级目录;板级 Makefile 是真正执行编译的脚本;Code::Blocks 工程文件(.cbp)内嵌了完整的编译选项;VS Code 任务则封装了 make 命令。这种分层设计让 Windows 与 Linux 开发者都可以使用自己习惯的方式,而底层编译逻辑完全一致。 - 产物与烧录层:编译产物为
.hex固件文件,位于对应 board 目录下;USB 升级工具(开发阶段)与生产烧写工具(量产/裸片)负责将其写入目标芯片。
编译流程的整体决策路径如下:
flowchart TD
Start([开始]) --> Env{"工具链就绪?"}
Env -->|"否"| Install["安装杰理工具链<br/>Linux: 解压到 /opt/jieli"]
Install --> CheckClang{"clang 存在?"}
CheckClang -->|"否"| Fix["检查目录层次<br/>/opt/jieli/common/bin/clang"]
CheckClang -->|"是"| Ulimit{"ulimit -n 足够?"}
Ulimit -->|"否"| Raise["ulimit -n 8096"]
Ulimit -->|"是"| Make["make aw31n_hid / aw31n_transfer"]
Raise --> Make
Make --> Link{"链接成功?"}
Link -->|"否"| Debug["排查编译错误<br/>(见故障模式章节)"]
Link -->|"是"| Hex2["生成 .hex 固件"]
Hex2 --> Burn["使用烧录工具下载到目标板"]
Debug --> Make
设计意图:将工具链路径与目录层次作为硬性约定(而非环境变量自动探测),是为了保证预编译库(lib.a)的 ABI 与工具链版本严格一致——lib.a 由杰理官方用同一套 clang 工具链构建,混用编译器版本会引入难以排查的链接错误。
环境搭建
前提条件
| 系统 | 说明 |
|---|---|
| Windows | 推荐使用 Code::Blocks IDE 编译(工程文件为 *.cbp) |
| Linux | 支持 Makefile 命令行编译,需要 bash 环境与 make |
SDK 面向的芯片平台为 bd47,覆盖型号 AW312B / AW313A / AW314A / AW318A / AW318B,适用于 transfer(透传/数传)与 hid(人机交互)两类应用。
安装杰理编译工具链
- 从杰理官方工具文档下载并安装编译工具链:工具链下载与安装说明。
- Linux 用户可从 pkgman.jieliapp.com 找到对应下载链接:
# 1. 下载工具链压缩包(链接见 pkgman.jieliapp.com/doc/all)
# 2. 解压到 /opt/jieli 目录下,保证目录层次正确
# /opt/jieli/common/bin/clang 必须存在
# 3. 确认文件描述符上限足够大(建议大于 8096),否则链接可能因
# 打开文件过多而失败
ulimit -n 8096
该步骤来自顶层
Makefile开头的注释,是官方对 Linux 编译环境的硬性要求。
- 安装完成后打开终端/命令提示符验证:
# 验证工具链是否安装成功
clang --version
若
clang --version无法执行,说明工具链路径未生效或目录层次不正确,请检查/opt/jieli/common/bin/clang是否存在(Linux)或tools/utils是否已注入PATH(Windows)。
安装烧录工具
| 工具 | 用途 | 获取方式 |
|---|---|---|
| USB 升级工具 | 将固件烧录到目标板(开发阶段) | 申请链接 · 使用文档 |
| 生产烧写工具 | 量产/裸片烧写 | 使用文档 |
| 无线测试盒 | 空中升级/射频标定/产品测试 | 申请链接 · 使用文档 |
构建系统详解
顶层 Makefile:统一编译入口
仓库根目录的 Makefile 是 Linux 命令行构建的唯一入口,负责把编译请求分发到各个子工程对应的板级 Makefile:
# 总的 Makefile,用于调用目录下各个子工程对应的 Makefile
# 注意: Linux 下编译方式:
# 1. 从 http://pkgman.jieliapp.com/doc/all 处找到下载链接
# 2. 下载后,解压到 /opt/jieli 目录下,保证
# /opt/jieli/common/bin/clang 存在(注意目录层次)
# 3. 确认 ulimit -n 的结果足够大(建议大于8096),否则链接可能会因为打开文件太多而失败
# 可以通过 ulimit -n 8096 来设置一个较大的值
# 支持的目标
# make aw31n_transfer
# make aw31n_hid
.PHONY: all clean aw31n_transfer aw31n_hid clean_aw31n_transfer clean_aw31n_hid
all: aw31n_transfer aw31n_hid
@echo +ALL DONE
clean: clean_aw31n_transfer clean_aw31n_hid
@echo +CLEAN DONE
aw31n_transfer:
$(MAKE) -C apps/demo/transfer/board/bd47 -f Makefile
clean_aw31n_transfer:
$(MAKE) -C apps/demo/transfer/board/bd47 -f Makefile clean
aw31n_hid:
$(MAKE) -C apps/demo/hid/board/bd47 -f Makefile
clean_aw31n_hid:
$(MAKE) -C apps/demo/hid/board/bd47 -f Makefile clean
Source: Makefile
设计意图解析:
.PHONY声明:所有 target 都是伪目标(不生成同名文件),确保每次执行make都会实际触发编译动作,避免因已存在同名文件而跳过构建。-C递归调用:顶层 Makefile 不直接包含编译规则,而是用$(MAKE) -C <目录>递归进入板级目录执行其自身的 Makefile。这种「总控 + 子工程」结构让每个板级工程保持独立,新增产品时只需在顶层增加一个 target 指向新的 board 目录。all/clean聚合:all依次编译 transfer 与 hid 两个子工程,clean依次清理,便于一次构建 SDK 全部产物。
支持的目标一览:
| Target | 作用 | 实际执行 |
|---|---|---|
make all | 编译全部子工程 | transfer + hid |
make clean | 清理全部产物 | 两个子工程 clean |
make aw31n_transfer | 编译 BLE 透传工程 | make -C apps/demo/transfer/board/bd47 |
make clean_aw31n_transfer | 清理透传工程 | 同上 + clean |
make aw31n_hid | 编译 HID 工程 | make -C apps/demo/hid/board/bd47 |
make clean_aw31n_hid | 清理 HID 工程 | 同上 + clean |
板级构建目录:board/bd47
每个应用工程下都有 board/ 子目录,按芯片平台划分。以 apps/demo/hid/board/bd47/ 为例,目录中包含:
| 文件 | 作用 |
|---|---|
Makefile | 板级编译脚本(clang 编译、静态库链接、hex 生成) |
AW31N_hid.cbp | Code::Blocks 工程文件 |
board_aw312a_rc.c / board_aw313a_mouse.c / board_aw31n_demo.c 等 | 板级初始化代码 |
board_*_cfg.h | 板级配置(引脚、外设) |
board_*_global_build_cfg.h | 全局编译配置(功能开关) |
board_config.h | 板级总配置选择头文件 |
app_modules.h | 应用模块裁剪开关 |
设计意图:板级目录将「芯片平台(bd47)」与「具体产品板型(RC 遥控、鼠标、Demo)」分离——同一芯片平台可容纳多个板型,每个板型通过 board_<型号>_<形态>.c + 对应 _cfg.h + _global_build_cfg.h 三个文件自洽描述,board_config.h 负责在编译期选中具体板型。产品化时只需复制一个板型目录并修改配置头文件,无需改动 SDK 内核。
Code::Blocks 工程文件(Windows 推荐)
Windows 用户推荐直接双击打开 *.cbp 工程文件(如 AW31N_hid.cbp),在 Code::Blocks 中点击 Build → Build(Ctrl+F9)即可编译。.cbp 文件内嵌了完整的编译器路径、头文件搜索路径、宏定义与链接脚本,与板级 Makefile 保持同一套配置,保证两种构建方式产物一致。
VS Code 任务
仓库预配置了 VS Code 编译任务(.vscode/tasks.json),按 Ctrl+Shift+B 即可弹出目标选择列表,直接触发对应的 make 编译目标。VS Code 方式本质上是 Makefile 命令的图形化封装,适合习惯现代编辑器的开发者。
Windows 命令行环境:make_prompt.bat
tools/make_prompt.bat 是 Windows 下使用 Makefile 编译的命令行入口:
SET SCRIPT_PATH=%~dp0%
set PATH=%SCRIPT_PATH%\utils;%PATH%
cd ..
cmd
Source: tools/make_prompt.bat
逐行解析:
SET SCRIPT_PATH=%~dp0%:获取脚本自身所在目录(tools/),%~dp0是批处理中「当前脚本目录」的标准写法,带尾随反斜杠。set PATH=%SCRIPT_PATH%\utils;%PATH%:把tools/utils目录前置到PATH最前面,确保命令行优先解析 SDK 自带的辅助工具(如编译器封装、链接脚本工具),而不是系统中可能存在的同名工具——这是「工具链版本锁定」的关键手段。cd ..:切换到 SDK 根目录,使make aw31n_hid等命令可以按相对路径执行。cmd:启动交互式命令行,保持该环境,等待开发者输入make命令。
设计意图:make_prompt.bat 相当于 Windows 版的「环境激活脚本」,避免开发者手工配置全局环境变量,也防止污染系统全局 PATH——工具链只在脚本开启的终端会话内生效,关闭窗口即恢复,降低了多项目共存的冲突风险。
核心编译流程
下图展示从开发者执行 make 命令到产出可烧录固件的完整调用链:
sequenceDiagram
participant Dev as 开发者
participant Top as 顶层 Makefile
participant Board as 板级 Makefile<br/>(board/bd47)
participant Clang as clang 工具链
participant Lib as 预编译库 (lib.a)
participant Out as 构建产物 (.hex)
Dev->>Top: make aw31n_hid
activate Top
Top->>Board: $(MAKE) -C apps/demo/hid/board/bd47 -f Makefile
deactivate Top
activate Board
Board->>Clang: 编译应用源码与板级代码
Clang->>Lib: 链接 bt_controller_lib.a / bt_protocol_lib.a / cpu_lib.a 等
Lib-->>Clang: 静态库符号解析
Clang-->>Out: 生成 .hex 固件(含链接脚本与 objcopy 转换)
deactivate Board
Out-->>Dev: 位于 board 目录下,可烧录
流程要点:
- 入口分发:开发者执行
make aw31n_hid,顶层 Makefile 通过-C参数把 make 上下文切换到apps/demo/hid/board/bd47并执行该目录下的 Makefile。-C会同时改变工作目录,保证板级 Makefile 中的相对路径(源码、头文件、库文件)都能正确解析。 - 板级编译:板级 Makefile 先依据
board_config.h选中具体板型(如board_aw313a_mouse.c),再编译应用层与板级源码,期间通过board_*_global_build_cfg.h中的宏开关裁剪功能模块。 - 静态链接:SDK 以「源码 + 预编译
lib.a」形式发布,蓝牙协议栈、CPU 底层等闭源部分以静态库参与链接。库文件按芯片平台存放(apps/include_lib/liba/bd47/flash等目录),版本必须与源码配套,混用会导致链接失败或运行异常。 - 产物生成:链接完成后,工具链依据链接脚本将固件转换为
.hex格式,输出到 board 目录,供 USB 升级工具或生产烧写工具直接下载。
用法示例
示例一:完整编译 HID 工程(Linux/macOS)
cd fw-AW31N_BLE_SDK
# 编译完整 HID 工程
make aw31n_hid
# 编译完成后,在 apps/demo/hid/board/bd47/ 目录下找到生成的 .hex 文件
Source: README.md
示例二:编译全部工程并清理
# 编译全部子工程(transfer + hid)
make all
# 清理全部编译产物
make clean
Source: Makefile
示例三:Windows 命令行环境激活
# 双击 tools/make_prompt.bat 打开命令行环境
# 脚本自动将 tools/utils 注入 PATH 并切换到 SDK 根目录
# 之后即可在提示符下执行:
make aw31n_hid
Source: tools/make_prompt.bat
示例四:工具链验证
# 验证工具链是否安装成功
clang --version
Source: README.md
示例五:Code::Blocks 图形化编译(Windows 推荐)
# 1. 进入对应的板级目录
cd apps/demo/hid/board/bd47/
# 2. 双击打开 .cbp 工程文件(如 AW31N_hid.cbp)
# 3. 在 Code::Blocks 中点击 Build → Build (Ctrl+F9)
# 4. 编译成功后,使用 USB 升级工具烧录生成的 .hex 文件
Source: README.md
配置选项
编译目标(Makefile Targets)
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
all | target | - | 编译全部子工程(transfer + hid) |
clean | target | - | 清理全部子工程产物 |
aw31n_transfer | target | - | 编译 BLE 透传/数传工程 |
clean_aw31n_transfer | target | - | 清理透传工程 |
aw31n_hid | target | - | 编译 HID 人机交互工程 |
clean_aw31n_hid | target | - | 清理 HID 工程 |
环境变量与系统约束
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| 工具链安装路径 | 路径 | /opt/jieli(Linux) | 解压后必须保证 /opt/jieli/common/bin/clang 存在 |
PATH 注入 | 路径 | tools/utils(Windows) | 由 make_prompt.bat 前置注入,锁定工具版本 |
ulimit -n | 数值 | 建议 > 8096 | 文件描述符上限,过小会导致链接失败 |
| 芯片平台 | 枚举 | bd47 | 板级目录划分依据,覆盖 AW312B/AW313A/AW314A/AW318A/AW318B |
板级编译开关(头文件宏)
| 配置文件 | 作用 |
|---|---|
board_*_global_build_cfg.h | 全局编译配置:功能模块开关(如 USB、充电、按键数量等) |
board_*_cfg.h | 板级配置:引脚分配、外设参数 |
board_config.h | 板型选择:决定编译哪一套板级代码 |
app_modules.h | 应用模块裁剪:决定是否编译某个应用功能 |
这些宏开关在编译期生效(条件编译),修改后需重新编译整个工程才会生效,这正是「全局编译配置」名称的由来——它影响的是链接进固件的代码集合,而非运行时行为。
API 参考(构建命令速查)
make aw31n_transfer / make aw31n_hid
- 描述:编译指定应用工程的完整固件。
- 行为:递归进入对应 board 目录执行 Makefile,调用 clang 工具链编译源码、链接预编译静态库,生成
.hex固件。 - 产物:
apps/demo/<app>/board/bd47/下的.hex文件。 - 前置条件:工具链就绪(见环境搭建章节)、
ulimit -n足够大。
make all
- 描述:依次编译 transfer 与 hid 两个子工程。
- 行为:等价于顺序执行
make aw31n_transfer与make aw31n_hid。
make clean / make clean_aw31n_*
- 描述:删除指定工程(或全部工程)的编译中间产物。
- 行为:递归执行对应板级 Makefile 的
clean目标。 - 适用场景:切换板型配置、升级工具链版本或遇到诡异链接问题时,建议先 clean 再重新编译。
故障模式、边界情况与并发注意
常见编译故障及排查
| 故障现象 | 根因 | 排查/解决 |
|---|---|---|
clang: command not found | 工具链未安装或路径未生效 | Linux 检查 /opt/jieli/common/bin/clang 是否存在及目录层次;Windows 确认通过 make_prompt.bat 启动终端 |
| 链接阶段报「打开文件过多」(Too many open files) | ulimit -n 过小,链接器打开的目标文件/库文件超过系统限制 | 执行 ulimit -n 8096(建议更大)后重新链接 |
| 链接错误:符号未定义/重复定义 | 预编译库 lib.a 与源码版本不匹配,或板级宏开关与库的裁剪不一致 | 确认库文件与 SDK 版本配套;检查 board_*_global_build_cfg.h 功能开关是否与库的编译配置一致;必要时 make clean 后重编 |
| 烧录后设备异常/功能缺失 | 功能宏未打开,相关模块代码未链接进固件 | 检查 board_*_global_build_cfg.h 与 app_modules.h 的模块开关 |
| Windows 下命令行找不到 make | 未使用 make_prompt.bat 激活环境 | 双击 tools/make_prompt.bat 打开命令行环境 |
边界情况
- 目录层次敏感:Linux 工具链必须解压为
/opt/jieli/common/bin/clang的层次;若误将压缩包内容解压到/opt/jieli/common/或更深层目录,clang无法被定位。官方注释中「注意目录层次」即针对此问题。 - 多版本工具链共存:
make_prompt.bat将tools/utils前置到 PATH,可屏蔽系统其他 clang;Linux 下若系统安装了其他 clang,需确保 SDK 构建使用的是/opt/jieli下的工具链(可执行which clang核对)。 - 构建工作目录:顶层 Makefile 依赖
-C切换目录,若在错误目录直接执行make可能找不到apps/路径;make_prompt.bat已通过cd ..规避了此问题。
并发与一致性
- SDK 构建本身为串行依赖(板级编译 → 链接),未发现并行构建(
-j)的显式配置;若使用make -j加速,需确认板级 Makefile 对中间产物目录的依赖是否安全,出现偶发链接错误时建议退回串行构建。 make clean与make不应并发执行(同一工作目录下产物目录竞争),否则可能出现残留中间文件导致链接到过期目标文件。- 预编译库(
lib.a)与源码的配套关系属于「版本一致性」约束:SDK 发布时库与源码锁定在同一版本,开发中不要单独替换某个库文件。
性能与运维注意事项
- 链接是资源密集阶段:BLE 协议栈 + CPU 底层库体积较大,链接阶段会打开大量文件,这就是官方要求调大
ulimit -n的原因。在容器或 CI 环境中尤其要注意默认限制可能很低(如 1024)。 - 产物定位:编译完成后固件位于对应 board 目录(如
apps/demo/hid/board/bd47/),CI 脚本可据此路径归档.hex文件用于自动化烧录/测试。 - CI 环境建议:在 Linux CI 中,构建前执行工具链就绪检查(
clang --version)、ulimit -n 8192,并按需make clean,可显著降低偶发失败率。 - 版本管理:SDK 以 git tag 发布(见 README 头部徽章),编译前确认 checkout 的分支/标签与目标产品匹配,避免库与源码错配。
扩展点
新增产品板型
- 在
apps/demo/<app>/board/bd47/下复制一个现有板型的三件套:board_<型号>_<形态>.c、board_<型号>_<形态>_cfg.h、board_<型号>_<形态>_global_build_cfg.h。 - 修改
board_config.h使其编译期选中新板型。 - 若需要独立编译入口,在顶层
Makefile增加对应的.PHONYtarget,复用$(MAKE) -C apps/demo/<app>/board/bd47 -f Makefile的调用模式。
新增编译目标(target)
顶层 Makefile 的扩展模式非常规整:一个 target + 一个 clean_target,均以 -C 递归调用。新增子工程时照此模式添加即可,all / clean 聚合目标同步加入新 target 即可一键构建全部。
板级宏开关定制
功能裁剪全部通过 board_*_global_build_cfg.h 中的条件编译宏完成。定制产品功能时优先修改宏开关而非源码逻辑,可保持与官方库的兼容性,并便于后续 SDK 升级时合并差异。
Related Links
- Makefile(顶层构建入口)
- README.md(环境搭建与编译指南)
- tools/make_prompt.bat(Windows 编译环境入口)
- default.workspace(Code::Blocks 工作空间)
- 杰理工具链安装文档
- AW31N SDK 文档中心
- 工具链下载源 pkgman.jieliapp.com
- 应用工程开发细节(BLE 透传、HID 等)参见
apps/demo/transfer与apps/demo/hid相关页面 - 固件烧录与升级操作参见「烧录与升级」相关页面