WiFi 摄像头方案
基于杰理(Jieli)AC79NN 系列芯片(wl82 平台,AC7911B/AC7912A/AC7913A/AC7915A/AC7915B/AC7916A)的 WiFi 摄像头产品级参考方案,位于 apps/wifi_camera/ 目录。该方案以 WiFi 图传为核心,支持摄像头采集(BT656 YUV)、视频编码、SD 卡录像/拍照、RTC 时间戳、OTA 升级等完整产品能力。
Purpose and Scope
本文档系统性地说明 apps/wifi_camera 产品应用(对应编译目标 ac791n_wifi_camera)的工程结构、核心配置、存储布局、视频通路与运行机制,帮助开发者快速理解并基于该方案进行二次开发。
本文档覆盖以下内容:
apps/wifi_camera应用目录的模块划分与职责(主入口、配置数据库、YUV 采集、板级适配)include/app_config.h中的关键编译开关与宏配置(WiFi、SD 卡、录像、OTA、视频缓冲模式)- 录像/拍照目录布局与存储路径设计(DCIM、EMR、U 盘)
- 板级支持(wl82 平台的多芯片配置头文件)与构建方式
以下内容不在本页展开,请参见对应页面:
- 摄像头裸机驱动的详细实现,参见
apps/demo/demo_uvc(UVC 摄像头 Demo)与apps/demo/demo_DevKitBoard(SPI 摄像头 Demo)相关页面 - WiFi IPC 网络摄像头方案(另一条产品线
apps/wifi_ipc/),有独立的文档页 - 通用 SDK 工具链与烧录流程,参见 SDK 根目录 README
概述
WiFi 摄像头方案是杰理 AC79NN SDK 中针对「无线图传摄像头」品类的量产级参考实现。与同平台的 WiFi 故事机(wifi_story_machine)、扫码枪(scan_box)等产品并列,wifi_camera 聚焦于视频采集 → 编码 → 无线传输/本地存储的完整链路。
其核心设计要点:
- 单芯片方案:摄像头 YUV 数据直接接入芯片(
bt656_camera_get_yuv.c、get_yuv_data.c负责采集与搬运),无需外部视频处理芯片; - WiFi 直连图传:通过
CONFIG_WIFI_ENABLE使能无线,视频数据经乒乓缓冲(PPBUF)模式实时传输(图传 ≤ 20 帧场景);关闭 PPBUF 则使用 LBUF 模式以支持写卡录像与大帧率图传; - 本地存储双保险:支持 SD0/SD1 双卡,录像/拍照统一落盘到
storage/sdX/C/DCIM/目录,可选 EMR(紧急事件录像)子目录; - 无 SDRAM 与有 SDRAM 两种封装:通过
CONFIG_NO_SDRAM_ENABLE切换,影响__SDRAM_SIZE__与 RF TRIM 代码的运行位置(节省 RAM vs 固定 RAM); - 系统配置持久化:
CONFIG_DATABASE_2_FLASH将系统配置(app_database.c)写入 Flash,掉电不丢失。
架构
flowchart TD
subgraph sg_App["应用层 apps/wifi_camera"]
AppMain["app_main.c<br/>主入口/任务调度"]
AppDB["app_database.c<br/>配置数据库(Flash持久化)"]
YuvGet["get_yuv_data.c<br/>YUV 数据采集"]
Bt656["bt656_camera_get_yuv.c<br/>BT656 摄像头对接"]
end
subgraph sg_Config["配置层 include/"]
AppCfg["app_config.h<br/>编译开关/路径宏"]
ActionH["action.h<br/>动作事件定义"]
AppDBH["app_database.h<br/>数据库接口"]
end
subgraph sg_Board["板级支持 board/wl82/"]
BoardCfg["board_config.h"]
Board791x["board_7911B/7912A/7913A/<br/>7915A/7915B/7916A_cfg.h"]
BoardDev["board_dev_kit.c<br/>开发板初始化"]
Makefile["Makefile + .cbp 工程"]
end
subgraph sg_System["SDK 系统层"]
RTOS["RTOS(任务/栈检查)"]
FS["文件系统 storage/sd0|sd1|udisk0"]
Video["视频编码/乒乓缓冲<br/>CONFIG_VIDEO_REC_PPBUF_MODE"]
Wifi["WiFi 无线图传<br/>CONFIG_WIFI_ENABLE"]
Flash["Flash 数据库<br/>CONFIG_DATABASE_2_FLASH"]
end
AppMain --> AppCfg
AppMain --> AppDB
AppMain --> YuvGet
YuvGet --> Bt656
AppDB --> AppDBH
AppCfg --> BoardCfg
BoardCfg --> Board791x
BoardDev --> BoardCfg
AppMain --> RTOS
AppDB --> Flash
YuvGet --> Video
Video --> Wifi
Video --> FS
Makefile --> AppMain
架构说明:
- 应用层是方案的核心,
app_main.c负责创建任务与事件分发,app_database.c管理用户配置(存 Flash),get_yuv_data.c与bt656_camera_get_yuv.c完成传感器 YUV 数据的获取与格式对接; - 配置层以
app_config.h为总开关:所有功能裁剪(WiFi、SD、录像、RTC、OSD)与路径布局都在此集中定义,编译期生效,避免运行时分支开销; - 板级层按芯片型号拆分为独立配置头文件,同一套应用代码通过
board_config.h选择具体型号,实现"一套应用、多芯片量产"; - 系统层提供 RTOS 调度、文件系统、视频编码与 WiFi 协议栈,应用层通过宏开关选择使用方式(如 PPBUF vs LBUF 视频缓冲模式)。
主要模块详解
1. 编译开关与平台配置(app_config.h)
apps/wifi_camera/include/app_config.h 是整个方案的"总控台",所有产品级功能都通过宏在编译期裁剪。其设计意图是:产品形态变化(有无 SDRAM、有无 SD 卡、是否带 WiFi)只改宏,不改业务代码。
1.1 无 SDRAM 封装适配
#ifdef CONFIG_NO_SDRAM_ENABLE /* 封装不带sdram就打开该宏 */
#undef __SDRAM_SIZE__
#define __SDRAM_SIZE__ (0 * 1024 * 1024)
#endif
当产品采用无 SDRAM 封装时,__SDRAM_SIZE__ 被清零,系统只能依赖芯片内部 RAM 运行。这一设计对成本敏感的摄像头方案至关重要——去掉外部 SDRAM 可以显著降低 BOM 成本。
1.2 WiFi 与 RF TRIM 的 RAM 策略
#ifdef CONFIG_NET_ENABLE
#define CONFIG_CTP_ENABLE
#define CONFIG_WIFI_ENABLE /* 无线WIFI */
#ifdef CONFIG_NO_SDRAM_ENABLE
#define CONFIG_RF_TRIM_CODE_MOVABLE //把RF TRIM 的运行代码动态加载到ram运行(节省4K ram内存), 防止RF TRIM 期间500ms大电流访问flash造成flash挂掉持续大电流
#else
#define CONFIG_RF_TRIM_CODE_AT_RAM //把RF TRIM 的运行代码定死到ram运行(浪费4K ram内存,否则若动态加载到sdram需清cache), 防止RF TRIM 期间500ms大电流访问flash造成flash挂掉持续大电流
#endif
// #define CONFIG_IPERF_ENABLE // iperf测试
#endif
WiFi 使能(CONFIG_WIFI_ENABLE)是摄像头图传的前提。RF TRIM(射频校准)期间会有约 500ms 的大电流访问 Flash,为防止该操作导致 Flash 挂掉并持续大电流,将 RF TRIM 代码放入 RAM 执行:无 SDRAM 时动态加载(省 4KB RAM),有 SDRAM 时固定驻留(避免清 cache 的开销)。这是芯片级电源与 Flash 可靠性的关键折中。
1.3 视频缓冲模式:PPBUF vs LBUF
#define CONFIG_VIDEO_REC_PPBUF_MODE /*视频使用乒乓BUF模式(图传<=20帧),关闭则用lbuf模式(图传>20帧和写卡录像),缓冲区大小配置video_buf_config.h*/
//#define CONFIG_VIDEO_SPEC_DOUBLE_REC_MODE /* 视频支持双路莫模式(一路实时流、一路录SD卡)*/
- PPBUF(乒乓缓冲)模式:适用于图传 ≤ 20 帧的低延迟场景,双缓冲交替读写,延迟小;
- LBUF 模式:关闭 PPBUF 后启用,支持图传 > 20 帧以及写卡录像,缓冲大小在
video_buf_config.h配置; - 双路录制模式(默认关闭):可同时输出一路实时流 + 一路 SD 卡录像,是高端产品(如同时看画面又留证据)的扩展开关。
1.4 系统能力开关
| 宏 | 作用 | 说明 |
|---|---|---|
CONFIG_DATABASE_2_FLASH | 系统配置存 Flash | 用户配置掉电保存 |
CONFIG_DEBUG_ENABLE | 打印开关 | 量产可关闭以省资源 |
CONFIG_RTC_ENABLE | RTC 使能 | 录像/拍照时间戳的基础 |
CONFIG_PCM_DEC_ENABLE / CONFIG_PCM_ENC_ENABLE | PCM 音频编解码 | 摄像头录音对讲扩展 |
CONFIG_OSD_ENABLE | 视频 OSD 时间戳 | 默认关闭,开启后叠加时间信息 |
RTOS_STACK_CHECK_ENABLE | 定时检查任务栈 | 开发期防栈溢出 |
MEM_LEAK_CHECK_ENABLE | 内存泄漏检查 | 默认关闭,需包含 mem_leak_test.h |
2. 存储布局与录像/拍照路径
方案在 Flash/SD/U 盘上建立了统一的三级目录体系,多路摄像头(VIDEO1)与紧急录像(EMR)通过宏自动展开路径:
#define CONFIG_REC_DIR_0 "DCIM/1/"
#define CONFIG_REC_DIR_1 "DCIM/2/"
#ifndef CONFIG_VIDEO1_ENABLE
#define CONFIG_REC_DIR_2 "DCIM/2/"
#else
#define CONFIG_REC_DIR_2 "DCIM/3/"
#endif
#if TCFG_SD0_ENABLE
#define CONFIG_STORAGE_PATH "storage/sd0"
#define SDX_DEV "sd0"
#endif
#if TCFG_SD1_ENABLE
#define CONFIG_STORAGE_PATH "storage/sd1"
#define SDX_DEV "sd1"
#endif
#ifndef CONFIG_STORAGE_PATH
#define CONFIG_STORAGE_PATH "no_sd_card" //不使用SD定义对应别的路径,防止编译出错
#define SDX_DEV "no_sd"
#endif
路径推导关系如下:
- 根路径:
CONFIG_ROOT_PATH = storage/sdX/C/ - 三路录像/拍照:
DCIM/1/、DCIM/2/、DCIM/3/(第三路仅在CONFIG_VIDEO1_ENABLE时启用,否则复用第二路) - 紧急录像(EMR):
EMR/子目录挂在各路 DCIM 之下,通过CONFIG_EMR_DIR_ENABLE开启 - 音乐/回放:
MUSIC/目录 +CONFIG_DEC_PATH_x解码路径 - U 盘:
storage/udisk0/C/,与 SD 卡路径体系平行
设计意图:将路径全部收敛为编译期宏拼接,一方面保证字符串在 Flash 中只存一份(嵌入式 RAM 宝贵),另一方面让上层业务(录像、拍照、回放、EMR)只依赖 CONFIG_REC_PATH_x / CAMERAx_CAP_PATH 等统一宏,与底层介质(sd0/sd1/udisk)解耦。
3. OTA 版本管理
#define OTA_MAJOR 1
#define OTA_MINOR 3
#define OTA_PATCH 0
方案内置三级版本号(主/次/修订),遵循"次版本必须向下兼容"的升级纪律:主版本用于架构级不兼容变更,次版本用于兼容性功能增加,修订版本用于内部发布与 BUG 修复。该版本号用于固件 OTA 升级时的版本比对与升级包校验。
4. 摄像头数据通路
方案包含两个 YUV 采集模块:
bt656_camera_get_yuv.c:对接 BT656 接口的数字摄像头,负责时序同步、场/行同步检测与 YUV 数据接收;get_yuv_data.c:通用 YUV 数据获取层,向上层视频编码模块提供统一的帧数据接口。
采集链路为:摄像头 sensor → BT656 接口 → get_yuv_data 缓存 → 视频编码 → (PPBUF/LBUF) → WiFi 图传 或 SD 卡落盘。乒乓缓冲模式下双 buffer 交替写入/读出,保证图传的低延迟;写卡录像场景则需关闭 PPBUF 使用 LBUF 大缓冲。
5. 板级支持与构建
板级目录 apps/wifi_camera/board/wl82/ 提供:
board_config.h:板级总配置,选择具体芯片型号头文件;board_7911B_cfg.h/board_7912A_cfg.h/board_7913A_cfg.h/board_7915A_cfg.h/board_7915B_cfg.h/board_7916A_cfg.h:六款 AC79NN 芯片的引脚、时钟、外设差异化配置;board_dev_kit.c/board_develop.c:开发板与自研板的初始化代码;AC791N_WIFI_CAMERA.cbp:Code::Blocks 工程文件;Makefile:命令行构建入口。
构建方式(SDK 根目录 Makefile):
ac791n_wifi_camera:
$(MAKE) -C apps/wifi_camera/board/wl82 -f Makefile
即顶层执行 make ac791n_wifi_camera 即可编译该方案,生成的固件可配合 OTA_MAJOR/MINOR/PATCH 版本号进行 OTA 升级。
核心流程
启动与图传链路
sequenceDiagram
participant B as 板级初始化 board_dev_kit.c
participant M as app_main.c 主入口
participant D as app_database.c 配置数据库
participant Y as get_yuv_data/bt656 采集
participant V as 视频编码(PPBUF/LBUF)
participant W as WiFi 图传
participant S as SD 卡存储
B->>M: 硬件/时钟/外设就绪
M->>M: 解析 app_config.h 宏, 创建任务
M->>D: 读取 Flash 配置(数据库)
D-->>M: 配置加载完成
M->>Y: 启动摄像头采集任务
Y->>Y: BT656 同步, YUV 帧缓存
Y->>V: 提交 YUV 帧
V->>V: 编码 + 乒乓缓冲
par 并行输出
V->>W: 实时图传帧
V->>S: 录像帧写 DCIM/1/ (LBUF模式)
end
W-->>M: 传输状态/事件回馈
流程说明:
- 板级初始化:
board_dev_kit.c依据所选芯片型号配置时钟、GPIO、外设,完成后进入应用主入口; - 配置加载:
app_main.c按app_config.h的宏裁剪创建各功能任务,并从 Flash 数据库(CONFIG_DATABASE_2_FLASH)恢复用户设置; - 采集启动:
bt656_camera_get_yuv.c完成摄像头时序同步,get_yuv_data.c持续产出 YUV 帧; - 编码分发:视频编码后按缓冲模式分发——PPBUF 模式专注低延迟图传(≤20 帧),LBUF 模式可同时支撑图传(>20 帧)与写卡录像;
- 并行输出:WiFi 图传与 SD 卡录像可并行(双路模式),单路模式下按宏配置选择输出通道。
录像/拍照路径决策
flowchart TD
Start([事件触发]) --> Check{"TCFG_SD0/SD1 使能?"}
Check -->|"是"| Path["CONFIG_STORAGE_PATH = storage/sdX"]
Check -->|"否"| Nopath["no_sd_card 占位路径"]
Path --> Dir{"第几路?"}
Dir -->|"0"| D0["DCIM/1/"]
Dir -->|"1"| D1["DCIM/2/"]
Dir -->|"2"| D2{"CONFIG_VIDEO1_ENABLE?"}
D2 -->|"是"| D2b["DCIM/3/"]
D2 -->|"否"| D2a["DCIM/2/ 复用"]
D0 --> EMR{"CONFIG_EMR_DIR_ENABLE?"}
D1 --> EMR
D2b --> EMR
EMR -->|"是"| E["追加 EMR/ 紧急录像子目录"]
EMR -->|"否"| Save["落盘: storage/sdX/C/DCIM/..."]
Save --> End([完成])
配置选项汇总
| 配置宏 | 类型 | 默认值 | 说明 |
|---|---|---|---|
CONFIG_NO_SDRAM_ENABLE | 开关 | 关闭 | 无 SDRAM 封装,__SDRAM_SIZE__ 清零 |
CONFIG_NET_ENABLE | 开关 | 依赖 board | 网络功能总开关,级联使能 CTP/WiFi |
CONFIG_WIFI_ENABLE | 开关 | 关闭 | 无线 WiFi 图传 |
CONFIG_RF_TRIM_CODE_MOVABLE | 开关 | 随 NO_SDRAM | RF TRIM 代码动态加载到 RAM(省 4KB) |
CONFIG_RF_TRIM_CODE_AT_RAM | 开关 | 随 SDRAM | RF TRIM 代码固定驻留 RAM(免清 cache) |
CONFIG_VIDEO_REC_PPBUF_MODE | 开关 | 开启 | 乒乓缓冲模式(图传 ≤20 帧) |
CONFIG_VIDEO_SPEC_DOUBLE_REC_MODE | 开关 | 关闭 | 双路模式:实时流 + SD 卡录像 |
CONFIG_OSD_ENABLE | 开关 | 关闭 | 视频 OSD 时间戳叠加 |
CONFIG_DATABASE_2_FLASH | 开关 | 开启 | 系统配置写入 Flash 持久化 |
CONFIG_RTC_ENABLE | 开关 | 开启 | RTC 实时时钟 |
CONFIG_PCM_DEC/ENC_ENABLE | 开关 | 开启 | PCM 音频编解码 |
TCFG_SD0_ENABLE / TCFG_SD1_ENABLE | 0/1 | 0 | SD 卡通道使能,决定存储路径 |
CONFIG_EMR_DIR_ENABLE | 开关 | 关闭 | 紧急事件录像目录 EMR/ |
CONFIG_VIDEO1_ENABLE | 开关 | 关闭 | 第三路录像目录 DCIM/3/ |
OTA_MAJOR / OTA_MINOR / OTA_PATCH | int | 1 / 3 / 0 | OTA 固件版本号 |
RTOS_STACK_CHECK_ENABLE | 开关 | 开启 | 定时检查任务栈 |
MEM_LEAK_CHECK_ENABLE | 开关 | 关闭 | 内存泄漏检查(需头文件) |
CONFIG_DEBUG_ENABLE | 开关 | 开启 | 调试打印开关 |
MAX_FILE_NAME_LEN | int | 64 | 文件名最大长度 |
失败模式、边界与并发注意
- Flash 大电流风险:RF TRIM 期间约 500ms 大电流访问 Flash,若此时再并发访问 Flash 可能造成挂死。方案强制将 RF TRIM 代码放入 RAM(MOVABLE/AT_RAM 二选一),并在无 SDRAM 封装下通过动态加载节省 4KB RAM——这是"可靠性 vs 内存"的显式权衡,二次开发时不应随意关闭该宏;
- 无 SD 卡降级:当
TCFG_SD0_ENABLE/TCFG_SD1_ENABLE均为 0 时,存储路径退化为no_sd_card占位符,防止编译错误;上层录像/拍照代码应基于该路径宏做运行时能力判断,避免写盘失败; - PPBUF 帧率上限:乒乓缓冲模式仅适合图传 ≤20 帧的场景;若产品需要更高帧率或写卡录像,必须关闭 PPBUF 切换到 LBUF 模式并在
video_buf_config.h中调整缓冲大小,否则会出现丢帧或缓冲溢出; - 任务栈溢出:默认开启
RTOS_STACK_CHECK_ENABLE定时巡检,新增业务任务时应遵循同一机制并预留足够栈空间; - 多路目录复用:第三路录像目录(
DCIM/3/)仅在CONFIG_VIDEO1_ENABLE时启用,未启用时第二路与第三路共享DCIM/2/,文件管理代码需按此去重,避免重复枚举。
使用示例
示例 1:按产品形态裁剪编译开关
无 SDRAM + WiFi 图传的低成本摄像头典型配置组合:
#ifdef CONFIG_NO_SDRAM_ENABLE /* 封装不带sdram就打开该宏 */
#undef __SDRAM_SIZE__
#define __SDRAM_SIZE__ (0 * 1024 * 1024)
#endif
#ifdef CONFIG_NET_ENABLE
#define CONFIG_CTP_ENABLE
#define CONFIG_WIFI_ENABLE /* 无线WIFI */
#ifdef CONFIG_NO_SDRAM_ENABLE
#define CONFIG_RF_TRIM_CODE_MOVABLE //把RF TRIM 的运行代码动态加载到ram运行(节省4K ram内存), 防止RF TRIM 期间500ms大电流访问flash造成flash挂掉持续大电流
#else
#define CONFIG_RF_TRIM_CODE_AT_RAM //把RF TRIM 的运行代码定死到ram运行(浪费4K ram内存,否则若动态加载到sdram需清cache), 防止RF TRIM 期间500ms大电流访问flash造成flash挂掉持续大电流
#endif
#endif
Source: app_config.h
生产时只需在 board_config.h 中定义 CONFIG_NO_SDRAM_ENABLE 与 CONFIG_NET_ENABLE,应用代码无需改动即可自动切换内存布局与 RF TRIM 策略。
示例 2:存储路径宏的拼接约定
录像、拍照、回放均依赖统一的路径宏,新增介质(如 U 盘)只需平行追加:
#define CONFIG_REC_DIR_0 "DCIM/1/"
#define CONFIG_REC_DIR_1 "DCIM/2/"
#if TCFG_SD0_ENABLE
#define CONFIG_STORAGE_PATH "storage/sd0"
#define SDX_DEV "sd0"
#endif
#define CONFIG_ROOT_PATH CONFIG_STORAGE_PATH"/C/"
#define CONFIG_REC_PATH_0 CONFIG_STORAGE_PATH"/C/"CONFIG_REC_DIR_0
#define CONFIG_UDISK_STORAGE_PATH "storage/udisk0"
Source: app_config.h
业务代码应始终引用 CONFIG_REC_PATH_x / CAMERAx_CAP_PATH 等宏,而不是硬编码字符串,这样切换 SD0/SD1/U 盘时零改动。
示例 3:命令行构建
ac791n_wifi_camera:
$(MAKE) -C apps/wifi_camera/board/wl82 -f Makefile
Source: Makefile
在 SDK 根目录执行 make ac791n_wifi_camera 即可编译 WiFi 摄像头方案;也可用 Code::Blocks 打开 apps/wifi_camera/board/wl82/AC791N_WIFI_CAMERA.cbp 图形化构建。
扩展点
- 视频缓冲策略:
CONFIG_VIDEO_REC_PPBUF_MODE与CONFIG_VIDEO_SPEC_DOUBLE_REC_MODE组合出四种产品形态(纯图传 / 图传+录像 / 高帧率图传 / 双路并行),缓冲大小在video_buf_config.h调整; - 多芯片量产:新增芯片型号时,在
board/wl82/下仿照board_7915A_cfg.h增加配置头,并在board_config.h中按宏选择,应用层零改动; - 存储介质扩展:沿
CONFIG_UDISK_STORAGE_PATH的平行模式可继续增加 U 盘、eMMC 等介质,只需补齐路径宏与介质驱动; - 音频扩展:
CONFIG_PCM_DEC/ENC_ENABLE已预留音频编解码能力,可支撑摄像头对讲/录音功能; - OSD 叠加:开启
CONFIG_OSD_ENABLE可在视频流上叠加 RTC 时间戳,适合需要时间水印的产品。