设备初始化

更新时间:2023-06-25 09:08:33下载pdf

初始化是指设备上电、启动之后,调用一系列接口,完成设备硬件环境的初始化、涂鸦 TuyaOS 软件的初始化、应用功能初始化等工作。

概述

基本概念

可独立 OTA 的功能模组:App 上可以展现该功能模组的版本信息,如果配置了升级,则会有相应提示,如 MCU、外挂的语音模组等。

功能描述

一般来说,软件启动会执行 main 函数,对于涂鸦 TuyaOS 来说,不同场景,入口不一样,例如说在 Linux 操作系统环境下,需要自己实现 main 函数。在 RTOS 系统下,需要实现 tuya_app_main 函数,并在函数里对 TuyaOS 软件和设备应用能力进行初始化。

工作原理

  • 设备启动流程

    设备上电
    应用入口
    系统服务初始化
    设备授权
    设备初始化
    注册网络状态回调
    正常运行
  • TuyaOS 系统服务初始化

    日志服务初始化
    本地时钟初始化
    定时服务初始化
    工作队列初始化
    UF 初始化
    KV 初始化
    安全模块初始化
  • 设备初始化

    订阅通用流程事件<初始化完成/复位/运行错误等>
    注册 DP 处理等回调函数
    启动配网/联网/ OTA 等服务

开发指导

关联头文件

  • tuya_iot_com_api.h
  • tuya_iot_wifi_api.h
  • tuya_iot_base_api.h

使用方法

在使用 TuyaOS 其他功能前,必须首先初始化 TuyaOS 系统服务,并根据实际场景设置启动参数。然后,根据设备能力选择具体初始化接口,并注册网络状态回调函数。

数据结构

系统服务初始化参数

  • init_db:TuyaOS 初始化系统服务时,是否初始化 KV 数据存储服务。如果选择不初始化,则后续需要显式调用 tuya_iot_kv_flash_init_param 以使能 KV 数据存储服务。详情请参考下文 FAQ

  • sys_env:系统环境变量(Linux 适用)。

  • log_seq_path:日志序文件存储路径(Linux 适用)。

    /**
    * @brief Definition of TuyaOS init param
    */
    typedef struct {
        /** kv init or not */
        BOOL_T init_db;
        /** sys env settings */
        CHAR_T sys_env[SYS_ENV_LEN];
        /** log seq path */
        CHAR_T log_seq_path[LOG_SEQ_PATH_LEN];
    } TY_INIT_PARAMS_S;
    

IoT 设备功能回调函数

您按需注册相关回调,无需注册的填 NULL 即可。

  • 和设备本身相关

    • gw_status_cb:通知开发者设备激活的状态发生改变。
    • gw_reset_cb:通知开发者设备被重置了。
    • dev_obj_dp_cb:通知开发者有 obj 类型 DP 指令下发。
    • dev_raw_dp_cb:通知开发者有 raw 类型 DP 指令下发。
    • dev_dp_query_cb:通知您需要查询指定 DP 当前的状态。
  • 和设备带的可独立 OTA 的功能模组相关

    • pre_gw_ug_cb:通知开发者,设备带的可独立 OTA 的功能模组有升级请求,开发者通过返回值告诉开发框架当前是否允许升级。

    • gw_ug_cb:通知开发者,设备带的可独立 OTA 的功能模组开始进入升级流程,并告知开发者拉取升级数据时所需的 URL 等必要信息。

      单品类设备的开发者无需关心与子设备相关的回调函数,填 NULL 即可。

  • 和设备下挂的子设备相关

    • pre_dev_ug_cb:通知开发者,设备所属的子设备有升级请求,开发者通过返回值告诉开发框架当前是否允许升级。

    • dev_ug_cb:通知开发者,设备所属的子设备开始进入升级流程,并告知开发者拉取升级数据时所需的 URL 等必要信息。

    • dev_reset_cb:通知开发者,设备所属的子设备被重置了(单品类设备无需关心)。

      Wi-Fi 类和 Wi-Fi 和蓝牙类设备的开发者无需关心与支持扫码设备相关的回调函数,填 NULL 即可。

  • 与支持扫码设备相关

    • active_shorturl:在设备配网时开发框架会返回给开发者 URL。您可以用该 URL 生成图片,让客户端可以通过扫描该图片将设备激活。(仅用于支持扫码的设备)。
    /**
    * @brief Definition of gateway callback functions
    */
    typedef struct {
        /** status update */
        GW_STATUS_CHANGED_CB gw_status_cb;
        /** gateway upgrade */
        GW_UG_INFORM_CB gw_ug_cb;
        /** gateway reset */
        GW_RESET_IFM_CB gw_reset_cb;
        /** structured DP info */
        DEV_OBJ_DP_CMD_CB dev_obj_dp_cb;
        /** raw DP info */
        DEV_RAW_DP_CMD_CB dev_raw_dp_cb;
        /** DP query */
        DEV_DP_QUERY_CB dev_dp_query_cb;
        /** sub-device upgrade */
        DEV_UG_INFORM_CB dev_ug_cb;
        /** sub-device reset */
        DEV_RESET_IFM_CB dev_reset_cb;
        /** active short url */
        ACTIVE_SHORTURL_CB active_shorturl;
        /** gateway upgrade pre-condition */
        GW_UG_INFORM_CB pre_gw_ug_cb;
        /** sub-device upgrade pre-condition */
        DEV_UG_INFORM_CB pre_dev_ug_cb;
    } TY_IOT_CBS_S;
    

API 说明

系统服务初始化

该 API 是 TuyaOS 的系统服务初始化入口,不区分设备类型,有线、Wi-Fi、Wi-Fi 和蓝牙、蜂窝网络都会使用。其内部会对 TuyaOS 的基础服务进行资源分配、初始化。

一般来说,该 API 会第一个调用。但是在某些场景下,需要在此 API 之前进行一些功能配置、事件订阅等工作,从而可以在 TuyaOS 系统服务初始化过程中进行一些特殊的业务逻辑处理。详情请参考下文 FAQ

/**
 * @brief TuyaOS system service init
 *
 * @param[in] fs_storge_path: Storge path of KV database(Linux only)
 * @param[in] p_param: Extra init params, @see TY_INIT_PARAMS_S
 *
 * @return OPRT_OK on success. For others on error, please refer to tuya_error_code.h
 */
OPERATE_RET tuya_iot_init_params(IN CONST CHAR_T *fs_storge_path,
                                 IN CONST TY_INIT_PARAMS_S *p_param);

联网单品设备初始化

该 API 针对具有多个可独立 OTA 的功能模组的设备(如外挂语音模组)进行初始化。

GW_ATTACH_ATTR_T:可独立 OTA 的功能模组的信息。其中 tp 为模组类型:

  • 0~9 表示通用类型
  • 10~19 表示自定义类型

无线设备

GW_WF_CFG_MTHD_SELGW_WF_START_MODE:TuyaOS 开发框架提供的配网方式,满足各种连接方式的配网需求,详情请参考 设备配网模式

/**
 * @brief General Wi-Fi device init(with attached functional facilities)
 *
 * @param[in] cfg: wifi device work mode, @see GW_WF_CFG_MTHD_SEL
 * @param[in] start_mode: wifi netcfg mode, @see GW_WF_START_MODE
 * @param[in] cbs: tuya sdk user callbacks, @see TY_IOT_CBS_S
 * @param[in] firmware_key: the firmware key
 * @param[in] product_key: product key/product ID
 * @param[in] wf_sw_ver: wifi module software version format: xx.xx.xx (0<=x<=9)
 * @param[in] tp: device type, DEV_NM_ATH_SNGL
 * @param[in] attr: attached firmware of this device, @see GW_ATTACH_ATTR_T
 * @param[in] attr_num: number of attached firmwares
 *
 * @return OPRT_OK on success. For others on error, please refer to tuya_error_code.h
 */
OPERATE_RET tuya_iot_wf_dev_init(IN CONST GW_WF_CFG_MTHD_SEL cfg,
                                 IN CONST GW_WF_START_MODE start_mode,
                                 IN CONST TY_IOT_CBS_S *cbs,
                                 IN CHAR_T *firmware_key,
                                 IN CHAR_T *product_key,
                                 IN CHAR_T *wf_sw_ver,
                                 IN CONST DEV_TYPE_T tp,
                                 IN GW_ATTACH_ATTR_T *attr,
                                 IN CONST UINT_T attr_num);

有线设备

/**
 * @brief General wired device init(with attached functional facilities)
 *
 * @param[in] cbs: tuya sdk user callbacks, @see TY_IOT_CBS_S
 * @param[in] firmware_key: the firmware key
 * @param[in] product_key: product key/product ID
 * @param[in] sw_ver: wired module software version format: xx.xx.xx (0<=x<=9)
 * @param[in] tp: device type, DEV_NM_ATH_SNGL
 * @param[in] attr: attached firmware of this device, @see GW_ATTACH_ATTR_T
 * @param[in] attr_num: number of attached firmwares
 *
 * @return OPRT_OK on success. For others on error, please refer to tuya_error_code.h
 */
OPERATE_RET tuya_iot_dev_init(IN CONST TY_IOT_CBS_S *cbs,
                              IN CONST CHAR_T *firmware_key,
                              IN CONST CHAR_T *product_key,
                              IN CONST CHAR_T *sw_ver,
                              IN CONST DEV_TYPE_T tp,
                              IN CONST GW_ATTACH_ATTR_T *attr,
                              IN CONST UINT_T attr_num);

MCU 对接类设备(带一个可独立 OTA 的功能模组)初始化

该 API 对 联网单品设备初始化 接口进行了封装,实现了专门用于带一个可独立 OTA 的功能模组的设备初始化功能。

无线设备

/**
 * @brief Wi-Fi device init (with MCU)
 *
 * @param[in] cfg: wifi device work mode, @see GW_WF_CFG_MTHD_SEL
 * @param[in] start_mode: wifi netcfg mode, @see GW_WF_START_MODE
 * @param[in] cbs: tuya sdk user callbacks, @see TY_IOT_CBS_S
 * @param[in] p_firmware_key: the firmware key
 * @param[in] product_key: product key/product ID
 * @param[in] wf_sw_ver: wifi module software version format:xx.xx.xx (0<=x<=9)
 * @param[in] mcu_sw_ver: MCU software version format:xx.xx.xx (0<=x<=9)
 *
 * @return OPRT_OK on success. For others on error, please refer to tuya_error_code.h
 */
OPERATE_RET tuya_iot_wf_mcu_dev_init(IN CONST GW_WF_CFG_MTHD_SEL cfg,
                                     IN CONST GW_WF_START_MODE start_mode,
                                     IN CONST TY_IOT_CBS_S *cbs,
                                     IN CHAR_T *p_firmware_key,
                                     IN CHAR_T *product_key,
                                     IN CHAR_T *wf_sw_ver,
                                     IN CONST CHAR_T *mcu_sw_ver);

有线设备

/**
 * @brief wired device init (with MCU)
 *
 * @param[in] cbs: tuya sdk user callbacks, @see TY_IOT_CBS_S
 * @param[in] p_firmware_key: the firmware key
 * @param[in] product_key: product key/product ID
 * @param[in] sw_ver: module software version format:xx.xx.xx (0<=x<=9)
 * @param[in] mcu_sw_ver: MCU software version format:xx.xx.xx (0<=x<=9)
 *
 * @return OPRT_OK on success. For others on error, please refer to tuya_error_code.h
 */
OPERATE_RET tuya_iot_mcu_dev_init(IN CONST TY_IOT_CBS_S *cbs,
                                  IN CHAR_T *p_firmware_key,
                                  IN CHAR_T *product_key,
                                  IN CHAR_T *sw_ver,
                                  IN CONST CHAR_T *mcu_sw_ver);

SoC 类设备(不带可独立 OTA 的功能模组)初始化

该 API 对 联网单品设备初始化 进行了封装,实现了专门用于不带可独立 OTA 的功能模组的设备初始化功能。

无线设备

/**
 * @brief Wi-Fi device init(without MCU)
 *
 * @param[in] cfg: wifi device work mode, @see GW_WF_CFG_MTHD_SEL
 * @param[in] start_mode: wifi netcfg mode, @see GW_WF_START_MODE
 * @param[in] cbs: tuya sdk user callbacks, @see TY_IOT_CBS_S
 * @param[in] firmware_key: the firmware key
 * @param[in] product_key: product key/product ID
 * @param[in] wf_sw_ver: wifi module software version format:xx.xx.xx (0<=x<=9)
 *
 * @return OPRT_OK on success. For others on error, please refer to tuya_error_code.h
 */
OPERATE_RET tuya_iot_wf_soc_dev_init_param(IN CONST GW_WF_CFG_MTHD_SEL cfg,
                                           IN CONST GW_WF_START_MODE start_mode,
                                           IN CONST TY_IOT_CBS_S *cbs,
                                           IN CHAR_T *firmware_key,
                                           IN CHAR_T *product_key,
                                           IN CHAR_T *wf_sw_ver);

有线设备

/**
 * @brief wired device init(without MCU)
 *
 * @param[in] cbs: tuya sdk user callbacks, @see TY_IOT_CBS_S
 * @param[in] firmware_key: the firmware key
 * @param[in] product_key: product key/product ID
 * @param[in] sw_ver: module software version format:xx.xx.xx (0<=x<=9)
 *
 * @return OPRT_OK on success. For others on error, please refer to tuya_error_code.h
 */
OPERATE_RET tuya_iot_soc_init_param(IN CONST TY_IOT_CBS_S *cbs,
                                    IN CHAR_T *firmware_key,
                                    IN CHAR_T *product_key,
                                    IN CHAR_T *sw_ver);

注册网络状态回调函数

设备网络状态变化的时候,TuyaOS 框架会调用该 API 注册进来的回调函数通知应用进行相应的处理。

无线设备

/**
 * @brief Set callback when network state changed(@see GW_WIFI_NW_STAT_E)
 *
 * @param wf_nw_stat_cb: network status monitor callback
 * @param min_interval_s: @deprecated (callback is called on state changed)
 *
 * @return OPRT_OK on success. For others on error, please refer to tuya_error_code.h
 */
OPERATE_RET tuya_iot_reg_get_wf_nw_stat_cb_params(IN CONST GET_WF_NW_STAT_CB wf_nw_stat_cb,
                                                  IN CONST INT_T min_interval_s);

有线设备

/**
 * @brief Set callback when network state changed(@see GW_BASE_NW_STAT_T)
 *
 * @param nw_stat_cb: network status monitor callback
 * @param min_interval_s: @deprecated (callback is called on state changed)
 *
 * @return OPRT_OK on success. For others on error, please refer to tuya_error_code.h
 */
OPERATE_RET tuya_iot_reg_get_nw_stat_cb_params(IN CONST GET_NW_STAT_CB nw_stat_cb,
                                               IN CONST INT_T min_interval_s);

使用示例

可实际运行的详细代码可见每个框架里提供的 Quickstart Demo

STATIC VOID_T user_main(VOID_T)
{
  // 1. TuyaOS 系统服务初始化
  TY_INIT_PARAMS_S init_param = {0};
  init_param.init_db = FALSE; // KV 初始化耗时较长,影响一些设备的启动效率,因此可以延后初始化
  strcpy(init_param.sys_env, TARGET_PLATFORM);
  TUYA_CALL_ERR_LOG(tuya_iot_init_params(NULL, &init_param));

  // 2. KV 初始化
  tuya_iot_kv_flash_init(NULL);

  // 3. 设置授权或者产测
  // xxx

  // 4. 设备初始化
  TY_IOT_CBS_S iot_cbs = {0};
  iot_cbs.gw_status_cb = __soc_dev_status_changed_cb;
  iot_cbs.gw_ug_cb = __soc_dev_rev_upgrade_info_cb;
  iot_cbs.gw_reset_cb = __soc_dev_restart_req_cb;
  iot_cbs.dev_obj_dp_cb = __soc_dev_obj_dp_cmd_cb;
  iot_cbs.dev_raw_dp_cb = __soc_dev_raw_dp_cmd_cb;
  iot_cbs.dev_dp_query_cb = __soc_dev_dp_query_cb;
  tuya_iot_wf_soc_dev_init(GWCM_OLD, WF_START_AP_ONLY, &wf_cbs);

  // 5. 注册网络状态回调函数
  tuya_iot_reg_get_wf_nw_stat_cb(__soc_dev_net_status_cb);
}

THREAD_HANDLE ty_app_thread = NULL;
STATIC VOID_T tuya_app_thread(VOID_T *arg)
{
  user_main();

  tal_thread_delete(ty_app_thread);
  ty_app_thread = NULL;
}

// 应用入口
VOID_T tuya_app_main(VOID_T)
{
    THREAD_CFG_T thrd_param = {4096, 4, "tuya_app_main"};
     tal_thread_create_and_start(&ty_app_thread, NULL, NULL, tuya_app_thread, NULL, &thrd_param);
}

常见问题

init_db 使用场景是什么?

TuyaOS 系统服务初始化时,默认会初始化 KV 数据存储服务,除非 init_db 显式设置为 FALSE

某些场景下,需要设备上电后快速读取存储的数据,以执行特定行为,该类数据建议存储在 UF 中,并且在 TuyaOS 系统服务初始化时,将 init_db 设置为 FALSE。在系统服务初始化完成后,需要再调用 tuya_iot_kv_flash_init 接口显式初始化 KV 数据存储服务。

设备外挂了语音、MCU、蓝牙等多个,应该调用哪个 API 初始化设备?

无线设备调用 tuya_iot_wf_dev_init,有线设备调用 tuya_iot_dev_init,并且正确设置 attrattr_num。示例如下:

UINT_T attr_num = 3;
GW_ATTACH_ATTR_T attr[3] = {
  {
    .tp = DEV_NM_NOT_ATH_SNGL, // MCU 模组
    .ver = "1.0.0"
  },
  {
    .tp = DEV_BLE_SNGL, // 蓝牙模组
    .ver = "2.0.0"
  },
  {
    .tp = DEV_ATTACH_MOD_1, // 语音模组(自定义 tp,需要与 IoT 前台配置保持一致)
    .ver = "3.0.0"
  }
};

模组固件版本号根据实际的填入,在每次 OTA 后需要更新为新的版本号。

支持与帮助

在开发过程遇到问题,可以到 TuyaOS 开发者论坛 联网单品开发版块 进无线