杰理 SDK 文档中心
首页
首页
  • SDK 概述与快速开始

    • SDK 概览与 AC791N 芯片平台
    • 环境搭建与编译指南
    • 烧录与固件升级
    • 工程结构导览
  • 产品方案应用

    • WiFi 摄像头方案
    • WiFi IPC 可视对讲方案
    • WiFi 故事机方案
    • 扫码枪 HID 方案
    • 开发板示例工程
  • 公共应用组件

    • 语音识别 ASR 引擎
    • LLM 与 AI 语音助手接入
    • 摄像头传感器驱动
    • UI 显示框架与驱动
    • USB 主机与设备栈
    • 文件系统与存储管理
    • 系统服务与外设管理
    • 生产测试与射频工具
  • 蓝牙协议栈

    • 经典蓝牙 BR/EDR
    • BLE 低功耗蓝牙
    • 蓝牙 Mesh 网络
    • 蓝牙扩展协议(RCSP/广播/无线麦克风)
  • WiFi 与网络协议栈

    • WiFi 驱动与网络模式
    • lwIP TCP/IP 协议栈
    • 网络安全与加密库
    • 应用层网络协议
    • 流媒体与音视频传输
    • 云平台接入 SDK
    • P2P 远程访问与设备互联
  • 芯片平台与驱动

    • wl82 平台与硬件加速
    • 外设驱动框架
    • 平台配置与固件打包工具
  • 媒体与音频引擎

    • 音频编解码与音源
    • 音效处理引擎
    • 视频与图像处理
  • 操作系统与运行时

    • 实时操作系统与 POSIX 层
    • C/C++ 运行时库
  • 开发资源与文档

    • 文档与规格书
    • 公共示例工程
    • UI 资源工程与打包
    • SDK 辅助工具与脚本

公共示例工程

本文介绍 fw-AC79_AIoT_SDK 中位于 apps/common/example 目录下的公共示例工程集合,涵盖音频、蓝牙、网络协议、开发板测试以及 BLE Mesh 等各类示例,重点说明其组织方式、编译使能方法、事件驱动机制和核心运行流程,帮助开发者快速定位、理解并复用这些示例代码。

Purpose and Scope

本页面向希望在 AC791N 系列 AIoT SoC 上快速开始开发的工程师,系统梳理 SDK 中"开箱即用"的公共示例工程:

  • 说明示例工程的目录结构与分类(音频、蓝牙、网络协议、开发板测试、BLE Mesh);
  • 讲解示例应用的通用组织模式:main.c 入口、事件处理器注册、intent + start_app 应用切换机制;
  • 给出示例工程的编译使能与配置宏(如 USE_AUDIO_DEMO、CONFIG_LOCAL_MUSIC_MODE_ENABLE 等);
  • 通过真实代码摘录演示如何编写按键事件、设备事件、网络事件处理器以及音频服务器回调。

不包含的内容:本文只覆盖"公共示例"这一主题边界。各示例具体业务(如本地音乐、网络音乐、录音、ASR、CoAP/HTTP/MQTT 协议细节、BLE Mesh 模型实现等)属于各自独立的功能主题,请参阅对应的功能页;SDK 整体环境搭建与编译烧录流程参见《快速开始》等姊妹页面。

Overview

fw-AC79_AIoT_SDK 是杰理科技面向 AC791N 系列(wl82 平台)WiFi 802.11b/g/n + 双模蓝牙(BR/EDR + BLE)音视频多媒体 SoC 的通用固件开发包,芯片内置 320MHz 双核浮点 DSP,集成了音频(ADC/DAC/IIS/PDM)、视频(摄像头 ISC)、显示(RGB 推屏)及丰富外设资源。SDK 的 Release 代码中附带大量可直接编译运行的示例工程,全部集中在 apps/common/example(以及 BLE Mesh 示例所在的 apps/common/ble/mesh/examples),覆盖了 SDK 主要的应用场景:

示例类别目录典型示例覆盖能力
音频apps/common/example/audio/*audio_demo(本地音乐/网络音乐/录音/AI 音箱四合一)、asr、lc3、pitch_speed、play_audio_buffer、src_test、virtual_dac、virtual_enc、jla音频服务器框架、编解码、变速变调、SRC、虚拟 DAC/编码、ASR 语音
蓝牙经典apps/common/example/bluetooth/edr/bt_musicbt_music经典蓝牙(BR/EDR)音乐播放
网络协议apps/common/example/network_protocols/*coap_client/server、http_download、http_post_get_put、http_server、user_http_head/post_flash、user_http_head/post_sd、mqttWiFi 联网、CoAP/HTTP/MQTT 协议栈、HTTP 上传下载
开发板测试apps/common/example/Devkitboard_testmain.c + ui_main.c开发板硬件外设全功能自检
BLE Meshapps/common/ble/mesh/examples/*generic_onoff_client/server、light_lightness_server、provisioner、onoff_tobe_provision、vendor_client/server、AliGenie_*、TUYA_lightBLE Mesh 配网、Generic OnOff、Lightness、Vendor Model、天猫精灵/涂鸦平台对接

这些示例共用一个统一的"应用框架 + 事件驱动"运行模型:每个示例以 main.c 为入口,通过注册按键/设备/网络事件处理器响应外部输入,借助 server 框架(如 audio_server)完成媒体等耗时任务,最终以 intent 结构体 + start_app() 的方式在多个子应用间切换。理解这个模型是读懂任何示例工程的前提。

Architecture

公共示例工程在 SDK 中的位置及其与基础组件的关系如下图所示:

flowchart TD
    subgraph sg_Examples["apps/common/example 公共示例工程"]
        Audio["音频示例<br/>audio/* (audio_demo 等)"]
        BT["经典蓝牙示例<br/>bluetooth/edr/bt_music"]
        Net["网络协议示例<br/>network_protocols/*"]
        Devkit["开发板测试<br/>Devkitboard_test"]
        Mesh["BLE Mesh 示例<br/>ble/mesh/examples/*"]
    end

    subgraph sg_Framework["SDK 公共框架层"]
        AppCore["app_core 应用框架<br/>(intent / start_app)"]
        Server["server 服务器框架<br/>audio_server / server_core"]
        EventSys["事件系统<br/>key_event / device_event / net_event"]
    end

    subgraph sg_Config["配置与平台层"]
        AppCfg["app_config.h<br/>使能宏定义"]
        Platform["wl82 平台库 (*.a)<br/>FreeRTOS / lwIP / mbedTLS"]
    end

    Audio --> AppCore
    BT --> AppCore
    Net --> AppCore
    Devkit --> AppCore
    Mesh --> AppCore
    Audio --> Server
    Audio --> EventSys
    BT --> EventSys
    Net --> EventSys
    Devkit --> EventSys
    Audio --> AppCfg
    Net --> AppCfg
    AppCfg --> Platform

架构解读:

  • 示例层(上层):各类示例工程位于 apps/common/example 下,按功能划分子目录。它们不直接操作寄存器,而是调用公共框架层的 API 完成业务。
  • 框架层(中层):app_core 提供应用生命周期管理(start_app / intent),server 框架(server/audio_server.h、server/server_core.h)以"请求-应答"模式封装音频解码等异步任务,event 系统(event/key_event.h、event/device_event.h、event/net_event.h)负责将按键、设备插拔、网络状态等外部变化派发给示例注册的处理器。
  • 配置与平台层(底层):每个示例通过 app_config.h 中的使能宏(如 USE_AUDIO_DEMO)决定是否参与编译;最终链接平台库(*.a)以及 FreeRTOS、lwIP、mbedTLS 等开源组件(见 README.md)。

这种"示例 → 框架 → 配置/平台"的三层结构使示例代码保持简洁:示例只关心业务逻辑,框架负责资源管理与事件分发,平台层屏蔽芯片差异,从而让同一套示例可以复用于不同方案(wifi_camera、wifi_story_machine 等,见 README.md)。

示例工程目录结构

公共示例按功能域组织为 apps/common/example/<类别>/<子功能>/main.c 的形式,每个可独立编译的子应用都以 main.c 作为程序入口。仓库中实际存在的示例清单如下:

类别目录子示例说明
audio/asrmain.c语音打断唤醒(ASR)示例
audio/audio_demomain.c + local_music.c / net_music.c / recorder.c / ai_speaker.c四合一音频综合示例:本地音乐、网络音乐、录音、AI 音箱,通过按键循环切换模式,是理解示例工程组织方式的最佳范本
audio/jla、audio/lc3main.cJLA / LC3 编解码应用示例
audio/pitch_speedmain.c变声变速(pitch/speed)效果示例
audio/play_audio_buffermain.c内存音频缓冲播放示例
audio/src_testmain.c采样率转换(SRC)测试示例
audio/virtual_dac、audio/virtual_encmain.c虚拟 DAC、虚拟编码器示例
bluetooth/edr/bt_musicmain.c经典蓝牙音乐示例
Devkitboard_testmain.c + ui_main.c开发板外设自检示例(带 UI)
network_protocols/coapcoap_client/main.c、coap_server/main.cCoAP 客户端/服务端示例
network_protocols/httphttp_download、http_post_get_put、http_server、user_http_head/post_flash、user_http_head/post_sdHTTP 下载、POST/GET/PUT、HTTP 服务器、自定义 HTTP 头上传 Flash/SD 示例
network_protocols/mqttmain.cMQTT 客户端示例
apps/common/ble/mesh/examplesgeneric_onoff_client、generic_onoff_server、light_lightness_server、provisioner、onoff_tobe_provision、vendor_client、vendor_server、AliGenie_fan/light/socket、TUYA_lightBLE Mesh 模型与平台对接示例(含 provisioner_config.h)

示例的编译与使能

示例并非全部默认编译,而是通过 app_config.h 中的使能宏"按需参与构建"。以 audio_demo 为例,整个文件被 USE_AUDIO_DEMO 宏包裹,只有定义该宏时示例代码才进入编译单元:

Source: main.c

#ifdef USE_AUDIO_DEMO

static int main_key_event_handler(struct key_event *key)

同理,示例内部各功能模式也由独立宏控制。audio_demo 的应用模式表通过条件编译动态组装——启用哪个宏,表中就包含哪个模式,未启用的模式不会占用 Flash 与 RAM:

Source: main.c

struct audio_app_t {
    const char *tone_file_name;
    const char *app_name;
};

static const struct audio_app_t audio_app_table[] = {
#ifdef CONFIG_LOCAL_MUSIC_MODE_ENABLE
    {"FlashMusic.mp3", "local_music"},
#endif
#ifdef CONFIG_NET_MUSIC_MODE_ENABLE
    {"NetMusic.mp3", "net_music"  },
#endif
#ifdef CONFIG_RECORDER_MODE_ENABLE
    {"Recorder.mp3", "recorder"},
#endif
#ifdef CONFIG_ASR_ALGORITHM_ENABLE
    {"AiSpeaker.mp3", "ai_speaker"},
#endif
};

设计意图:这张表是"公共示例"最典型的组织模式——每个子应用由 app_name 标识(与 start_app() 的应用注册名对应),每个模式切换前先播放一段提示音 tone_file_name,提示音结束后才真正拉起目标应用。这种"先播提示音、再切模式"的顺序由 dec_server_event_handler 中的事件回调保证(见下文核心流程)。

示例的统一运行模型

所有公共示例共享同一套"事件驱动 + 应用切换"的运行模型,audio_demo/main.c 是这一模型的完整样本,包含四类标准组件:

1. 按键事件处理器

示例通过注册 main_key_event_handler 响应用户按键,处理 KEY_EVENT_CLICK(单击)与 KEY_EVENT_LONG(长按)两类动作;未消费的事件返回 false 交给上层继续处理:

Source: main.c

static int main_key_event_handler(struct key_event *key)
{
    switch (key->action) {
    case KEY_EVENT_CLICK:
        switch (key->value) {
        case KEY_MODE:
            audio_demo_mode_switch();
            break;
        default:
            return false;
        }
        break;
    case KEY_EVENT_LONG:
        break;
    default:
        return false;
    }

    return true;
}

2. 设备事件与网络事件处理器

示例还需处理设备插拔(如 Flash/SD 卡)与网络状态变化。设备事件区分 DEVICE_EVENT_IN(插入)、DEVICE_EVENT_OUT(拔出)、DEVICE_EVENT_CHANGE(变更);网络事件区分 NET_EVENT_CMD 与 NET_EVENT_DATA,且仅在 CONFIG_NET_ENABLE 开启时编译:

Source: main.c

static int main_dev_event_handler(struct device_event *event)
{
    switch (event->event) {
    case DEVICE_EVENT_IN:
        break;
    case DEVICE_EVENT_OUT:
        break;
    case DEVICE_EVENT_CHANGE:
        break;
    }
    return 0;
}

#ifdef CONFIG_NET_ENABLE
static int main_net_event_hander(struct net_event *event)
{
    switch (event->event) {
    case NET_EVENT_CMD:
        break;
    case NET_EVENT_DATA:
        break;
    }

    return false;
}
#endif

3. 音频服务器事件回调

耗时媒体任务通过 server 框架执行,示例以回调 dec_server_event_handler 接收解码服务器(audio_server)的事件。当提示音解码结束(AUDIO_SERVER_EVENT_END)或出错(AUDIO_SERVER_EVENT_ERR)时,回调负责:停止解码请求、关闭服务器连接、关闭文件句柄、重新使能按键,最后通过 start_app 拉起下一个应用模式:

Source: main.c

static void dec_server_event_handler(void *priv, int argc, int *argv)
{
    union audio_req r = {0};

    switch (argv[0]) {
    case AUDIO_SERVER_EVENT_ERR:
        log_i("tone: AUDIO_SERVER_EVENT_ERR\n");
    case AUDIO_SERVER_EVENT_END:
        log_i("tone: AUDIO_SERVER_EVENT_END\n");
        r.dec.cmd = AUDIO_DEC_STOP;
        server_request(priv, AUDIO_REQ_DEC, &r);
        server_close(priv); //priv是server_register_event_handler_to_task的priv参数
        fclose((FILE *)argv[1]); //argv[1]是解码开始时传递进去的文件句柄
        key_event_enable();
        //等提示音播完了再切换模式
        struct intent it;
        init_intent(&it);
        it.name = audio_app_table[mode_index++].app_name;
        start_app(&it);
        break;
    case AUDIO_SERVER_EVENT_CURR_TIME:
        log_i("play_time: %d\n", argv[1]);
        break;
    default:
        break;
    }
}

设计意图:这里体现了两个关键约定——(1) 事件回调通过 argv[0] 区分事件类型,argv[1] 传递解码开始时传入的文件句柄,priv 是 server_register_event_handler_to_task 注册时传入的服务器句柄;(2) 模式切换必须等提示音播完(AUDIO_SERVER_EVENT_END 回调内)才执行 start_app,避免在音频服务器仍占用资源时切换应用导致冲突。

核心流程:示例应用的启动与模式切换

以 audio_demo 为例,公共示例工程的完整运行流程遵循"按键事件 → 播放提示音 → 事件回调 → 应用切换"的时序。图中 audio_app_table 的下标 mode_index 每切换一次递增,循环遍历已使能的模式:

sequenceDiagram
    participant U as 用户按键
    participant KE as main_key_event_handler
    participant AM as audio_demo_mode_switch
    participant PS as app_play_tone_file
    participant SRV as audio_server
    participant DSE as dec_server_event_handler
    participant AC as app_core (start_app)

    U->>KE: KEY_EVENT_CLICK / KEY_MODE
    KE->>AM: audio_demo_mode_switch()
    AM->>PS: app_play_tone_file(tone_file_name)
    PS->>SRV: server_request(AUDIO_REQ_DEC, ...)
    SRV-->>DSE: AUDIO_SERVER_EVENT_END (argv[1]=FILE*)
    DSE->>SRV: server_request(AUDIO_DEC_STOP) + server_close
    DSE->>DSE: fclose(file) + key_event_enable()
    DSE->>AC: init_intent + start_app(audio_app_table[mode_index++].app_name)
    AC-->>U: 进入下一应用模式(local_music → net_music → recorder → ai_speaker)

提示音的发起由 app_play_tone_file 完成——它打开音频文件、构造 audio_req 请求并通过 server_request 提交给音频解码服务器,同时把文件句柄作为参数随请求传递,供回调结束时释放:

Source: main.c

//播放提示音
static int app_play_tone_file(const char *path)
{
    int err = 0;
    union audio_req req = {0};

    log_d("play tone file : %s\n", path);

    FILE *file = fopen(path, "r");
    ...
}

示例工程的生命周期总览

从编译到运行,公共示例经历以下阶段:

flowchart TD
    Start([工程配置]) --> Build{"app_config.h 使能宏"}
    Build -->|"USE_AUDIO_DEMO 等已定义"| Compile["示例代码参与编译"]
    Build -->|"未定义"| Skip["示例被排除出固件"]
    Compile --> Boot["系统启动,app_core 初始化"]
    Boot --> Reg["示例注册事件处理器"]
    Reg --> Wait["进入事件驱动主循环"]
    Wait --> Ev{"事件到达?"}
    Ev -->|"按键事件"| Key["main_key_event_handler"]
    Ev -->|"设备事件"| Dev["main_dev_event_handler"]
    Ev -->|"网络事件"| Net["main_net_event_hander"]
    Key --> Action["执行业务动作<br/>如 audio_demo_mode_switch"]
    Dev --> Action
    Net --> Action
    Action --> Wait

配置选项

公共示例的编译与行为主要由 app_config.h 中的宏控制。下表汇总了 audio_demo 中可直接观察到的配置项(其他示例遵循相同模式,具体宏名以各示例头文件为准):

配置宏作用范围默认状态说明
USE_AUDIO_DEMO编译期关闭使能 audio_demo 综合示例,未定义时 main.c 整体不参与编译
CONFIG_NET_ENABLE编译期关闭使能网络功能,决定 main_net_event_hander 等网络代码是否编译
CONFIG_LOCAL_MUSIC_MODE_ENABLE编译期关闭在 audio_app_table 中启用 local_music(本地音乐)模式,提示音 FlashMusic.mp3
CONFIG_NET_MUSIC_MODE_ENABLE编译期关闭启用 net_music(网络音乐)模式,提示音 NetMusic.mp3
CONFIG_RECORDER_MODE_ENABLE编译期关闭启用 recorder(录音)模式,提示音 Recorder.mp3
CONFIG_ASR_ALGORITHM_ENABLE编译期关闭启用 ai_speaker(AI 音箱/ASR)模式,提示音 AiSpeaker.mp3

配置要点:模式表采用条件编译组装,因此"未使能模式对应的代码模块"同样不会被链接,固件体积随使能模式数量线性增长。新增一个模式时,开发者只需在表中追加一条 {提示音, app_name} 条目,并提供同名 .c 应用文件即可。

API 参考(来自 audio_demo 示例)

以下签名均提取自 apps/common/example/audio/audio_demo/main.c 实际代码,是编写自定义示例时最常复用的接口模式:

main_key_event_handler(struct key_event *key): int

按键事件回调入口。返回 true 表示事件已消费,false 表示未处理、交由框架继续分发。

  • 参数:key — 按键事件对象,含 action(KEY_EVENT_CLICK / KEY_EVENT_LONG)与 value(如 KEY_MODE)。
  • 返回:int(true/false)。

dec_server_event_handler(void *priv, int argc, int *argv): void

音频服务器事件回调,通过 argv[0] 区分事件类型。

  • 参数:priv — 服务器句柄(注册时传入);argc — 参数个数;argv — 参数数组,argv[0] 为事件类型(AUDIO_SERVER_EVENT_END / AUDIO_SERVER_EVENT_ERR / AUDIO_SERVER_EVENT_CURR_TIME),argv[1] 为解码文件句柄或播放时间。
  • 典型动作:server_request(priv, AUDIO_REQ_DEC, &r)(停止解码)、server_close(priv)、fclose((FILE *)argv[1])、key_event_enable()、init_intent(&it) + start_app(&it)。

app_play_tone_file(const char *path): int

播放提示音文件。打开 path 指向的音频文件,构造 union audio_req 并通过 server_request 提交解码。

  • 参数:path — 音频文件路径(如 "FlashMusic.mp3")。
  • 返回:int(错误码)。

init_intent(struct intent *it) / start_app(struct intent *it)

应用切换原语。init_intent 初始化意图结构体,设置 it.name 为目标应用名后调用 start_app 拉起新应用。audio_app_table[mode_index++].app_name 即通过此机制实现模式轮转。

失败模式与边界情况

根据 audio_demo/main.c 的实现可以归纳出公共示例工程中常见且必须处理的边界与失败场景:

  • 提示音播放失败/中断:解码出错时服务器会回调 AUDIO_SERVER_EVENT_ERR。代码将 AUDIO_SERVER_EVENT_ERR 与 AUDIO_SERVER_EVENT_END 合并处理(fall-through),保证无论提示音正常结束还是出错,都会执行 server_close、fclose 与 key_event_enable,避免资源泄漏和按键被永久禁用。这一"错误与正常路径共用清理代码"的模式值得在自定义示例中沿用。
  • 模式表越界:mode_index++ 直接作为 audio_app_table 下标使用,因此 audio_app_table[] 中未初始化的数组元素(如仅使能一个模式时)不会导致越界——但表元素数量必须与使能宏严格一致,新增模式而忘记配置宏会导致数组长度不匹配的隐患。
  • 资源双重释放风险:文件句柄 argv[1] 由事件回调负责 fclose,而解码请求本身通过 server_request(AUDIO_DEC_STOP) 停止——两者必须按"先停请求、再关句柄"的顺序执行,先 fclose 后停止解码可能造成服务器在已关闭的句柄上继续读写。
  • 按键与应用的竞态:播放提示音期间按键被禁用(key_event_enable 前的状态),提示音结束后才重新使能,防止用户在模式切换过程中再次触发切换导致状态错乱。自定义示例若需快速连续切换,需自行设计防抖或队列机制。
  • 网络代码的条件编译:main_net_event_hander 仅在 CONFIG_NET_ENABLE 下编译。若在未使能网络的固件中引用了 NET_EVENT_* 相关符号,会直接编译失败;反之在使能网络的工程中遗漏 CONFIG_NET_ENABLE 则不会有任何网络事件被处理。

性能与运维注意事项

  • Flash 占用:每个模式的提示音文件(FlashMusic.mp3、NetMusic.mp3 等)需随固件烧录到 Flash。示例中提示音文件名以字符串字面量写死在表中,实际方案中建议通过资源打包工具统一管理,避免文件名不一致导致 fopen 失败。
  • 音频服务器资源:server_request/server_close 是异步请求,解码任务运行在独立服务器任务上下文中,示例回调中不应执行耗时操作(如长时间阻塞 I/O),以免阻塞服务器任务影响其他音频请求。
  • 事件回调执行上下文:事件处理器运行在系统事件分发上下文中,代码应保持轻量——audio_demo 中各处理器仅做分发,实际业务(如模式切换、文件操作)落在后续调用中,这种设计避免了在事件上下文中做重活导致的系统卡顿。

扩展点

公共示例工程的设计为开发者预留了清晰的扩展路径:

  1. 新增子应用模式:在 audio_app_table 中追加 {"提示音文件", "app_name"} 条目,并以该 app_name 编写独立的 xxx.c 应用文件(参考 local_music.c、recorder.c 等),同时通过 start_app 注册应用名。
  2. 新增整个示例工程:在 apps/common/example/<类别>/ 下新建目录并编写 main.c,在 app_config.h 中定义对应的使能宏,参照 USE_AUDIO_DEMO 的 #ifdef 包裹方式接入构建系统。
  3. 接入新的网络协议:network_protocols/ 下的 coap、http、mqtt 示例展示了统一的协议接入模式——在 CONFIG_NET_ENABLE 基础上注册网络事件,示例可作为协议栈移植的起点。
  4. BLE Mesh 平台对接:apps/common/ble/mesh/examples 中的 AliGenie_*、TUYA_light 示例展示了如何基于 provisioner.c 与 provisioner_config.h 对接天猫精灵、涂鸦等云平台,新增平台时可在同目录复制改造。

测试情况说明

公共示例工程面向"开箱演示"与"二次开发起点"两个目标,仓库中示例代码以演示与移植为主(如 Devkitboard_test 即开发板硬件自检程序)。示例目录下未发现独立的单元测试文件——功能验证主要依赖目标板上运行的集成验证(如按键切换模式、播放提示音、网络连接等手工验证路径)。audio_demo 的事件回调中大量 log_i/log_d 日志(如 "tone: AUDIO_SERVER_EVENT_END"、"play_time: %d")即为板端调试定位的主要手段,开发者可通过串口日志观察运行轨迹。

Related Links

  • SDK 概述与快速开始(README)
  • audio_demo 综合示例源码
  • BLE Mesh 示例目录
  • 文档中心(SDK 在线开发文档):https://doc.zh-jieli.com/AC79/zh-cn/release_v1.2.0/index.html
  • 姊妹页面:音频服务器框架(server/audio_server)、网络协议栈(lwIP/mbedTLS 集成)、BLE Mesh 协议栈
Prev
文档与规格书
Next
UI 资源工程与打包