第五步介绍AG SDK结构和如何开发自有应用程序。

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。

  1. static int ag_open_api_demo_init()
  2. {
  3. ag_play_cmd_init();
  4. ag_event_cmd_init();
  5. ag_input_cmd_init();
  6. ag_os_cmd_init();
  7. ag_talk_cmd_init();
  8. ag_gatts_cmd_init();
  9. ag_bt_cmd_init();
  10. ag_clock_cmd_init();
  11. httpclient_cli_register();
  12. return 0;
  13. }
  14. int application_start(int argc, char *argv[])
  15. {
  16. 。。。
  17. //AligenieSDK初始化
  18. ag_open_api_init();
  19. //demo初始化
  20. ag_open_api_demo_init();
  21. 。。。
  22. }

3. 添加自定义应用

3.1 应用入口

project/目录下为产品应用代码入口,BSP初始化完成后会运行到project/genie_tg6000a/app_entry.c,调用应用入口函数:application_start。入口函数会依次启动看门狗、初始化AligenieSDK、初始化Demo,最后拉起二次开发应用逻辑。

  1. void __attribute__((weak)) third_party_init(void)
  2. {
  3. LOGE(TAG, "[TODO] need implement\n");
  4. }
  5. static int ag_open_api_demo_init()
  6. {
  7. ag_play_cmd_init();
  8. ag_event_cmd_init();
  9. ag_input_cmd_init();
  10. ag_os_cmd_init();
  11. ag_talk_cmd_init();
  12. ag_gatts_cmd_init();
  13. ag_bt_cmd_init();
  14. ag_clock_cmd_init();
  15. httpclient_cli_register();
  16. return 0;
  17. }
  18. int application_start(int argc, char *argv[])
  19. {
  20. //看门狗初始化
  21. watchdog_start(NULL);
  22. //AligenieSDK初始化
  23. ag_open_api_init();
  24. //demo初始化
  25. ag_open_api_demo_init();
  26. //自定义应用入口
  27. third_party_init();
  28. aos_loop_run();
  29. }

3.2 接口约定

为了更方便的构建固件,二次开发的代码逻辑统一使用third_party_init()拉起,所有二次开发逻辑都隐藏到这个api里。third_party_init()参考示例代码位于thirdparty_app/thirdparty_entry.c。

  1. 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为编译配置脚本,内容如下所示:

  1. NAME := thirdparty_app
  2. $(NAME)_MBINS_TYPE := app
  3. $(NAME)_VERSION := 1.0.0
  4. $(NAME)_SUMMARY := third party app
  5. $(NAME)_INCLUDES += .
  6. $(NAME)_INCLUDES += ../aligenieSDK/inc/
  7. $(NAME)_INCLUDES += ../../kernel/include/posix/
  8. $(NAME)_SOURCES := thirdparty_entry.c
  9. $(NAME)_SOURCES += test.c
  10. $(NAME)_SOURCES += ProdConfInfo.cpp

其中,
1、NAME的值不要修改
2、$(NAME)_INCLUDES用来配置引用头文件的路径,按需增删即可。比如增加一项../aligenieSDK/inc/,那么在该工程下的源代码,就可以直接include AligenieSDK头文件,然后调用其中的各个api了。
3、$(NAME)_SOURCES用来配置二次开发涉及的源文件,按需增删即可。

4. 修改产品配置信息

从上一章我们已经知道,thirdparty_app中的ProdConfInfo.为平台上的产品配置信息。如下所示,*我们默认提供的是木星标准模组Pro2(混天绫模组)的产品信息,因此本地默认构建出来的固件,是需要使用木星标准模组Pro2或者基于木星标准模组Pro2创建产品的一机一密才能正常配网的。

  1. #ifndef __PRODCONF_INFO_H__
  2. #define __PRODCONF_INFO_H__
  3. #ifdef __cplusplus
  4. extern "C" {
  5. #endif
  6. #define PROD_FIRMWARE_VERSION "1.0.0-D-00000000.0000"
  7. #define PROD_BIZ_TYPE "AILABS"
  8. #define PROD_BIZ_GROUP "S710"
  9. #define PROD_NET_CONFIG_ID "9Oup"
  10. #define PROD_DEF_VOLUME "60"
  11. #define PROD_MAX_VOLUME "100"
  12. #define PROD_MIN_VOLUME "20"
  13. /*
  14. * To make genie be independent static library(.a),
  15. * move all product information out by calling function outside.
  16. */
  17. const char *getProdBizType(void);
  18. const char *getProdBizGroup(void);
  19. const char *getProdNetConfigID(void);
  20. const char *getProdDefVolume(void);
  21. const char *getProdMaxVolume(void);
  22. const char *getProdMinVolume(void);
  23. const char *tg_ota_get_version(void);
  24. #ifdef PROD_AES1_SECRET
  25. const char *getProdAes1Secret(void);
  26. #endif
  27. #ifdef PROD_AES1_IV
  28. const char *getProdAes1Iv(void);
  29. #endif
  30. #ifdef PROD_AES2_SECRET
  31. const char *getProdAes2Secret(void);
  32. #endif
  33. #ifdef PROD_AES2_IV
  34. const char *getProdAes2Iv(void);
  35. #endif
  36. #ifdef PROD_PUB_KEY
  37. char *tg_ota_get_pubkey(void);
  38. #endif
  39. #ifdef __cplusplus
  40. }
  41. #endif
  42. #endif

天猫精灵AI平台 的平台构建入口打包固件时,平台会自动将ProdConfInfo.h中默认的木星标准模组Pro2配置信息替换为对应产品的真正配置信息(如BizType、BizGroup、NetConfigId等)。如果需要使用基于语音芯片TG6000A(SDK版)方案创建产品之后生成的三元组配网,本地需要配置ProdConfInfo.h重新编译打包固件才能正常配网。修改方法如下:

4.1 配置版本号

编译脚本会自动基于当前时间生成版本号,并自动更新PROD_FIRMWARE_VERSION的值,无需手动修改(即使修改也会被编译脚本自动覆盖)

4.2 配置BizType、BizGroup

image.png
BizGroup和BizType指的是设备机型,相关信息可以在天猫精灵AI平台的对应产品的开发页面找到,对应修改PROD_BIZ_GROUP和PROD_BIZ_TYPE的值。

4.3 配置蓝牙广播ID

image.png
蓝牙广播ID用于设备配网时APP发现设备,相关信息可以在天猫精灵AI平台的对应产品的开发 - APP配置 - 激活联网信息页面找到,对应修改PROD_NET_CONFIG_ID的值即可。

4.4 配置音量

image.png
目前支持配置默认音量、最大音量、最小音量,相关信息可以在天猫精灵AI平台的对应产品的开发 - 产品信息 - 开发方案页面找到,对应修改PROD_DEF_VOLUME、PROD_MAX_VOLUME、PROD_MIN_VOLUME的值即可。

4.5 配置加解密秘钥

image.png
解密秘钥用于从三元组Secret Key中解析出设备UUID,加密秘钥用于设备鉴权激活时的签名计算,相关信息可以在天猫精灵AI平台的对应产品的开发 - 产品信息 - 基本信息页面找到,然后在ProdConfInfo.h中新增如下四行(自行替换为平台上的对应值):

  1. #define PROD_AES1_SECRET "三元组解密秘钥的密钥"
  2. #define PROD_AES1_IV "三元组解密秘钥的偏移量"
  3. #define PROD_AES2_SECRET "签名加密密钥的秘钥"
  4. #define PROD_AES2_IV "签名加密密钥的偏移量"

:::warning 加解密秘钥,请注意保密,请勿泄漏!!! :::

4.6 最终示例

按上述步骤修改完产品配置信息之后,会得到类似如下所示的一个文件,然后本地重新编译固件之后,即可使用新开发方案的三元组进行配网了。

  1. #ifndef __PRODCONF_INFO_H__
  2. #define __PRODCONF_INFO_H__
  3. #ifdef __cplusplus
  4. extern "C" {
  5. #endif
  6. #define PROD_FIRMWARE_VERSION "1.0.0-D-00000000.0000"
  7. #define PROD_AES1_SECRET "bcb68d82XXXXXXXX"
  8. #define PROD_AES1_IV "2df26bb6XXXXXXXX"
  9. #define PROD_AES2_SECRET "eee0eef4XXXXXXXX"
  10. #define PROD_AES2_IV "ef086606XXXXXXXX"
  11. #define PROD_BIZ_TYPE "AILABS"
  12. #define PROD_BIZ_GROUP "TGChip6000A"
  13. #define PROD_NET_CONFIG_ID "gWHQ"
  14. #define PROD_DEF_VOLUME "60"
  15. #define PROD_MAX_VOLUME "100"
  16. #define PROD_MIN_VOLUME "0"
  17. /*
  18. * To make genie be independent static library(.a),
  19. * move all product information out by calling function outside.
  20. */
  21. const char *getProdBizType(void);
  22. const char *getProdBizGroup(void);
  23. const char *getProdNetConfigID(void);
  24. const char *getProdDefVolume(void);
  25. const char *getProdMaxVolume(void);
  26. const char *getProdMinVolume(void);
  27. const char *tg_ota_get_version(void);
  28. #ifdef PROD_AES1_SECRET
  29. const char *getProdAes1Secret(void);
  30. #endif
  31. #ifdef PROD_AES1_IV
  32. const char *getProdAes1Iv(void);
  33. #endif
  34. #ifdef PROD_AES2_SECRET
  35. const char *getProdAes2Secret(void);
  36. #endif
  37. #ifdef PROD_AES2_IV
  38. const char *getProdAes2Iv(void);
  39. #endif
  40. #ifdef PROD_PUB_KEY
  41. char *tg_ota_get_pubkey(void);
  42. #endif
  43. #ifdef __cplusplus
  44. }
  45. #endif
  46. #endif

4.7 注意事项(必读!!!)

不同开发方案的三元组不通用。所以如果平台上创品时,最开始使用的不是语音芯片TG6000A(SDK版)方案,后来修改为了语音芯片TG6000A(SDK版)方案,那么需要重新生成三元组,设备写入新的一机一密,设备重新配网。