更新时间:2024-07-30 03:09:50下载pdf
本文介绍设备初始化功能。
设备初始化是程序运行的基础,具体指设备上电、启动之后调用的一系列接口,这些接口负责完成设备硬件环境的初始化、TuyaOS 软件的初始化、蓝牙协议栈功能的初始化以及应用功能初始化等工作。
涂鸦蓝牙设备初始化继承了嵌入式设备初始化的一般流程,同时抽象出了一组通用的接口,方便您在不同芯片平台之间进行切换。
全局初始化接口调用框图:
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 隔离开来,实现跨平台特性。
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 版本指针,字符串格式。下文对设备初始化过程中一些重要的接口进行单独介绍。
芯片原厂的 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-蓝牙设备开发 版块进行沟通咨询。
该内容对您有帮助吗?
是意见反馈该内容对您有帮助吗?
是意见反馈