工程结构导览
fw-AC79_AIoT_SDK 是杰理科技 AC791N 系列 WiFi + 蓝牙 AIoT 多媒体 SoC 的通用固件开发包。本文从仓库顶层目录出发,逐层讲解 apps、cpu、include_lib、lib、tools 等目录的职责与组织方式,帮助你快速建立整个 SDK 的"地图",并掌握方案工程、Demo 与编译入口之间的对应关系。
目的与范围
本页面面向初次接触该 SDK 的开发者,系统性地导览仓库的工程结构:顶层目录职责、应用层与平台层的划分、预编译库与头文件的存放位置、构建入口(Makefile / default.workspace / init_env.sh),以及方案工程与功能 Demo 的组织方式。
本页不深入以下主题,相关细节由对应页面覆盖:
- 编译命令、工具链与常见编译错误 → 见「编译指南」
- 各方案工程与 Demo 的开发说明 → 见「应用与示例指南」
- 烧录、固件打包与升级流程 → 见「烧录与升级」
- 蓝牙 Profile、用户配置与日志等裁剪配置 → 见「配置说明」
概述
fw-AC79_AIoT_SDK 是一个典型的"分层 + 多工程"固件 SDK:同一套平台代码(cpu/wl82)支撑多个方案工程(apps/*),方案工程通过 board 目录做板级差异化,通过 apps/common 复用公共中间件,最终链接 cpu/wl82/liba 与 lib 下的预编译静态库(*.a)生成固件。
从宏观上看,SDK 划分为五个逻辑层次:
| 层次 | 目录 | 职责 |
|---|---|---|
| 应用层 | apps/ | 方案工程(wifi_camera / wifi_ipc / wifi_story_machine / scan_box)、11 个功能 Demo、公共中间件 common/ |
| 平台层 | cpu/wl82/ | CPU 平台代码、预编译静态库 liba/、烧录与打包工具 tools/ |
| 接口层 | include_lib/ + lib/ | 协议栈/驱动/媒体/系统/网络的对外头文件与预编译库 |
| 构建入口 | Makefile / default.workspace / init_env.sh | 顶层统一编译入口、Code::Blocks 工作空间、环境初始化脚本 |
| 文档层 | doc/ / docs/ / tools/ | 数据手册与规格书、在线文档 rst 源、编译辅助工具 |
其中 apps/*/board/wl82/ 是每个工程的板级配置目录,承载引脚定义、外设初始化、编译选项与 .cbp 工程文件——这是理解"一个工程如何被编译"的关键位置。
架构
下图展示了 SDK 顶层目录的组织关系与构建依赖:
flowchart TD
subgraph sg_Root["SDK 根目录 fw-AC79_AIoT_SDK"]
MF["Makefile<br/>顶层编译入口"]
WS["default.workspace<br/>Code::Blocks 工作空间"]
ENV["init_env.sh<br/>环境初始化"]
end
subgraph sg_Apps["apps/ 应用层"]
APP_COMMON["common/<br/>公共中间件"]
APP_CAMERA["wifi_camera/"]
APP_IPC["wifi_ipc/"]
APP_SCAN["scan_box/"]
APP_STORY["wifi_story_machine/"]
APP_DEMO["demo/<br/>11 个功能 Demo"]
end
subgraph sg_Platform["cpu/wl82/ 平台层"]
CPU_LIBA["liba/<br/>预编译静态库 *.a"]
CPU_TOOLS["tools/<br/>烧录与打包工具"]
end
subgraph sg_Interface["接口与预编译库"]
INC["include_lib/<br/>模块头文件"]
LIB["lib/<br/>net/server/utils 等"]
end
MF --> APP_CAMERA
MF --> APP_IPC
MF --> APP_SCAN
MF --> APP_STORY
MF --> APP_DEMO
APP_COMMON --> APP_CAMERA
APP_COMMON --> APP_STORY
APP_COMMON --> APP_DEMO
APP_CAMERA --> CPU_LIBA
APP_CAMERA --> INC
APP_CAMERA --> LIB
WS --> APP_CAMERA
ENV --> MF
图中各层的设计意图:
apps/是唯一需要开发者日常修改的层次。每个方案工程自带board/wl82/板级配置,通过make <target>即可独立编译;common/则提供跨工程共享的音频、视频、蓝牙、WiFi、UI、AI 等中间件,避免各方案重复造轮子。cpu/wl82/是平台底座。liba/下的*.a静态库以预编译形式提供(SDK 源码不公开库内部实现),tools/提供烧录与固件打包脚本,配合方案工程完成从源码到可烧录固件的闭环。include_lib/+lib/构成接口契约。方案工程只依赖头文件中的 API 签名与预编译库的符号,这种"头文件 + 二进制库"的交付方式保证了平台实现可以独立演进,同时隔离了芯片底层细节。Makefile是唯一推荐的编译入口,default.workspace则面向 Code::Blocks 图形化开发场景;init_env.sh用于初始化编译环境(如工具链路径)。
顶层目录总览
仓库根目录包含以下内容(源自 README「六、工程结构」章节):
fw-AC79_AIoT_SDK/
├── apps/ # 应用层代码
│ ├── common/ # 公共模块(asr/audio_music/ble/camera/eth/fm/
│ │ # gsensor/jl_math/LLM/ui/usb/update/third_party_profile…)
│ ├── wifi_camera/ # 📌 WiFi 摄像头方案
│ ├── scan_box/ # 📌 扫码盒方案
│ ├── wifi_ipc/ # 📌 WiFi IPC 网络摄像机方案
│ ├── wifi_story_machine/ # 📌 WiFi 故事机方案
│ └── demo/ # 📌 11 个功能 demo(ble/wifi/edr/ui/uvc/video/audio…)
├── cpu/wl82/ # CPU 平台代码 + 预编译库(liba) + 烧录工具(tools)
├── include_lib/ # 头文件(btctrler/btstack/driver/media/net/system/update…)
├── lib/ # 预编译库(net/server/utils…)
├── doc/ # 数据手册(datasheet/AC791N规格书) 与资料(stuff)
├── docs/ # 在线文档源(rst)
├── tools/ # 编译工具(make_prompt.bat + utils)
├── Makefile # 顶层统一编译入口
└── default.workspace # Code::Blocks 工作空间
Source: README.md
README 还给出了关键目录速查表,这是导航 SDK 时最高频的路径:
| 目录 | 作用 |
|---|---|
apps/*/board/wl82/ | 板级配置:引脚定义、外设初始化、编译选项、.cbp 工程 |
apps/common/ | 公共模块:跨工程共享的音频、视频、蓝牙、WiFi、UI、AI 等中间件 |
apps/common/config/ | 库配置:蓝牙 Profile、用户配置、日志等裁剪配置 |
apps/demo/ | 功能示例:11 个可直接参考或修改的最小 demo 工程 |
cpu/wl82/liba/ | 预编译库:*.a 静态库文件 |
cpu/wl82/tools/ | 烧录工具:下载脚本、固件打包工具等 |
include_lib/ | 头文件:协议栈、驱动、媒体、系统、网络等模块接口 |
Source: README.md
应用层 apps/ 详解
apps/ 是 SDK 中唯一需要开发者日常编写与修改代码的层次,由三类内容组成:
1. 公共中间件 apps/common/
common/ 按功能模块划分子目录,涵盖 asr(语音识别)、audio_music(音频音乐)、ble(低功耗蓝牙)、camera(摄像头)、eth(以太网)、fm(收音机)、gsensor(重力传感器)、jl_math(杰理数学库)、LLM(大语言模型对接)、ui(界面显示)、usb、update(升级)、third_party_profile(第三方协议)等。
设计意图:把各方案都会用到的能力下沉为"中间件",方案工程只负责编排与业务逻辑。例如 wifi_camera 与 wifi_ipc 都依赖 camera 与 audio_music,但各自的采集流程、网络推流策略不同。
2. 方案工程(Solution)
| 方案 | 路径 | 适用场景 | make target |
|---|---|---|---|
| WiFi 摄像头 | apps/wifi_camera/ | WiFi 监控摄像头、可视门铃、图传 | ac791n_wifi_camera |
| WiFi IPC | apps/wifi_ipc/ | 网络摄像机 IP Camera、录卡/网络推流 | ac791n_wifi_ipc |
| WiFi 故事机 | apps/wifi_story_machine/ | 儿童故事机、智能音箱、网络音频播放 | ac791n_wifi_story_machine |
| 扫码盒 | apps/scan_box/ | 蓝牙/USB 扫码枪、HID/POS 设备 | ac791n_scan_box |
Source: README.md
每个方案工程内部遵循统一骨架:board/wl82/(板级配置 + .cbp 工程)、app/ 或 src/(业务代码)、config/(工程级配置)。新做产品时,通常从最接近的方案复制一份,只改 board 与业务层。
3. 功能 Demo apps/demo/
demo/ 下共有 11 个最小可编译工程,每个 Demo 只聚焦一个能力,是学习与验证 API 的最佳起点:
| Demo | 路径 | 演示功能 | make target |
|---|---|---|---|
| demo_ble | apps/demo/demo_ble/ | BLE 低功耗蓝牙数传 | ac791n_demo_demo_ble |
| demo_edr | apps/demo/demo_edr/ | 经典蓝牙 EDR(音乐/SPP/发射器/解码) | ac791n_demo_demo_edr |
| demo_wifi | apps/demo/demo_wifi/ | WiFi STA/AP 联网 | ac791n_demo_demo_wifi |
| demo_wifi_ext | apps/demo/demo_wifi_ext/ | 外置 WiFi / LTE 扩展联网 | ac791n_demo_demo_wifi_ext |
| demo_audio | apps/demo/demo_audio/ | 音频采集/播放/编解码 | ac791n_demo_demo_audio |
| demo_video | apps/demo/demo_video/ | 视频采集/JPEG 编码/录像 | ac791n_demo_demo_video |
| demo_uvc | apps/demo/demo_uvc/ | USB UVC 摄像头 | ac791n_demo_demo_uvc |
| demo_ui | apps/demo/demo_ui/ | UI 显示/图层/触摸 | ac791n_demo_demo_ui |
| demo_hello | apps/demo/demo_hello/ | 最小启动工程(入门骨架) | ac791n_demo_demo_hello |
| demo_DevKitBoard | apps/demo/demo_DevKitBoard/ | 官方开发板综合演示 | ac791n_demo_demo_devkitboard |
| demo_matter | apps/demo/demo_matter/ | Matter 物联网协议(需进入 board 目录编译) | — |
Source: README.md
设计意图:demo_hello 作为最小启动骨架,demo_DevKitBoard 作为官方开发板的综合演示,二者构成"从零到一"的入门路径;其余 Demo 按外设/协议拆分,方便按需裁剪出最小复现用例。
平台层 cpu/wl82/ 详解
cpu/wl82/ 是芯片平台专属目录(wl82 即 AC791N 系列平台代号),包含三部分:
- 平台源码:芯片启动、内核适配等底层代码(配合
include_lib使用)。 liba/预编译静态库:*.a文件是 SDK 功能的主体实现(协议栈、驱动、媒体编解码等),以二进制形式随 Release 提供,需配合include_lib/中的头文件调用。SDK 引用了 lwIP、mbedTLS、FreeRTOS 等开源项目,相关实现也以库或源码形式包含在内。tools/烧录工具:下载脚本、固件打包工具,配合「烧录与升级」流程使用。
平台层与 lib/ 目录共同构成了"二进制交付层":cpu/wl82/liba/ 提供与芯片强相关的平台库,lib/ 提供 net/server/utils 等相对通用的功能库。当链接报错 cannot find -lxxx 时,应优先检查这两个目录是否缺失对应库文件(见下文「常见问题」)。
头文件与预编译库 include_lib/ + lib/
include_lib/按模块组织头文件:btctrler(蓝牙控制器)、btstack(蓝牙协议栈)、driver(驱动)、media(媒体)、net(网络)、system(系统)、update(升级)等。开发时通过#include这些头文件获取 API 签名,是"接口契约"所在。lib/存放预编译库:net(网络协议栈)、server(服务)、utils(工具库)等*.a文件。
这两个目录不应被修改——它们是 Release 交付物。功能裁剪发生在 apps/common/config/(库配置层),而不是头文件或库本身。
文档与工具 doc/ / docs/ / tools/
doc/:数据手册(datasheet/AC791N 规格书)与参考资料(stuff),用于硬件设计、引脚对照与电气参数查询。docs/:在线文档中心(AC79 模块示例文档)的 rst 源文件。tools/:编译辅助工具(make_prompt.bat、utils),例如在 Windows 下生成编译提示环境。
SDK 固件包本身不含开发文档,开发前应详细阅读在线文档中心,本仓库的 docs/ 即其源。
构建入口与方案/Demo 组织
SDK 提供三个顶层入口,职责各不相同:
| 入口 | 类型 | 作用 |
|---|---|---|
Makefile | 命令行 | 唯一推荐的编译入口。通过 make <target> 选择方案或 Demo,make all 全量编译,make clean 清理 |
default.workspace | Code::Blocks | 图形化工作空间,可在 IDE 中打开各方案的 .cbp 工程进行编辑、编译与调试 |
init_env.sh | Shell 脚本 | 编译环境初始化(如工具链路径、文件描述符限制等) |
Makefile 的 target 命名规则为 ac791n_<工程路径>,例如 ac791n_wifi_camera、ac791n_demo_demo_ble。target 与 apps/ 下目录一一对应,编译时 Makefile 会进入对应工程的 board/wl82/ 读取编译选项与源文件清单,链接平台库后产出固件。因此新增方案工程时,只需在 apps/ 下创建目录并仿照既有工程的 board 结构,即可获得对应的 make target(命名遵循 ac791n_<路径> 约定)。
核心流程
编译流程
一次典型编译的控制流如下:
flowchart TD
Start([在 SDK 根目录执行 make target]) --> MF["Makefile<br/>解析 target 与工具链"]
MF --> Board["apps/<工程>/board/wl82/<br/>读取 .cbp 工程与编译选项"]
Board --> Config["apps/common/config/<br/>功能裁剪与库配置"]
Config --> Compile["编译应用源码"]
Compile --> Link["链接 include_lib 头文件 +<br/>cpu/wl82/liba + lib 预编译库"]
Link --> Out{"链接成功?"}
Out -->|"Yes"| FW["生成固件产物<br/>(配合 cpu/wl82/tools 打包烧录)"]
Out -->|"No"| Err["定位错误:<br/>缺库 / 裁剪配置缺失 / 工具链问题"]
Err --> Board
图中各节点对应仓库中的真实位置:
Makefile(根目录)、apps/*/board/wl82/、apps/common/config/、cpu/wl82/liba/、lib/、cpu/wl82/tools/。
关键点:编译选项在 board/wl82/,功能裁剪在 apps/common/config/。如果链接报 undefined reference,通常是裁剪配置未包含对应模块;如果报 cannot find -lxxx,则是 cpu/wl82/liba/ 或 lib/ 缺少对应 .a 文件。
源码导航路径
当需要定位某个功能时,推荐按"应用 → 中间件 → 接口 → 库"的层级自上而下查找:
flowchart LR
A["现象/需求"] --> B["apps/<方案> 业务代码"]
B --> C["apps/common/ 公共中间件"]
C --> D["include_lib/ 头文件 API 签名"]
D --> E["cpu/wl82/liba + lib 预编译库<br/>(二进制实现)"]
C --> F["apps/common/config/ 裁剪配置"]
例如要调查"WiFi 摄像头如何推流":先看 apps/wifi_camera/ 的业务代码,发现其调用 apps/common/camera 与 net 相关 API,再到 include_lib/ 查接口定义,最后在 apps/common/config/ 确认相关模块未被裁剪。
使用示例
示例 1:查看工程结构
# 仓库顶层结构
fw-AC79_AIoT_SDK/
├── apps/ # 应用层代码
│ ├── common/ # 公共模块(asr/audio_music/ble/camera/eth/fm/…)
│ ├── wifi_camera/ # WiFi 摄像头方案
│ ├── scan_box/ # 扫码盒方案
│ ├── wifi_ipc/ # WiFi IPC 网络摄像机方案
│ ├── wifi_story_machine/ # WiFi 故事机方案
│ └── demo/ # 11 个功能 demo
├── cpu/wl82/ # CPU 平台代码 + 预编译库(liba) + 烧录工具(tools)
├── include_lib/ # 头文件(btctrler/btstack/driver/media/net/system/update…)
├── lib/ # 预编译库(net/server/utils…)
├── doc/ # 数据手册 与 资料
├── docs/ # 在线文档源(rst)
├── tools/ # 编译工具(make_prompt.bat + utils)
├── Makefile # 顶层统一编译入口
└── default.workspace # Code::Blocks 工作空间
Source: README.md
示例 2:Linux 下编译 WiFi 摄像头工程
# 1. 确保文件描述符限制足够大(链接阶段需要打开大量文件)
ulimit -n 8096
# 2. 进入 SDK 根目录并行编译
make ac791n_wifi_camera -j`nproc`
Source: README.md
示例 3:常用编译目标速查
make ac791n_wifi_camera # 编译 WiFi 摄像头方案
make ac791n_demo_demo_ble # 编译 BLE 数传 Demo
make ac791n_demo_demo_hello # 编译最小启动工程
make all # 编译全部
make clean # 清理全部
make clean_ac791n_wifi_camera # 清理 wifi_camera 编译产物
make clean_ac791n_demo_demo_ble # 清理 demo_ble 编译产物
Source: README.md
设计意图:make target 与 apps/ 目录一一对应,clean_<target> 提供单工程清理能力,避免全量 make clean 带来的重复编译开销;Linux 下必须调大文件描述符限制,因为链接阶段要同时打开大量 .a 库与目标文件。
配置入口
工程结构中的"配置"分散在三个层级,理解其边界是正确裁剪功能的前提:
| 配置位置 | 配置内容 | 修改建议 |
|---|---|---|
apps/*/board/wl82/ | 板级配置:引脚定义、外设初始化、编译选项、.cbp 工程 | 每个方案/硬件平台必改,属于"本工程专属" |
apps/common/config/ | 库配置:蓝牙 Profile、用户配置、日志等裁剪配置 | 影响所有引用 common 的工程,改动需谨慎并回归测试 |
include_lib/ + lib/ + cpu/wl82/liba/ | 预编译库与头文件(Release 交付物) | 不应修改,缺失或改动会破坏接口契约 |
其中 apps/common/config/ 是"功能裁剪开关"的集中地:开启某模块(如音频编码、蓝牙 Profile)后,链接阶段才会把对应库符号纳入固件。若裁剪配置未包含某模块却调用了它的 API,就会出现 undefined reference 链接错误——这是配置与代码不一致时最常见的信号。
常见问题与失败模式
根据 README「编译指南」章节整理的典型问题,均可在本页的目录结构中找到根因:
| 错误提示 | 根因定位 | 解决方法 |
|---|---|---|
clang: command not found | 工具链问题(构建入口层) | 未安装杰理编译工具链,或 init_env.sh 环境变量未配置 |
Too many open files | 环境限制(构建入口层) | Linux 下执行 ulimit -n 8096 增加文件描述符限制 |
cannot find -lxxx | 库缺失(平台/接口层) | 检查 cpu/wl82/liba/ 与 lib/ 是否存在对应的 .a 文件 |
undefined reference to ... | 裁剪配置与代码不一致(配置层) | 检查 apps/common/config/ 下的功能裁剪配置是否包含对应模块 |
Source: README.md
从失败模式可以看出工程结构设计的两个核心约束:
- 二进制交付层不可随意改动——库文件缺失会导致链接失败,且由于 SDK 为 Release 形态(源码不含库内部实现),本地无法重建平台库,只能从发布渠道获取完整包。
- 裁剪配置是隐式的模块依赖图——
apps/common/config/决定哪些库符号进入固件,改配置等同于改依赖图,因此"改了一处配置、影响了所有工程"是预期行为,而非缺陷。
操作注意与扩展点
- 多工程并行:每个方案工程在
apps/下独立成目录、拥有独立 make target,可以并行编译互不干扰;clean_<target>支持按工程清理,无需全量清理。 - 新增方案工程:在
apps/下仿照现有方案创建目录,补齐board/wl82/(引脚、外设、编译选项、.cbp),Makefile 侧即可获得ac791n_<路径>target,无需修改顶层构建脚本——这是 SDK 的主要扩展点。 - 新增功能 Demo:在
apps/demo/下创建demo_xxx/,以demo_hello为最小骨架起步,复用apps/common/中间件即可快速验证单项能力。 - 文档与硬件资料:硬件设计请以
doc/下数据手册(datasheet/AC791N 规格书)为准;软件 API 以include_lib/头文件为权威,在线文档中心(docs/源)提供模块级开发说明。
相关链接
- README.md(仓库总览) — SDK 概述、支持芯片、能力总览、快速开始
- README-en.md(英文版总览) — English version of the overview
- Makefile(顶层编译入口) — 编译 target 定义与依赖关系
- default.workspace(Code::Blocks 工作空间) — IDE 工程组织
- apps/common/example/readme.md — 公共模块示例说明
- AC79 在线文档中心 — 各模块详细开发文档(SDK 不内置开发文档,以在线文档为准)
相邻目录页:编译指南 · 应用与示例指南 · 烧录与升级 · 配置说明。