1. 概述
AG SDK介绍请查阅相关页面。本文主要指导在从芯片原厂授权服务商和阿里获取到代码后,如何创建代码工程。
代码主要托管到 阿里云云效代码管理 Codeup , 以下是一些您可能感兴趣的链接:
代码托管官网:https://codeup.aliyun.com 快速开始:https://help.aliyun.com/document_detail/153705.html 快速开始-创建第一个代码库:https://help.aliyun.com/document_detail/153707.html 快速开始-提交第一行代码:https://help.aliyun.com/document_detail/153708.html 操作指南:https://help.aliyun.com/document_detail/153718.html 操作指南-邀请成员协作:https://help.aliyun.com/document_detail/153719.html 操作指南-代码组:https://help.aliyun.com/document_detail/153720.html 操作指南-代码评审-合并请求:https://help.aliyun.com/document_detail/153872.html Git教学:https://help.aliyun.com/document_detail/153799.html
2. 代码结构
整个工程代码分为三部分,BSP + 阿里仓库 + 您的代码。BSP 的代码由芯片原厂授权服务商提供,最新版本的阿里核心能力库从阿里获取。
2.1 目录说明
整个工程涉及多个仓库,并有固定的路径,在编写 manifest.xml 时请不要肆意修改 clone 路径。以下表格描述了涉及的所有仓库、路径以及技术支持方等信息。
仓库名 | clone 目标路径 | 技术支持 | 补充信息 |
---|---|---|---|
aligenieSDK_alg | ${TOP}/aligenieSDK_alg | 阿里 | 算法库 |
project | ${TOP}/project | 阿里 | 工程文件 |
aligenieSDK | ${TOP}/aligenieSDK | 阿里 | 核心库 |
toolchain | ${TOP}/toolchain | 恒玄 | BSP |
kernel | ${TOP}/kernel | 恒玄 | BSP |
vendor | ${TOP}/vendor | 恒玄 | BSP |
build | ${TOP}/build | 恒玄 | BSP |
component | ${TOP}/component | 恒玄 | BSP |
thirdparty_app | ${TOP}/thirdparty_app | ISV/TSP开发商 | 三方二次开发代码 |
2.2 Demo试跑
本AG SDK提供了demo演示,代码位于project/genie_tg6000a/app_entry.c,通过ag_open_api_demo_init启动相关demo。
static int ag_open_api_demo_init()
{
ag_play_cmd_init();
ag_event_cmd_init();
ag_input_cmd_init();
ag_os_cmd_init();
ag_talk_cmd_init();
ag_gatts_cmd_init();
ag_bt_cmd_init();
ag_clock_cmd_init();
httpclient_cli_register();
return 0;
}
int application_start(int argc, char *argv[])
{
。。。
//AligenieSDK初始化
ag_open_api_init();
//demo初始化
ag_open_api_demo_init();
。。。
}
3. 添加自定义应用
3.1 应用入口
project/目录下为产品应用代码入口,BSP初始化完成后会运行到project/genie_tg6000a/app_entry.c,调用应用入口函数:application_start。入口函数会依次启动看门狗、初始化AligenieSDK、初始化Demo,最后拉起二次开发应用逻辑。
void __attribute__((weak)) third_party_init(void)
{
LOGE(TAG, "[TODO] need implement\n");
}
static int ag_open_api_demo_init()
{
ag_play_cmd_init();
ag_event_cmd_init();
ag_input_cmd_init();
ag_os_cmd_init();
ag_talk_cmd_init();
ag_gatts_cmd_init();
ag_bt_cmd_init();
ag_clock_cmd_init();
httpclient_cli_register();
return 0;
}
int application_start(int argc, char *argv[])
{
//看门狗初始化
watchdog_start(NULL);
//AligenieSDK初始化
ag_open_api_init();
//demo初始化
ag_open_api_demo_init();
//自定义应用入口
third_party_init();
aos_loop_run();
}
3.2 接口约定
为了更方便的构建固件,二次开发的代码逻辑统一使用third_party_init()拉起,所有二次开发逻辑都隐藏到这个api里。third_party_init()参考示例代码位于thirdparty_app/thirdparty_entry.c。
void third_party_init(void);
3.3 thirdparty_app工程约定
目前,该实例工程包含aos.mk test.c test.h thirdparty_entry.c ProdConfInfo.cpp ProdConfInfo.h等主要文件,其中test.为二次开发的示例码,ProdConfInfo.为平台上的产品配置信息,aos.mk为编译配置脚本,内容如下所示:
NAME := thirdparty_app
$(NAME)_MBINS_TYPE := app
$(NAME)_VERSION := 1.0.0
$(NAME)_SUMMARY := third party app
$(NAME)_INCLUDES += .
$(NAME)_INCLUDES += ../aligenieSDK/inc/
$(NAME)_INCLUDES += ../../kernel/include/posix/
$(NAME)_SOURCES := thirdparty_entry.c
$(NAME)_SOURCES += test.c
$(NAME)_SOURCES += ProdConfInfo.cpp
其中,
1、NAME的值不要修改
2、$(NAME)_INCLUDES用来配置引用头文件的路径,按需增删即可。比如增加一项../aligenieSDK/inc/,那么在该工程下的源代码,就可以直接include AligenieSDK头文件,然后调用其中的各个api了。
3、$(NAME)_SOURCES用来配置二次开发涉及的源文件,按需增删即可。
4. 修改产品配置信息
从上一章我们已经知道,thirdparty_app中的ProdConfInfo.为平台上的产品配置信息。如下所示,*我们默认提供的是木星标准模组Pro2(混天绫模组)的产品信息,因此本地默认构建出来的固件,是需要使用木星标准模组Pro2或者基于木星标准模组Pro2创建产品的一机一密才能正常配网的。
#ifndef __PRODCONF_INFO_H__
#define __PRODCONF_INFO_H__
#ifdef __cplusplus
extern "C" {
#endif
#define PROD_FIRMWARE_VERSION "1.0.0-D-00000000.0000"
#define PROD_BIZ_TYPE "AILABS"
#define PROD_BIZ_GROUP "S710"
#define PROD_NET_CONFIG_ID "9Oup"
#define PROD_DEF_VOLUME "60"
#define PROD_MAX_VOLUME "100"
#define PROD_MIN_VOLUME "20"
/*
* To make genie be independent static library(.a),
* move all product information out by calling function outside.
*/
const char *getProdBizType(void);
const char *getProdBizGroup(void);
const char *getProdNetConfigID(void);
const char *getProdDefVolume(void);
const char *getProdMaxVolume(void);
const char *getProdMinVolume(void);
const char *tg_ota_get_version(void);
#ifdef PROD_AES1_SECRET
const char *getProdAes1Secret(void);
#endif
#ifdef PROD_AES1_IV
const char *getProdAes1Iv(void);
#endif
#ifdef PROD_AES2_SECRET
const char *getProdAes2Secret(void);
#endif
#ifdef PROD_AES2_IV
const char *getProdAes2Iv(void);
#endif
#ifdef PROD_PUB_KEY
char *tg_ota_get_pubkey(void);
#endif
#ifdef __cplusplus
}
#endif
#endif
从天猫精灵AI平台 的平台构建入口打包固件时,平台会自动将ProdConfInfo.h中默认的木星标准模组Pro2配置信息替换为对应产品的真正配置信息(如BizType、BizGroup、NetConfigId等)。如果需要使用基于语音芯片TG6000A(SDK版)方案创建产品之后生成的三元组配网,本地需要配置ProdConfInfo.h重新编译打包固件才能正常配网。修改方法如下:
4.1 配置版本号
编译脚本会自动基于当前时间生成版本号,并自动更新PROD_FIRMWARE_VERSION的值,无需手动修改(即使修改也会被编译脚本自动覆盖)
4.2 配置BizType、BizGroup
BizGroup和BizType指的是设备机型,相关信息可以在天猫精灵AI平台的对应产品的开发页面找到,对应修改PROD_BIZ_GROUP和PROD_BIZ_TYPE的值。
4.3 配置蓝牙广播ID
蓝牙广播ID用于设备配网时APP发现设备,相关信息可以在天猫精灵AI平台的对应产品的开发 - APP配置 - 激活联网信息页面找到,对应修改PROD_NET_CONFIG_ID的值即可。
4.4 配置音量
目前支持配置默认音量、最大音量、最小音量,相关信息可以在天猫精灵AI平台的对应产品的开发 - 产品信息 - 开发方案页面找到,对应修改PROD_DEF_VOLUME、PROD_MAX_VOLUME、PROD_MIN_VOLUME的值即可。
4.5 配置加解密秘钥
解密秘钥用于从三元组Secret Key中解析出设备UUID,加密秘钥用于设备鉴权激活时的签名计算,相关信息可以在天猫精灵AI平台的对应产品的开发 - 产品信息 - 基本信息页面找到,然后在ProdConfInfo.h中新增如下四行(自行替换为平台上的对应值):
#define PROD_AES1_SECRET "三元组解密秘钥的密钥"
#define PROD_AES1_IV "三元组解密秘钥的偏移量"
#define PROD_AES2_SECRET "签名加密密钥的秘钥"
#define PROD_AES2_IV "签名加密密钥的偏移量"
:::warning 加解密秘钥,请注意保密,请勿泄漏!!! :::
4.6 最终示例
按上述步骤修改完产品配置信息之后,会得到类似如下所示的一个文件,然后本地重新编译固件之后,即可使用新开发方案的三元组进行配网了。
#ifndef __PRODCONF_INFO_H__
#define __PRODCONF_INFO_H__
#ifdef __cplusplus
extern "C" {
#endif
#define PROD_FIRMWARE_VERSION "1.0.0-D-00000000.0000"
#define PROD_AES1_SECRET "bcb68d82XXXXXXXX"
#define PROD_AES1_IV "2df26bb6XXXXXXXX"
#define PROD_AES2_SECRET "eee0eef4XXXXXXXX"
#define PROD_AES2_IV "ef086606XXXXXXXX"
#define PROD_BIZ_TYPE "AILABS"
#define PROD_BIZ_GROUP "TGChip6000A"
#define PROD_NET_CONFIG_ID "gWHQ"
#define PROD_DEF_VOLUME "60"
#define PROD_MAX_VOLUME "100"
#define PROD_MIN_VOLUME "0"
/*
* To make genie be independent static library(.a),
* move all product information out by calling function outside.
*/
const char *getProdBizType(void);
const char *getProdBizGroup(void);
const char *getProdNetConfigID(void);
const char *getProdDefVolume(void);
const char *getProdMaxVolume(void);
const char *getProdMinVolume(void);
const char *tg_ota_get_version(void);
#ifdef PROD_AES1_SECRET
const char *getProdAes1Secret(void);
#endif
#ifdef PROD_AES1_IV
const char *getProdAes1Iv(void);
#endif
#ifdef PROD_AES2_SECRET
const char *getProdAes2Secret(void);
#endif
#ifdef PROD_AES2_IV
const char *getProdAes2Iv(void);
#endif
#ifdef PROD_PUB_KEY
char *tg_ota_get_pubkey(void);
#endif
#ifdef __cplusplus
}
#endif
#endif
4.7 注意事项(必读!!!)
不同开发方案的三元组不通用。所以如果平台上创品时,最开始使用的不是语音芯片TG6000A(SDK版)方案,后来修改为了语音芯片TG6000A(SDK版)方案,那么需要重新生成三元组,设备写入新的一机一密,设备重新配网。