Last Updated on : 2024-05-21 08:13:52download
This topic describes the TuyaOS Bluetooth mesh development kit in terms of its architecture, run process, directory, and common APIs.
TuyaOS is designed with a modular approach, with capabilities covering basic services, security, networking middleware, and various IoT services. Built on top of TuyaOS capabilities, TuyaOS Bluetooth Development Framework is a set of SDKs used to build Bluetooth products for different specifications and scenarios.
Unified APIs and a variety of components allow you to focus on building applications with a consistent development experience, without taking care of specific implementations.
The diagram above shows that the TuyaOS Bluetooth mesh development kit is divided into four layers. We will now review each layer, starting from the bottom.
The Tuya Kernel Layer (TKL) consists of Tuya-specific standard TKL APIs and chip vendor SDKs. The TKL provides unified APIs for the upper layer and adapts to different chip platforms. The adaptation development can be carried out by Tuya or chip vendors.
The Tuya Abstraction Layer (TAL) and Service Layer, the core parts of the development kit, consist of various components. The basic services include pairing, data communication, and system management.
The Application Layer covers various fields including lights, electrical products, sensors, remotes, and wireless switches. Besides the standard product routines, you can build with the standard demo projects without altering the code, or implement complex features on top of the demo.
For more information, see Device Initialization.
This basic demo project allows you to test almost all the Bluetooth mesh development kit features and develop complex applications accordingly.
app_common
: Demo application initialization and basic Bluetooth mesh data reception and transmission. The demo uses a cool and warm white light to show how communication functions with standard mesh opcodes.
tuya_mesh_sdk_test
: Used to test the Bluetooth mesh, system, and peripherals through Tuya’s production tool. You can refer to the example code for implementing the SDK’s API.
tal_driver
: Driver API.
tal_gpio_test
: GPIO testing with Tuya’s production tool.
tal_oled
: OLED driver.
tal_system
: System service API.
tal_utc
: UTC API.
tal_util
: Common tools.
tal_bluetooth
: Bluetooth and Bluetooth mesh API.
tal_mesh_factory_test
: Authorization and testing.
tal_mesh_gatt_ota
: OTA updates.
tal_nv_flash
: Nonvolatile storage for flash memory.
The vendor
directory stores the development environment, including chip vendor SDKs, adaptation layers, and common header files. It is maintained by Tuya and chip vendors.
Chip vendor SDK
The chip vendor SDK is developed by Tuya based on the open routines or adapted by chip vendors.
Adaptation layers
APIs for accessing Bluetooth, peripheral drivers (such as GPIO, PWM, ADC, I2C, and SPI), system drivers (such as memory, OTA, and sleep), secure encryption and hash algorithms (AES and MD5), and common tools.
Common header files
To enable a single codebase above the TKL to run across different platforms, platform-specific code such as flash address and peripheral pins is stored in board.h
as macro definitions.
tuya_error_code.h
: Definitions for error codes.
tuya_cloud_types.h
: Definitions for data types, enumerations, macros, and structs.
tuya_iot_config
: Definitions for system configuration and component enablement or configuration.
tuya_init_first()
: Initializes basic peripherals, configurations, and memory.
tuya_init_second()
: Initializes logging, software timer, and Bluetooth.
tuya_init_third()
: Initializes complex peripherals and peripheral components.
tuya_init_last()
: Initializes the Bluetooth pairing protocol and the test code, and enables Bluetooth adverting. After this API is executed, the main loop will be run.
tuya_main_loop()
: A callback within the main loop
, allowing you to inject custom operations into it.
Note:
Do not modify the return value of this API unless necessary, as it can impact the low power mode.
This API is intended for debugging and validation purposes. Use it with caution. Excessive time slices used by this API can compromise the stability of the entire framework.
The Bluetooth mesh opcode
varies by capability value. See Bluetooth Mesh Category and Data Transmission and DP Control for more information. The Bluetooth mesh device can receive data as expected when the correct opcode
is used.
Register callbacks
OPERATE_RET tal_mesh_msg_recv_cb_init(tal_mesh_msg_recv_cb access_data_cb);
Register the Bluetooth mesh data reception callback into the tal_bluetooth
component. When the device receives a control command, it will call the registered function to send the data to the application layer for processing.
typedef OPERATE_RET (*tal_mesh_msg_recv_cb)(TAL_MESH_ACCESS_MSG_T *msg_raw, TAL_MESH_NET_PARAM_T *net_param);
The callback has two parameters: msg_raw
and net_param
.
msg_raw
: The data reception parameters for the access layer, including the opcode
as well as the payload data
in hex format. Convert the hex data
into structured data based on the opcode
.net_param
: The parameters for the network layer, including src_addr
(source address), dst_addr
(destination address), SEQ (sequence number of the current packet), TTL (time to live), and RSSI (signal strength upon receiving the packet).Process data
opcode
specifies the data type for the access layer, similar to a command ID. The client model sends an opcode
, such as get, set, and set unacknowledged, to the server model that returns a status opcode
to the client after executing the command. For more information about how to use the opcode
, visit the official Bluetooth website for Mesh Model Specifications.
In most control scenarios, the mobile app, gateway, and remote use the client model to send commands, while the device uses the server model to report status.
See tal_bluetooth_mesh_def.h
for the opcode
definitions. For example, the macro for Generic OnOff Set is as follows.
#define TAL_MESH_OPCODE_ON_OFF_SET (0x8202)
After receiving the opcode
data, convert the hex data into the required format. Refer to the struct definitions in tal_bluetooth_mesh_def.h
. For example, change the received Generic OnOff Set data
into the TAL_MESH_GENERIC_ONOFF_SET_T
type.
typedef struct{
UCHAR_T onoff; /**< The target value of the Generic OnOff state. */
UCHAR_T tid; /**< Transaction Identifier */
UCHAR_T transit_t; /**< Generic Default Transition Time(optional). */
UCHAR_T delay; /**< If the transit_t field is present, the Delay field shall also be present; otherwise these fields shall not be present. */
}TAL_MESH_GENERIC_ONOFF_SET_T;
Example of processing and responding to the data received:
OPERATE_RET app_mesh_data_recv(TAL_MESH_ACCESS_MSG_T *msg_raw, TAL_MESH_NET_PARAM_T *net_param){
switch(msg_raw->opcode){
case TAL_MESH_OPCODE_ON_OFF_SET:
case TAL_MESH_OPCODE_ON_OFF_SET_UNACK:
TAL_MESH_GENERIC_ONOFF_SET_T *onoff_set = (TAL_MESH_GENERIC_ONOFF_SET_T)msg_raw->data;
BOOL_T onoff = onoff_set->onoff;
light_onoff_set(onoff);
TAL_MESH_GENERIC_ONOFF_STATUS_T onoff_status;
onoff_status.present = onoff;
onoff_status.target = onoff;
onoff_status.remain_t = 0;
if(TAL_MESH_OPCODE_ON_OFF_SET == msg_raw->opcode){
tal_mesh_data_send(net_param->dst_addr, net_param->src_addr, TAL_MESH_OPCODE_ON_OFF_STAT, &onoff_status, sizeof(onoff_status));
}
break;
}
}
OPERATE_RET tal_mesh_data_send(USHORT_T src_addr, USHORT_T dst_addr, UINT_T opcode, UCHAR_T *data, USHORT_T data_len);
This function sends data from the access layer. Specify the payload data and opcode
. The SDK will send the data based on the network layer parameters in sequence.
dst_addr
: The destination address.src_addr
: The source address. It is typically the unicast address of the device, which can be obtained through tkl_mesh_primary_ele_addr_get();
.src_addr
is set to 0
or NULL, the SDK will populate it with the device’s main element address instead. For multi-element devices, set src_addr
to the element address using the correct format primary_ele_addr
+ element_index
.When the device proactively reports data without knowing the unicast_addr
of the mobile app or gateway, dst_addr
can be set to TUYA_REPROT_PUB_ADDR
as defined in tal_bluetooth_mesh_def.h
. The mobile app and gateway subscribe to this address, ensuring that any data sent here will be received and processed.
#define TAL_MESH_OPCODE_CFG_MODEL_SUB_ADD (0x801B)
#define TAL_MESH_OPCODE_CFG_MODEL_SUB_DELETE (0x801C)
OPERATE_RET tal_group_addr_sub_set(UINT_T opcode, USHORT_T ele_index, USHORT_T group_addr);
This function subscribes to or unsubscribes from a group address for the specified model. The SDK will automatically subscribe to all models of an element.
USHORT_T* tal_group_addr_sub_list_get(USHORT_T ele_idx, USHORT_T model_id);
This function requests the subscription list of the specified model for an element. Currently, a device can subscribe to up to 32 group addresses.
OPERATE_RET tal_element_register(USHORT_T element_index);
OPERATE_RET tal_model_register(USHORT_T element_index, UINT_T model_id);
For more information, see Initialization.
typedef enum {
MESH_NETWORK_RESET = 0x00, /**< Kick out, mesh node will be in the unprovisioned state, and it will clear the mesh provision data in RAM and flash */
MESH_NETWORK_RESET_WITH_RECOVER, /**< Node reset in tam, mesh node will be in the unprovisioned state, and it will clear the mesh provision data in RAM. The provision data is still stored in the flash */
MESH_NETWORK_RECOVER, /**< Recover the network, the mesh node will be in the provisioned state, and it will restore the provision data from flash into RAM */
} MESH_NETWORK_STATE_SET_T;
OPERATE_RET tal_mesh_network_state_set(MESH_NETWORK_STATE_SET_T net_state);
Reset a device to the unpaired status. Two reset methods are available. MESH_NETWORK_RESET
resets a device irreversibly. MESH_NETWORK_RESET_WITH_RECOVER
resets a device reversibly. If a device is not paired after a reset, set the request parameter to MESH_NETWORK_RESET_WITH_RECOVER
or restart the device to restore the network to its previous state before the reset.
The reversible method can prevent an accidental reset. If a device is reset irreversibly, it needs to be manually paired to reconnect to the network. If the network is restored in case of pairing timeout, this manual action is unnecessary.
typedef enum{
TAL_MESH_POWER_ON_UNPROVISION = 0,
TAL_MESH_POWER_ON_PROVISIONED,
TAL_MESH_PROVISION_SUCCESS,
TAL_MESH_RESET,
TAL_MESH_RESET_IN_RAM,
TAL_MESH_REVERT_IN_MESH,
TAL_MESH_GROUP_SUB_ADD,
TAL_MESH_GROUP_SUB_DEL,
TAL_GATT_OTA_START,
TAL_GATT_OTA_SUCCESS,
TAL_GATT_OTA_FAIL,
TAL_STATE_UNKONWN
}TAL_MESH_NET_STATE_T;
VOID tal_mesh_state_callback(TAL_MESH_NET_STATE_T state);
This function is a callback for the mesh device status. You need to create an instance of this function in the application layer so that the SDK can inform the service layer about the action it has performed. This callback is implemented with a weak function at the bottom layer. If a function instance is not created in the service layer, the bottom layer will link a null function to the firmware.
VOID tal_mesh_node_provision_enable(MESH_PROVISION_TYPE_T enable);
This function enables or disables the device’s ability to advertise its presence for pairing. It is used when an unpaired device does not want to be paired with the mobile app or gateway, or when pairing times out.
UCHAR_T tal_get_if_prov_success(VOID);
Get the provisioning status of the device. The Bluetooth mesh device pairing involves two stages: provisioning and configuration. The pairing is successful when the configuration stage is completed, which can be confirmed by the status sent from VOID tal_mesh_state_callback(TAL_MESH_NET_STATE_T state)
. This function is not used to verify the pairing process completion.
USHORT_T tal_primary_ele_addr_get(VOID);
Get the address of the device’s main element, which is assigned by the mobile app or gateway during pairing.
VOID tal_primary_ele_addr_set(USHORT_T addr, int flash_save_en);
Set the address of the device’s main element when it is not paired. Do not call this function to change the main element address after pairing the device, as it may cause communication problems.
The demo has logging turned off by default. You can modify #define ENABLE_LOG 1
in tuya_iot_config.h
to enable log output using the API in tal_log
. Note that components that have been compiled into a library
do not have logs. To debug them, contact Tuya’s technical support.
The chip vendor SDK is open source, allowing you to enable logging directly.
LOG_FW_FUNC_EN
in app_mesh.h
to turn on logging.PHY_LOG_EN
in EM_platform.h
to turn on logging.In tuya_sdk_test.h
, you can disable the SDK testing feature to save code size by commenting out #define TUYA_SDK_TEST 1
or modifying it to #define TUYA_SDK_TEST 0
.
The SDK testing feature is enabled by default. You can test pairing, communication, and peripherals using the test code and Tuya’s host software. Make sure to disable the testing feature on production firmware.
The SDK supports dynamic memory allocation. Allocate and release heap memory with the following function.
VOID_T *tkl_system_malloc(SIZE_T size);
VOID_T tkl_system_free(VOID_T* ptr);
You can change the default size of dynamic memory with the macro HEAP_SIZE
as needed.
TuyaOS Kernel Layer (TKL) provides a set of standard driver APIs required to run a minimum viable TuyaOS product. Note that not all drivers have the TKL API.
If the driver you need in the TKL is not implemented or not available, you can directly use the API provided by the chip vendor.
Is this page helpful?
YesFeedbackIs this page helpful?
YesFeedback