本文介绍设备初始化功能。

概述

概念介绍

设备初始化是程序运行的基础,具体指设备上电、启动之后调用的一系列接口,这些接口负责完成设备硬件环境的初始化、TuyaOS 软件的初始化、蓝牙协议栈功能的初始化以及应用功能初始化等工作。

涂鸦蓝牙设备初始化继承了嵌入式设备初始化的一般流程,同时抽象出了一组通用的接口,方便您在不同芯片平台之间进行切换。

功能描述

全局初始化接口调用框图:

lineageos 镜像站 osu镜像站怎么用_网络

TuyaOS 蓝牙 LE SDK 中提供了多个初始化接口,不同的初始化接口被 SDK 调用的时机不同。直接面向开发者使用的设备初始化接口如下:

OPERATE_RET tuya_init_first(VOID_T)
OPERATE_RET tuya_init_second(VOID_T)
OPERATE_RET tuya_init_third(VOID_T)
OPERATE_RET tuya_init_last(VOID_T)
OPERATE_RET tuya_main_loop(VOID_T)

不同初始化接口的差异和使用方法详见下表:

接口

接口调用时机

适用功能

tuya_init_first

设备启动,MCU 初始化成功之后

基础外设、基础资源初始化,对启动时间有要求,要求设备启动后立即做出响应。

tuya_init_second

蓝牙协议栈初始化及之前

蓝牙协议栈、Log 初始化。

tuya_init_third

蓝牙协议栈初始化之后

对于蓝牙 LE 协议栈的状态有依赖,需要获取协议栈内的状态才可以初始化的功能。

高级外设、数字接口初始化、主要业务功能初始化。

tuya_init_last

SDK 初始化最后的时机

其他业务、其他功能初始化。

tuya_main_loop

主循环

循环任务 API 也就是涂鸦常说的 loop 函数,loop 函数中实现较多的功能。例如队列或者事件的处理、软件定时器的处理函数等。

以上接口被涂鸦分层结构进行两层调用,涉及到的接口如下:

OPERATE_RET tal_init_first(VOID_T);
OPERATE_RET tal_init_second(VOID_T);
OPERATE_RET tal_init_third(VOID_T);
OPERATE_RET tal_init_last(VOID_T);
OPERATE_RET tal_main_loop(VOID_T);

OPERATE_RET tkl_init_first(VOID_T);
OPERATE_RET tkl_init_second(VOID_T);
OPERATE_RET tkl_init_third(VOID_T);
OPERATE_RET tkl_init_last(VOID_T);
OPERATE_RET tkl_main_loop(VOID_T);

最终,tkl_…… 相关接口被各芯片平台提供的 main 函数 或者 类 main 函数 直接调用。

这组标准接口是 TuyaOS 中低功耗蓝牙唯一一组反向调用的接口,目的是为整个 SDK 提供一个运行入口。这样 SDK 的其他部分就可以做到杜绝反向调用,将涂鸦 SDK 和不同的芯片原厂 SDK 隔离开来,实现跨平台特性。

数据结构

tal_common_info_t

typedef struct {
    UINT8_T  *p_firmware_name;
    UINT8_T  *p_firmware_version;
    UINT32_T firmware_version;
    UINT8_T  *p_hardware_version;
    UINT32_T hardware_version;

    UINT8_T  *p_sdk_version;
    UINT8_T  *p_kernel_version;
} tal_common_info_t;
  • p_firmware_name:固件名称指针,字符串格式。
  • p_firmware_version:固件版本指针,字符串格式。
  • firmware_version:固件版本,数值格式。
  • p_hardware_version:硬件版本指针,字符串格式。
  • hardware_version:硬件版本,数值格式。
  • p_sdk_version:SDK 版本指针,字符串格式。
  • p_kernel_version:Kernel 版本指针,字符串格式。

接口说明

下文对设备初始化过程中一些重要的接口进行单独介绍。

日志开关

lineageos 镜像站 osu镜像站怎么用_协议栈_02

芯片原厂的 Log 开关,请参考 开发平台介绍

Log 输出接口

tuya_log_output_cb

初始化日志设置

OPERATE_RET tal_log_create_manage_and_init(CONST TAL_LOG_LEVEL_E level, CONST INT_T buf_len, CONST TAL_LOG_OUTPUT_CB output);

支持打印标准的涂鸦日志(Log)发生的时间、位置,支持 Log 等级输出,支持字符串和数据流。

  • 参数 level 用于定义 Log 输出等级,默认为 TAL_LOG_LEVEL_DEBUG
  • 参数 buf_len 为 Log 缓存的最大值。
  • 参数 output 是 Log 输出的出口函数,由您在应用层传入,默认为 tuya_log_output_cb

测试功能开关

开启测试代码:设置宏 TUYA_SDK_TEST 的值为 1

关闭测试代码:设置宏 TUYA_SDK_TEST 的值为 0

测试代码结合测试上位机(Logic)可实现大部分配网、通信、外设等功能的测试,可帮助您更好地开发产品。但是,生产固件请务必关闭测试功能

调试模式开关

#define TUYA_SDK_DEBUG_MODE 0

若暂无生产需要,可通过开启调试模式的方式进行临时授权(仅用于调试,生产时请改回原状)。

生产时的授权方式请参考 蓝牙授权产测

初始化动态内存

动态内存的大小:BOARD_HEAP_SIZE

#define BOARD_HEAP_SIZE 5120

VOID_T tuya_memory_init(VOID_T)
{
    tuya_mem_heap_init(&heap_context);
    tuya_mem_heap_create(heap_pool, BOARD_HEAP_SIZE, &heap_handle);
}

初始化设备信息

OPERATE_RET app_config_info_set(VOID_T)
{
    tal_common_info_t tal_common_info   = {0};
    tal_common_info.p_firmware_name     = (UINT8_T*)FIRMWARE_NAME;
    tal_common_info.p_firmware_version  = (UINT8_T*)FIRMWARE_VERSION;
    tal_common_info.firmware_version    = FIRMWARE_VERSION_HEX;
    tal_common_info.p_hardware_version  = (UINT8_T*)HARDWARE_VERSION;
    tal_common_info.hardware_version    = HARDWARE_VERSION_HEX;
    tal_common_info.p_sdk_version       = (UINT8_T*)"0.2.0";
    tal_common_info.p_kernel_version    = (UINT8_T*)"0.0.1";
    return tal_common_info_init(&tal_common_info);
}

上电时间测试

OPERATE_RET tuya_init_first(VOID_T)
{
#if defined(TUYA_SDK_TEST) && (TUYA_SDK_TEST == 1)
    TUYA_GPIO_BASE_CFG_T gpio_cfg = {
        .mode = TUYA_GPIO_PUSH_PULL,
        .direct = TUYA_GPIO_OUTPUT,
        .level = TUYA_GPIO_LEVEL_LOW,
    };
    tal_gpio_init(BOARD_POWER_ON_PIN, &gpio_cfg);
    tal_gpio_write(BOARD_POWER_ON_PIN, TUYA_GPIO_LEVEL_HIGH);
#endif

    …………

    return OPRT_OK;
}

测试方法:使用逻辑分析仪测试 VCC 和 BOARD_POWER_ON_PIN 引脚拉高的时间差,即为对应芯片平台的上电时间。

测试结果:请参考 开发平台介绍

初始化蓝牙协议栈

OPERATE_RET tal_ble_bt_init(TAL_BLE_ROLE_E role, CONST TAL_BLE_EVT_FUNC_CB ble_event);

包括射频参数、GAP、GATT 参数初始化,服务和特征值添加,连接状态初始化,广播和扫描(若支持)初始化等内容。

  • 参数 role 支持从机、主机、Beacon 等可选值,一般默认仅支持从机。
  • 参数 ble_event 是蓝牙事件回调,在应用层的值为 tuya_ble_evt_callback,负责对连接、断开、服务发现、连接参数更新等各种蓝牙事件的处理。

初始化蓝牙配网

VOID_T tuya_ble_protocol_init(VOID_T)
{
    tuya_ble_protocol_param.firmware_version = tal_common_info.firmware_version,
    tuya_ble_protocol_param.hardware_version = tal_common_info.hardware_version,
    memcpy(tuya_ble_protocol_param.device_id,       device_id_test, DEVICE_ID_LEN);
    memcpy(tuya_ble_protocol_param.auth_key,        auth_key_test, AUTH_KEY_LEN);
    memcpy(tuya_ble_protocol_param.mac_addr_string, TY_DEVICE_MAC, MAC_STRING_LEN);
    memcpy(tuya_ble_protocol_param.product_id,      TY_DEVICE_PID, tuya_ble_protocol_param.product_id_len);
    memcpy(tuya_ble_protocol_param.adv_local_name, TY_DEVICE_NAME, tuya_ble_protocol_param.adv_local_name_len);
    tuya_ble_sdk_init(&tuya_ble_protocol_param);

    tuya_ble_callback_queue_register(tuya_ble_protocol_callback);

    ……
}
  • tuya_ble_sdk_init() 用于参数初始化,包括固件版本、三元组(Mac、Device id、Auth key)、PID、广播名称等参数。
  • tuya_ble_callback_queue_register() 用于注册回调函数,处理包括配网状态、时间戳、DP 数据、解绑等各种配网相关的逻辑。

该接口是涂鸦蓝牙设备和智能生活 App 通信的主要接口,涵盖了配网相关的各种参数和事件处理。

初始化串口

串口用于授权产测和功能测试,默认波特率 9600bps。

注意:如果使用涂鸦烧录授权工具,则必须使用 9600 波特率。

TAL_UART_CFG_T tal_uart_cfg = {
    .rx_buffer_size = 256,
    .open_mode = O_BLOCK,
    {
        .baudrate = 9600,
        .parity = TUYA_UART_PARITY_TYPE_NONE,
        .databits = TUYA_UART_DATA_LEN_8BIT,
        .stopbits = TUYA_UART_STOP_LEN_1BIT,
        .flowctrl = TUYA_UART_FLOWCTRL_NONE,
    }
};

STATIC VOID_T tuya_uart_irq_rx_cb(TUYA_UART_NUM_E port_id, VOID_T *buff, UINT16_T len)
{
    if (port_id == TUYA_UART_NUM_0) {
        tuya_ble_common_uart_receive_data(buff, len);
    } else {
#if defined(TUYA_SDK_TEST) && (TUYA_SDK_TEST == 1)
        test_cmd_send(TEST_ID_GET(TEST_GID_UART, TEST_CID_RX_UART_PORT), (VOID_T*)&port_id, SIZEOF(UINT32_T));
        test_cmd_send(TEST_ID_GET(TEST_GID_UART, TEST_CID_RX_UART_DATA), buff, len);
#endif
    }
}

OPERATE_RET tuya_init_last(VOID_T)
{
    tal_uart_init(TUYA_UART_NUM_0, &tal_uart_cfg);
    tal_uart_rx_reg_irq_cb(TUYA_UART_NUM_0, tuya_uart_irq_rx_cb);

    …………

    return OPRT_OK;
}

关于驱动接口的说明

涂鸦通过 TKL 层提供了最小功能集所需的驱动接口,TKL 只是涂鸦标准化的接口,并非所有驱动都有 TKL。

为了保证开发效率,如果 TKL 层对应的驱动没有实现或者没有相关驱动,您可以按照实际需求直接调用芯片原厂提供的接口。

支持与帮助

在开发过程遇到问题,您可以登录 TuyaOS 开发者论坛 TuyaOS-蓝牙设备开发 版块进行沟通咨询。

咨询前建议首先查阅 官方资料 或参考已有帖子,并认真阅读 发帖规范