概述*
文档简要介绍 GX8006 WiFi 语音大模型方案的SDK获取步骤及开发环境搭建方法,助您快速开始开发。
1. 获取SDK*
注册GitLab
GX8006 WiFi 语音大模型方案的 SDK 部署在我司的 GitLab 服务器上,开发者需要注册后才可拉取相关代码进行二次开发,注册教程参考 注册GitLab
注册完毕并且通过审核,将会在群组 Voice WiFi Solution
下看到以下两个 SDK:
- lighting :基于 LN882H WiFi 芯片开发的大模型方案 SDK
- ovp_aiot :基于 GX8006 语音芯片开发的大模型方案 SDK
2. 搭建开发环境*
2.1. ovp_aiot 开发环境搭建*
ovp_aiot 的开发环境搭建详见 GX8006 SDK 开发环境搭建
2.2. lighting 开发环境搭建*
注意
当前 SDK 仅维护 CMake + GCC
的构建方式,SDK 中的 Keil 工程文件为亮牛 SDK 保留,并不支持直接编译,用户如果需要使用 Keil 构建项目,需要自行参考 project
下的 CMakeLists.txt
添加相关源码到工程中
2.2.1 相关软件说明*
- Python3:构建中使用 python 脚本,且SDK路径不能包含中文,不支持 Python2
- ARM GCC 工具链:选用ARM官方的 GNU Arm Embedded Toolchain: 10-2020-q4-major 版本
- CMake:根据所选生成器生成对应的 Makefile 文件或者 build.ninja 文件。推荐版本 >= 3.16
- Ninja:构建工具,处理 CMake 生成的 build.ninja 文件
- Make:读取 CMake 生成的 Makefile 文件,调用编译器套件生成目标
- SEGGER JLink:可选,用于烧录固件,也可以启动GDB调试服务器,推荐安装 V752d 及以下版本
- 亮牛串口烧录工具:可选,用于从串口烧录固件,相关资料参考 LN882H文档资料集合
- Visual Studio Code:可选
提示
以上软件根据需要选择安装
2.2.2. 基于 Ubuntu 20.04 x64 的安装说明*
- 使用包管理器安装必要依赖软件
sudo apt install python3 cmake ninja-build make
- 安装交叉编译工具链
- 点击链接下载 gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2
- 解压工具链,
sudo tar -xf gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2 -C /opt
- 配置环境变量
export CROSS_TOOLCHAIN_ROOT=/opt/gcc-armnone-eabi-10-2020-q4-major
,可添加到自定义脚本或./.bashrc
否则每次打开新的 shell 环境都需要配置该环境变量
- SEGGER JLink(可选)
- 点击连接下载 v7.52d 64-bit DEB Installer
- 安装
sudo dpkg -i JLink_Linux_V752d_x86_64.deb
2.2.3. 基于 VSCode+GDB 的调试环境搭建说明*
- 完成上述 基于 Ubuntu 20.04 x64 的安装
- 自行安装VSCode及以下插件
- C/C++ IntelliSense
- CMake
- CMake Tools
- Cortex-Debug
- 将 JLink 调试器连接PC,测试调试器是否连接:
(base) zhuhy@zhuhy-lenovo:~$ lsusb Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub Bus 001 Device 002: ID 1366:0101 SEGGER J-Link PLUS Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
- 打开 SDK 根目录下的
CMakeLists.txt
,找到如下区域,修改编译类型为Debug# set(CMAKE_BUILD_TYPE Release CACHE STRING "build for release" FORCE) set(CMAKE_BUILD_TYPE Debug CACHE STRING "build for debug" FORCE)
- 重新编译并烧录 build-ln_model_public-debug 下的固件到 LN882H
- 新建
.vscode/launch.json
内容如下,其中serverpath
修改为 JLink 安装的路径,armToolchainPath
修改为工具链安装的路径{ // 使用 IntelliSense 了解相关属性。 // 悬停以查看现有属性的描述。 // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "name": "Cortex Debug", "type": "cortex-debug", "cwd": "${workspaceFolder}", "executable": "${workspaceFolder}/build-ln_model_public-debug/bin/ln_model_public.elf", "request": "attach", "runToEntryPoint": "main", "showDevDebugOutput": "both", "servertype": "jlink", "serverpath": "/usr/bin/JLinkGDBServerCLExe", "device": "Cortex-M4", "interface": "swd", "armToolchainPath": "/opt/gcc-arm-none-eabi-10-2020-q4-major/bin" } ] }
- 开启调试即可在 VSCode 的 UI 界面上进行单步调试
3. 开发指南*
3.1. ovp_aiot 开发指南*
正在开发中
3.2. lighting 开发指南*
3.2.1. 框架介绍*
WiFi 语音大模型的开发方案位于 project/ln_model_public
本方案主要包含三大块:
一是云端对接,即和云端之间的音频双向交互,以及一些控制消息的传输
二是和GX8006语音芯片的交互,即基于串口的双向音频传输及流控,相关控制指令的发送,例如配置播放参数、设置音量等
其次,基于小智云,给出了一套完整的授权和OTA,以及基于MCP实现控制的示例
3.3.2. 云端对接*
云端对接的源码位于 app/servers
- 云端对接抽象出一份接口
app/servers/server_interface.h
,对接不同的云端需要实现这份接口的函数定义, - 和云端的交互被抽象为:
- 连接和断开,以及对应的已连接的回调
- 音频的上传,即实现接收应用层其他模块传入的用户的语音数据,打包成云端指定的格式,推送给云端
- 音频的下载,即实现云端的tts等数据的下载,通过回调函数传递给应用层其他模块
- 相关控制信息的传递,例如音频的启停消息、唤醒词信息、MCP控制消息等
3.3.3. 串口对接GX8006*
串口对接的源码位于 app/smartbot
- 模块向底层提取出两个接口,即一收一发;此部分相对固定,若需要移植请参考 串口协议移植指南
smartbot_on_output
用于注册串口发送函数,模块内部调用该函数向串口输出字节流smartbot_proto_input
用于传入串口接收字节流,模块内部会解析数据帧,
注意
此接口会短暂关闭中断,用于向 ringbuffer 拷贝数据,但其后的协议解析行为在线程上下文中进行
- 模块向应用层提取出两个播放接口,分别用于播放本地音频和云端音频
- 本地音频存储于 Flash 代码段,播放时仅提供对应 ID,本模块会自动推送相对应的音频
- 云端音频缓冲在 RAM 区域,播放时云端模块将数据传入该缓冲,本模块自动处理和GX8006的串口交互
- 本地播报优先级高于云端播报
- 本模块的整体框架示意图如下:
3.2.4. 授权管理*
提示
当前以小智的授权管理为例,不同云端请根据实际情况进行实现
本方案的授权管理有两个步骤
- 步骤一:
- 出厂时,通过向授权服务器POST请求,附带自身唯一标识
- 解析返回的数据,提取加密秘钥和唯一标识
- 本地OTP或Flash特殊区域写入秘钥
- 步骤二:
- 用户端启动设备后,检查自身是否有合法的秘钥,否则不执行后续应用代码
- 通过向服务器POST请求,附带经秘钥加密的challenge信息,由服务器判断是否授权
- 若设备是一个新设备,还未绑定过,服务器返回绑定验证码,用户打开控制台即可绑定设备
- 若设备已绑定,则云端返回交互的 MQTT 连接参数等,设备连接后可建立和云端的交互
3.2.5. OTA*
由于本方案包含两颗芯片,因此OTA部分分为两部分,GX8006 部分和 LN882H 部分
在本 OTA 方案中,LN882H 作为主机,主导两颗芯片的升级工作
3.2.5.1. GX8006*
GX8006 OTA 通过和 LN882H 连接的串口实现裸片升级,即和开发时PC上位机通过串口烧录固件的原理一致,本方案实现了基于 HTTP 的流式 OTA
OTA 的源码位于 project/ln_model_public/app/ota
,GX8006 的裸片升级协议实现位于 project/ln_model_public/modules/gx_fornax_boot
,
裸片升级的具体流程可参考 串口裸机升级参考例程
3.2.5.2. LN882H*
正在开发中
3.2.6. MCP*
小智的 MCP 实现在 project/ln_model_public/app/servers/xiaozhi/mcp.c
中,目前添加了获取设备状态信息和设置音量的工具
支持可配置的独立线程执行,通过将 call_in_task
设置为 true
即可在大模型调用此工具时,自动建立一条线程来执行相关的函数
用户可根据需要建立自定义工具,配合合适的提示词,实现基于大模型的控制需求
static mcp_tool_t mcp_tools[] = {
{
.name = "self.get_device_status",
.description =
"Provides the real-time information of the device, including the current status of the audio speaker, screen, battery, network, etc.\n"
"Use this tool for: \n"
"1. Answering questions about current condition (e.g. what is the current volume of the audio speaker?)\n"
"2. As the first step to control the device (e.g. turn up / down the volume of the audio speaker, etc.)",
.call = mcp_tool_handle_get_device_status,
.call_in_task = false
},
{
.name = "self.audio_speaker.set_volume",
.description =
"Set the volume of the audio speaker. If the current volume is unknown, you must call `self.get_device_status` tool first and then call this tool.",
.call = mcp_tool_handle_set_volume,
.call_in_task = false,
.properties = {
{
.name = "volume",
.type = kPropertyTypeInteger,
.has_min_value = true,
.min_value = 0,
.has_max_value = true,
.max_value = 100
}
}
},
{
.name = NULL
}
};