TuyaOSTuyaOS 移植移植 TuyaOS 到 RTOS 平台

移植 TuyaOS 到 RTOS 平台

更新时间:2023-11-08 09:16:36下载pdf

实时操作系统(Real-time operating system,RTOS)的类型较多,且接口并不统一。为了能为上层软件提供稳定可靠、无差别的运行环境,TuyaOS 生成了一系列能力适配接口。您需要按照自己的操作系统、硬件、芯片的实际情况,根据本文描述完成接口适配。

编译适配

RTOS 系统的 TuyaOS Kernel 没有提供默认的编译适配。固件编译入口为 tuyaos/build.sh,需要您根据实际情况进行修改。

您无需考虑 TuyaOS 相关的文件编译,只需完成自身原厂相关的文件编译,并在链接的时候,将 TuyaOS 的库文件链接进去即可。

为了保证与涂鸦 IoT 云服务的兼容性和稳定性,建议使用 TuyaOS 自带的 mbedtls 库,即使您的系统中也已经存在该库。这样可以避免潜在的冲突问题,并减少可能出现的不可预知错误。

链接选项和路径参考:

# 根目录,注意,应为 software/TuyaOS 目录
ROOT_DIR ?= $(abspath ../../../)

# 编译所用变量,需要把编译好的固件存放到此目录下
OUTPUT_DIR = $(ROOT_DIR)/$(APP_PATH)/output/$(APP_NAME)_$(APP_VER)

# TuyaOS 库文件路径
TUYAOS_LIB_DIR = $(ROOT_DIR)/libs

# 推荐链接选项,注意,可能存在 .a 内容为空的情况,如果您的工具链不支持空 .a,可以移除掉
LINKFLAGS = -L$(TUYAOS_LIB_DIR) -Xlinker "-(" -l$(APP_NAME) -ltuyaapp_components -ltuyaapp_drivers -ltuyaos -ltuyaos_adapter -Xlinker "-)"

如果您在适配、编译的时候,发现 tuyaos_adapter/src 目录下的文件需要引入非常复杂的原厂头文件引用,可以把此目录下的文件放从 TuyaOS 编译体系移除,添加到原厂编译文件列表中。此时,您需要按照如下内容修改 tuyaos_adapter/local.mk 文件。

###################################################################################
# 注意
# tuyaos_adapter 可以在原厂环境下编译,如果选择在原厂环境下编译,则不需要修改此文件,如果不
# 在原厂环境下编译,则可以在此文件中把模组 tuyaos_adapter/src/ 下的源代码加到
# LOCAL_SRC_FILES,同时把编译需要的头文件放 LOCAL_TUYA_SDK_CFLAGS
###################################################################################
# include 目录下存在一些 tuya 提供的组件源文件,请勿修改
LOCAL_SRC_FILES := $(shell find $(LOCAL_PATH)/include -name "*.c" -o -name "*.cpp" -o -name "*.cc")
# 如果适配层要和 tuyaos 一起编译,请打开此处
#LOCAL_SRC_FILES += $(shell find $(LOCAL_PATH)/src -name "*.c" -o -name "*.cpp" -o -name "*.cc")
# 如果适配层要和 tuyaos 一起编译,请在此处新增原厂头文件路径
#LOCAL_TUYA_SDK_INC +=
###################################################################################

适配程序入口

TuyaOS 的运行入口为 tuya_app_main 函数,您需要将这个函数嵌入到开发平台启动的main函数中恰当的位置。

适配系统接口

系统接口主要是和操作系统相关的功能接口,包括基本的系统操作、线程、信号量、互斥量、I/O、内存、睡眠、升级等。适配系统接口完成之后,才能保障 TuyaOS 正常运行。

内存管理

接口
说明
VOID_T *tkl_system_malloc ( SIZE_T size ) 申请内存
VOID_T tkl_system_free ( VOID_T* ptr ) 释放内存
VOID_T *tkl_system_calloc ( size_t nitems, size_t size ) 连续分配内存
VOID_T *tkl_system_realloc ( VOID_T *ptr, size_t size ) 重新分配内存
INT_T tkl_system_get_free_heap_size ( VOID_T ) 获取堆的剩余空间

线程管理

接口
说明
OPERATE_RET tkl_thread_create (
TKL_THREAD_HANDLE* thread,
CONST CHAR_T* name,
UINT_T stack_size,
UINT_T priority,
CONST THREAD_FUNC_T func,
VOID_T* CONST arg )
创建并启动
OPERATE_RET tkl_thread_release ( TKL_THREAD_HANDLE thread ) 销毁线程并释放资源
OPERATE_RET tkl_thread_get_watermark (
TKL_THREAD_HANDLE thread,
UINT_T* watermark )
获取线程运行堆栈水线
OPERATE_RET tkl_thread_diagnose ( TKL_THREAD_HANDLE thread ) 获取线程诊断信息,如栈、寄存器等

接口
说明
OPERATE_RET tkl_mutex_create_init ( TKL_MUTEX_HANDLE *pMutexHandle ) 创建并初始化互斥量,注意,必须支持递归调用
OPERATE_RET tkl_mutex_release ( CONST TKL_MUTEX_HANDLE mutexHandle ) 销毁互斥量,并释放资源
OPERATE_RET tkl_mutex_lock ( CONST TKL_MUTEX_HANDLE mutexHandle ) 锁定互斥量,如果互斥量已经被锁定,则阻塞
OPERATE_RET tkl_mutex_trylock ( CONST TKL_MUTEX_HANDLE mutexHandle ) 尝试锁定互斥量,如果互斥量已经被锁定,则返回错误
OPERATE_RET tkl_mutex_unlock ( CONST TKL_MUTEX_HANDLE mutexHandle ) 解锁互斥量

信号量

接口
说明
OPERATE_RET tkl_semaphore_create_init (
TKL_SEM_HANDLE *handle,
UINT_T sem_cnt,
UINT_T sem_max )
创建并初始化信号量
OPERATE_RET tkl_semaphore_wait ( CONST TKL_SEM_HANDLE handle, UINT_T timeout ) 等待信号,timeout = TKL_SEM_WAIT_FOREVER 为一直等待
OPERATE_RET tkl_semaphore_post ( CONST TKL_SEM_HANDLE handle ) 发送信号
OPERATE_RET tkl_semaphore_release ( CONST TKL_SEM_HANDLE handle ) 销毁信号量并释放资源

输出

接口
说明
VOID_T tkl_log_output ( CONST CHAR_T *format, … ) 日志输出,参数是可变参数

OTA

接口
说明
OPERATE_RET tkl_ota_get_ability (
UINT_T *image_size,
TUYA_OTA_TYPE_E *type )
平台支持的 OTA 能力,平台移植一般选择 TUYA_OTA_FULL
OPERATE_RET tkl_ota_start_notify (
UINT_T image_size,
TUYA_OTA_TYPE_E type,
TUYA_OTA_PATH_E path )
通知开发平台数据开始写入,需要准备资源
OPERATE_RET tkl_ota_data_process (
TUYA_OTA_DATA_T *pack,
UINT_T *remain_len )
固件数据写入处理,TuyaOS 从云端拉数据写入平台 Flash
OPERATE_RET tkl_ota_end_notify ( BOOL_T reset ) 通知开发平台数据写完成,需要校验文件,设置状态

低功耗

接口
说明
OPERATE_RET tkl_cpu_sleep_mode_set (
BOOL_T enable,
TUYA_CPU_SLEEP_MODE_E mode )
让 CPU 进入低功耗模式

其他

接口
说明
VOID_T tkl_system_reset ( VOID_T ) 重启设备
SYS_TICK_T tkl_system_get_tick_count ( VOID_T ) 获取设备运行的 Tick 数
SYS_TIME_T tkl_system_get_millisecond ( VOID_T ) 获取设备运行的毫秒数
INT_T tkl_system_get_random ( UINT_T range ) 获取一个 (0, range) 范围内的随机数,随机数非常重要,请务必正确的实现
TUYA_RESET_REASON_E tkl_system_get_reset_reason ( CHAR_T** describe ) 获取设备重启原因,返回值即可,参数可以忽略
VOID_T tkl_system_sleep ( UINT_T num_ms) 当前任务休眠,休眠时间单位为毫秒
OPERATE_RET tkl_system_get_cpu_info (
TUYA_CPU_INFO_T **cpu_ary,
INT_T *cpu_cnt )
获取 CPU 利用率

适配 Flash 接口

在 RTOS 系统上,TuyaOS 基于 Flash 实现了一套统一的数据存储、文件操作方案。

Flash 分区

对于 RTOS 系统,需要对设备的 Flash 做统一的规划,满足各种功能的需求,是 TuyaOS 正常运行的基础。

  • 分区类型

    其用途参考注释,标为必须的类型,是一定要准备好相关的空间的,各个类型分区的体积需要按照整体 Flash 的体积和未来扩展考虑好。

    /**
    * @brief flash type
    *
    */
    typedef enum {
        TUYA_FLASH_TYPE_BTL0 = 0,                // 一级 BootLoader,大小按需规划,必须
        TUYA_FLASH_TYPE_BTL1,            // 次级 BootLoader,大小按需规划,如无需求则可以忽略
        TUYA_FLASH_TYPE_STACK,            // 固定协议存放区域,大小按需规划,如无需求则可以忽略
        TUYA_FLASH_TYPE_APP,            // 应用程序段,大小按需规划,必须
        TUYA_FLASH_TYPE_OTA,            // OTA 文件存储区,大小按需规划,必须
        TUYA_FLASH_TYPE_USER0,            // 用户数据区 1,大小按需规划,主要是应用层使用,如无需求则可以忽略
        TUYA_FLASH_TYPE_USER1,            // 用户数据区 2,大小按需规划,主要是应用层使用,如无需求则可以忽略
        TUYA_FLASH_TYPE_KV_DATA,                    // KV 数据库存储区,至少 32K,必须
        TUYA_FLASH_TYPE_KV_SWAP,                // KV 读、写操作交换区,目前已经不在使用,忽略
        TUYA_FLASH_TYPE_KV_KEY,            // KV 秘钥存储区,大小为 4K,必须
        TUYA_FLASH_TYPE_UF,                // 文件存储区,至少 32K,必须
        TUYA_FLASH_TYPE_INFO,            // 忽略
        TUYA_FLASH_TYPE_KV_UF,            // 忽略
        TUYA_FLASH_TYPE_KV_PROTECT,                    // KV 核心数据备份区,至少 4K,必须
        TUYA_FLASH_TYPE_RCD,            // RCD,网关使用的一种数据存储机制,非网关不需要
        TUYA_FLASH_TYPE_RSV0,            // 以下为保留类型,用于扩展所需使用
        TUYA_FLASH_TYPE_RSV1,
        TUYA_FLASH_TYPE_RSV2,
        TUYA_FLASH_TYPE_RSV3,
        TUYA_FLASH_TYPE_RSV4,
        TUYA_FLASH_TYPE_RSV5,
        TUYA_FLASH_TYPE_RSV6,
        TUYA_FLASH_TYPE_RSV7,
        TUYA_FLASH_TYPE_ALL,
        TUYA_FLASH_TYPE_MAX,
    } TUYA_FLASH_TYPE_E;
    
  • 分区描述

    一个特定的功能分区是可以是由多个小的、分散的分区构成,TUYA_FLASH_TYPE_MAX_PARTITION_NUM 默认为 10 个。

    typedef struct {
        UINT_T partition_num;                                    // 分区数量
        TUYA_FLASH_PARTITION_T partition[TUYA_FLASH_TYPE_MAX_PARTITION_NUM];    // 分区
    } TUYA_FLASH_BASE_INFO_T;
    

Flash 操作

接口
说明
OPERATE_RET tkl_flash_read ( UINT32_T addr,
UCHAR_T *dst,
UINT32_T size )
Flash 读操作
OPERATE_RET tkl_flash_write ( UINT32_T addr,
CONST UCHAR_T *src,
UINT32_T size )
Flash 写操作
OPERATE_RET tkl_flash_erase ( UINT32_T addr, UINT32_T size ) Flash 擦除
OPERATE_RET tkl_flash_lock ( UINT32_T addr, UINT32_T size ) Flash 锁定
OPERATE_RET tkl_flash_unlock ( UINT32_T addr, UINT32_T size ) Flash 解锁
OPERATE_RET tkl_flash_get_one_type_info (
TUYA_FLASH_TYPE_E type,
TUYA_FLASH_BASE_INFO_T *info )
获取特定类型分区信息

适配 RTC 时钟

支持实时时钟(Real-time clock,RTC)的平台可以实现 RTC 相关的接口,通过 RTC 提供的精确计时的能力,保障设备的时间准确。

TuyaOS 在设备配网激活之后,会和云端进行数据交互,获取云端的时间信息并设置到 RTC 中。TuyaOS 需要依赖 RTC 提供的时间服务进行工作。一旦检测到本地时间和云端时间偏差超过 5 秒,开发框架会再次通过云端更新时间,以保障时间偏差不至于扩大。但是,当设备处于离线状态时,则完全依赖于 RTC 自身的精度来保障时间的准确性。

接口
说明
OPERATE_RET tkl_rtc_init ( VOID_T ) 初始化 RTC 器件,使得其能够正常工作,注意,RTC 时间统计周期应为秒级。
OPERATE_RET tkl_rtc_deinit ( VOID_T ) 卸载 RTC 器件,释放相关资源。
OPERATE_RET tkl_rtc_time_set ( TIME_T time_sec ) 设置 RTC 时间戳,参数单位精度是秒级。设置成功之后,RTC 计时以该时间戳为起点。
OPERATE_RET tkl_rtc_time_get ( TIME_T *time_sec ) 获取当前系统的时间戳。

适配看门狗

支持看门狗(WatchDog)的平台可以实现 WatchDog 相关的接口,通过 WatchDog 来保障设备异常状态下能够通过超时重启的机制恢复,避免设备进入无法使用的状态。在 TuyaOS 里,喂狗操作是在一个独立的、高优先级的线程里进行的,不会受普通业务操作的影响。

接口
说明
UINT32_T tkl_watchdog_init ( TUYA_WDOG_BASE_CFG_T *cfg ) 初始化 WatchDog 器件,返回值是实际的超时周期,周期不应小于 5 秒。
OPERATE_RET tkl_watchdog_deinit ( VOID_T ) 卸载 WatchDog 器件,释放相关资源,和初始化 WatchDog 对应。
OPERATE_RET tkl_watchdog_refresh ( VOID_T ) 刷新 WatchDog,重置 WatchDog 状态。刷新周期是实际周期的三分之一。

适配网络接口

使用 TuyaOS 自带 LWIP

如果您选择使用 TuyaOS 自带的 LWIP(lightweight IP)库,适配接口会大大的减少。您只需仅需适配网卡相关的接口,将底层网卡驱动接收、发送和协议栈打通。

接口
说明
OPERATE_RET tkl_ethernetif_init ( TKL_NETIF_HANDLE netif ) 网卡初始化
OPERATE_RET tkl_ethernetif_output ( TKL_NETIF_HANDLE netif, TKL_PBUF_HANDLE p) 网卡发送数据
OPERATE_RET tkl_ethernetif_recv ( TKL_NETIF_HANDLE netif, TKL_PBUF_HANDLE p ) 网卡接受数据

使用开发平台自带的 LWIP

如果您要使用开发平台自带的协议栈,就需要适配较多接口。

接口
说明
TUYA_ERRNO tkl_net_get_errno ( VOID ) 获取 errno
OPERATE_RET tkl_net_fd_set ( CONST INT_T fd, TUYA_FD_SET_T* fds ) 把 fd 添加到 fdset
OPERATE_RET tkl_net_fd_clear ( CONST INT_T fd, TUYA_FD_SET_T* fds ) 把 fd 从 fdset 移除
OPERATE_RET tkl_net_fd_isset ( CONST INT_T fd, TUYA_FD_SET_T* fds ) 判断 fd 是否在 fdset
OPERATE_RET tkl_net_fd_zero ( TUYA_FD_SET_T* fds ) 清空 fdset
INT_T tkl_net_socket_create ( CONST TUYA_PROTOCOL_TYPE_E type ) 创建 socket
TUYA_ERRNO tkl_net_close ( CONST INT_T fd ) 关闭 socket
INT_T tkl_net_select (
CONST INT_T maxfd,
TUYA_FD_SET_T *readfds,
TUYA_FD_SET_T *writefds,
TUYA_FD_SET_T *errorfds,
CONST UINT_T ms_timeout)
选择 socket
TUYA_ERRNO tkl_net_connect (
CONST INT_T fd,
CONST TUYA_IP_ADDR_T addr,
CONST UINT16_T port)
连接 socket
TUYA_ERRNO tkl_net_connect_raw (
CONST INT_T fd,
VOID *p_socket_addr,
CONST INT_T len )
连接 socket raw
TUYA_ERRNO tkl_net_bind (
CONST INT_T fd,
CONST TUYA_IP_ADDR_T addr,
CONST UINT16_T port )
绑定 socket
TUYA_ERRNO tkl_net_listen ( CONST INT_T fd, CONST INT_T backlog ) 监听 socket
TUYA_ERRNO tkl_net_accept ( CONST INT_T fd, TUYA_IP_ADDR_T *addr, UINT16_T *port ) 接受 socket
TUYA_ERRNO tkl_net_send ( CONST INT_T fd, CONST VOID *buf, CONST UINT_T nbytes ) 发送 socket
TUYA_ERRNO tkl_net_send_to (
CONST INT_T fd,
CONST VOID *buf,
CONST UINT_T nbytes,
CONST TUYA_IP_ADDR_T addr,
CONST UINT16_T port )
发往 socket
TUYA_ERRNO tkl_net_recv (
CONST INT_T fd,
VOID *buf,
CONST UINT_T nbytes )
接收 socket
INT_T tkl_net_recv_nd_size (
CONST INT_T fd,
VOID *buf,
CONST UINT_T buf_size,
CONST UINT_T nd_size )
设置 socket 接收的长度
TUYA_ERRNO tkl_net_recvfrom (
CONST INT_T fd,
VOID *buf,
CONST UINT_T nbytes,
TUYA_IP_ADDR_T *addr,
UINT16_T *port )
Socket 的接收来源
OPERATE_RET tkl_net_gethostbyname ( CONST CHAR_T *domain, TUYA_IP_ADDR_T *addr ) DNS 请求对应域名的 IP
INT_T tkl_net_get_nonblock ( CONST INT_T fd ) 获取 Socket 是否未被屏蔽
OPERATE_RET tkl_net_set_block ( CONST INT_T fd, CONST BOOL_T block ) 设置 Socket 屏蔽
TUYA_ERRNO tkl_net_shutdown ( CONST INT_T fd, CONST INT_T how ) 设置 Socket 关闭
OPERATE_RET tkl_net_socket_bind ( CONST INT_T fd, CONST CHAR_T *ip ) 设置 Socket 绑定
OPERATE_RET tkl_net_set_cloexec ( CONST INT_T fd ) 设置 Socket cloexec
OPERATE_RET tkl_net_get_socket_ip ( CONST INT_T fd, TUYA_IP_ADDR_T *addr ) 获取 Socket IP
OPERATE_RET tkl_net_set_timeout (
CONST INT_T fd,
CONST INT_T ms_timeout,
CONST TUYA_TRANS_TYPE_E type )
设置 Socket 超时时间
OPERATE_RET tkl_net_set_bufsize (
CONST INT_T fd,
CONST INT_T buf_size,
CONST TUYA_TRANS_TYPE_E type)
设置 Socket 缓存大小
OPERATE_RET tkl_net_set_reuse ( CONST INT_T fd ) 设置 Socket 重用
OPERATE_RET tkl_net_disable_nagle ( CONST INT_T fd ) 设置 Socket Nagle 关闭
OPERATE_RET tkl_net_set_broadcast ( CONST INT_T fd ) 设置 Socket 广播
OPERATE_RET tkl_net_set_keepalive (
INT_T fd,
CONST BOOL_T alive,
CONST UINT_T idle,
CONST UINT_T intr,
CONST UINT_T cnt )
设置 Socket 保活
OPERATE_RET tkl_net_getsockname ( INT_T fd, TUYA_IP_ADDR_T *addr, UINT16_T *port ) 获取 Socket IP 和端口
OPERATE_RET tkl_net_getpeername ( INT_T fd, TUYA_IP_ADDR_T *addr, UINT16_T *port ) 获取对端 IP 和端口
OPERATE_RET tkl_net_setsockopt (
CONST INT_T fd,
CONST TUYA_OPT_LEVEL level,
CONST TUYA_OPT_NAME optname,
CONST VOID_T *optval,
CONST INT_T optlen )
设置扩展接口
OPERATE_RET tkl_net_getsockopt (
CONST INT_T fd,
CONST TUYA_OPT_LEVEL level,
CONST TUYA_OPT_NAME optname,
VOID_T *optval,
INT_T *optlen )
获取扩展接口

适配连接接口

连接接口是指开发平台的连接能力驱动接口,如有线、Wi-Fi、低功耗蓝牙等,可以按照您的目标平台实际连接方式进行适配。

有线

接口
说明
OPERATE_RET tkl_wired_get_status ( TKL_WIRED_STAT_E *status ) 获取有线网络连接状态
OPERATE_RET tkl_wired_set_status_cb ( TKL_WIRED_STATUS_CHANGE_CB cb ) 设置有线网络连接状态变化通知回调
OPERATE_RET tkl_wired_get_ip ( NW_IP_S *ip ) 获取网络接口 IP 地址
OPERATE_RET tkl_wired_get_mac ( NW_MAC_S *mac ) 获取网络接口 Mac 地址
OPERATE_RET tkl_wired_set_mac ( CONST NW_MAC_S *mac ) 设置网络接口 Mac 地址

Wi-Fi

接口
说明
OPERATE_RET tkl_wifi_init ( WIFI_EVENT_CB cb ) 初始化 Wi-Fi
OPERATE_RET tkl_wifi_scan_ap (
CONST SCHAR_T *ssid,
AP_IF_S **ap_ary,
UINT_T *num )
扫描周边热点,可以指定 SSID
OPERATE_RET tkl_wifi_release_ap ( AP_IF_S *ap ) 释放扫描到的热点信息,和扫描配套使用,否则会导致内存泄露
OPERATE_RET tkl_wifi_start_ap ( CONST WF_AP_CFG_IF_S *cfg ) 启动热点,需要指 SSID、Passwd 等信息
OPERATE_RET tkl_wifi_stop_ap ( VOID_T ) 关闭热点,释放资源,和启动热点配套使用
OPERATE_RET tkl_wifi_set_cur_channel ( CONST UCHAR_T chan ) 设置 Wi-Fi 工作信道
OPERATE_RET tkl_wifi_get_cur_channel ( UCHAR_T *chan ) 获取 Wi-Fi 工作信道
OPERATE_RET tkl_wifi_set_sniffer (
CONST BOOL_T en,
CONST SNIFFER_CALLBACK cb )
设置 sniffer 回调,需要把 sinffer 的原始报文上报
OPERATE_RET tkl_wifi_get_ip ( CONST WF_IF_E wf, NW_IP_S *ip ) 获取 Wi-Fi 接口 IP 地址
OPERATE_RET tkl_wifi_set_ip ( CONST WF_IF_E wf, NW_IP_S *ip ) 设置 Wi-Fi 接口 IP 地址
OPERATE_RET tkl_wifi_set_mac ( CONST WF_IF_E wf, CONST NW_MAC_S *mac ) 设置 Wi-Fi 接口 MAC 地址
OPERATE_RET tkl_wifi_get_mac ( CONST WF_IF_E wf, NW_MAC_S *mac ) 获取 Wi-Fi 接口 Mac 地址
OPERATE_RET tkl_wifi_set_work_mode ( CONST WF_WK_MD_E mode ) 设置 Wi-Fi 工作模式
OPERATE_RET tkl_wifi_get_work_mode ( WF_WK_MD_E *mode ) 获取 Wi-Fi 工作模式
OPERATE_RET tkl_wifi_get_connected_ap_info ( FAST_WF_CONNECTED_AP_INFO_T **fast_ap_info ) 获取 Wi-Fi 连接的热点信息
OPERATE_RET tkl_wifi_get_bssid ( UCHAR_T *mac ) 获取 Wi-Fi 接口 bssid
OPERATE_RET tkl_wifi_set_country_code ( CONST COUNTRY_CODE_E ccode ) 设置 Wi-Fi 接口 国家码
OPERATE_RET tkl_wifi_set_rf_calibrated ( VOID_T ) 设置 Wi-Fi 射频校准标志位, 一般产测时需要使用,不使用涂鸦产测的话不需要适配
OPERATE_RET tkl_wifi_set_lp_mode ( CONST BOOL_T enable, CONST UCHAR_T dtim ) 设置 Wi-Fi 低功耗模式
OPERATE_RET tkl_wifi_station_fast_connect ( CONST FAST_WF_CONNECTED_AP_INFO_T *fast_ap_info ) Wi-Fi 基于已保存的信息,快速连接热点
OPERATE_RET tkl_wifi_station_connect ( CONST SCHAR_T *ssid, CONST SCHAR_T *passwd ) Wi-Fi 连接热点
OPERATE_RET tkl_wifi_station_disconnect ( VOID_T ) Wi-Fi 断开和热点的连接
OPERATE_RET tkl_wifi_station_get_conn_ap_rssi ( SCHAR_T *rssi ) 获取信号强度
OPERATE_RET tkl_wifi_station_get_status ( WF_STATION_STAT_E *stat ) 获取连接状态
OPERATE_RET tkl_wifi_send_mgnt ( CONST UCHAR_T *buf, CONST UINT_T len ) 发送管理帧
OPERATE_RET tkl_wifi_register_recv_mgnt_callback (
CONST BOOL_T enable,
CONST WIFI_REV_MGNT_CB recv_cb )
接收管理帧
OPERATE_RET tkl_wifi_ioctl ( WF_IOCTL_CMD_E cmd, VOID *args ) 万能接口,供后续扩展

蓝牙

蓝牙设备可以作为以下两种设备:

  • 外围(Peripheral)设备:能被 App 控制,可以接受建立连接请求的装置。
  • 中心(Central)设备:能扫描周边的外围设备,可以发起建立连接请求的装置,建立绑定关系,被遥控器类设备控制。

您可以根据自己的需求,选择需求的接口来进行适配,减少适配的工作量。

  • 蓝牙协议栈

    接口
    说明
    OPERATE_RET tkl_ble_stack_init ( UCHAR_T role ) 初始化蓝牙协议栈
    OPERATE_RET tkl_ble_stack_deinit ( UCHAR_T role ) 卸载蓝牙协议栈,和初始化对应
    OPERATE_RET tkl_ble_stack_gatt_link ( USHORT_T *p_link ) 获取 GATT 连接信息
    OPERATE_RET tkl_ble_gap_callback_register ( CONST TKL_BLE_GAP_EVT_FUNC_CB gap_evt ) 注册 GAP 事件回调
    OPERATE_RET tkl_ble_gatt_callback_register ( CONST TKL_BLE_GATT_EVT_FUNC_CB gatt_evt ) 注册 GATT 事件回调
    OPERATE_RET tkl_ble_gap_addr_set ( TKL_BLE_GAP_ADDR_T CONST *p_peer_addr ) 设置 GAP 地址
    OPERATE_RET tkl_ble_gap_address_get ( TKL_BLE_GAP_ADDR_T *p_peer_addr ) 获取 GAP 地址
    OPERATE_RET tkl_ble_gap_conn_param_update (
    USHORT_T conn_handle,
    TKL_BLE_GAP_CONN_PARAMS_T CONST *p_conn_params )
    更新连接参数
    OPERATE_RET tkl_ble_gap_tx_power_set ( UCHAR_T role, INT_T tx_power ) 设置发射功率
    OPERATE_RET tkl_ble_gap_rssi_get ( USHORT_T conn_handle ) 获取连接信号强度
  • 外围设备

    接口
    说明
    OPERATE_RET tkl_ble_gap_adv_start ( TKL_BLE_GAP_ADV_PARAMS_T CONST *p_adv_params ) 启动 GAP 广播
    OPERATE_RET tkl_ble_gap_adv_stop ( VOID ) 停止 GAP 广播
    OPERATE_RET tkl_ble_gap_adv_rsp_data_set (
    TKL_BLE_DATA_T CONST *p_adv,
    TKL_BLE_DATA_T CONST *p_scan_rsp )
    设置 adv resp 数据
    OPERATE_RET tkl_ble_gap_adv_rsp_data_update (
    TKL_BLE_DATA_T CONST *p_adv,
    TKL_BLE_DATA_T CONST *p_scan_rsp )
    更新 adv resp 数据
    OPERATE_RET tkl_ble_gap_name_set ( CHAR_T *p_name ) 设置名称
    OPERATE_RET tkl_ble_gap_disconnect (
    USHORT_T conn_handle,
    UCHAR_T hci_reason )
    断开和 central device 的连接
    OPERATE_RET tkl_ble_gatts_service_add ( TKL_BLE_GATTS_PARAMS_T *p_service ) 添加能力
    OPERATE_RET tkl_ble_gatts_value_set (
    USHORT_T conn_handle,
    USHORT_T char_handle,
    UCHAR_T *p_data,
    USHORT_T length )
    设置指定属性的值
    OPERATE_RET tkl_ble_gatts_value_get (
    USHORT_T conn_handle,
    USHORT_T char_handle,
    UCHAR_T *p_data,
    USHORT_T length )
    获取指定属性的值
    OPERATE_RET tkl_ble_gatts_value_notify (
    USHORT_T conn_handle,
    USHORT_T char_handle,
    UCHAR_T *p_data,
    USHORT_T length )
    通知指定属性,无需确认
    OPERATE_RET tkl_ble_gatts_value_indicate (
    USHORT_T conn_handle,
    USHORT_T char_handle,
    UCHAR_T *p_data,
    USHORT_T length )
    指示指定属性,需要确认
    OPERATE_RET tkl_ble_gatts_exchange_mtu_reply (
    USHORT_T conn_handle,
    USHORT_T server_rx_mtu )
    应答 MTU Exchange
  • 中心设备

    接口
    说明
    OPERATE_RET tkl_ble_gap_scan_start ( TKL_BLE_GAP_SCAN_PARAMS_T CONST *p_scan_params ) 启动扫描 GAP 广播
    OPERATE_RET tkl_ble_gap_scan_stop ( VOID ) 关闭扫描 GAP 广播,和启动对应
    OPERATE_RET tkl_ble_gap_connect (
    TKL_BLE_GAP_ADDR_T CONST *p_peer_addr,
    TKL_BLE_GAP_SCAN_PARAMS_T CONST *p_scan_params,
    TKL_BLE_GAP_CONN_PARAMS_T CONST *p_conn_params )
    连接 peripheral device
    OPERATE_RET tkl_ble_gap_disconnect ( USHORT_T conn_handle, UCHAR_T hci_reason ) 断开与 peripheral device 的连接
    OPERATE_RET tkl_ble_gattc_all_service_discovery ( USHORT_T conn_handle ) 发现所有服务
    OPERATE_RET tkl_ble_gattc_all_char_discovery (
    USHORT_T conn_handle,
    USHORT_T start_handle,
    USHORT_T end_handle )
    发现所有特征
    OPERATE_RET tkl_ble_gattc_char_desc_discovery (
    USHORT_T conn_handle,
    USHORT_T start_handle,
    USHORT_T end_handle )
    发现所有描述符
    OPERATE_RET tkl_ble_gattc_write_without_rsp (
    USHORT_T conn_handle,
    USHORT_T char_handle,
    UCHAR_T *p_data,
    USHORT_T length )
    写 GATT server 数据,不需要应答
    OPERATE_RET tkl_ble_gattc_write (
    USHORT_T conn_handle,
    USHORT_T char_handle,
    UCHAR_T *p_data,
    USHORT_T length )
    写 GATT server 数据,需要应答
    OPERATE_RET tkl_ble_gattc_read ( USHORT_T conn_handle, USHORT_T char_handle ) 读取 GATT server 数据
    OPERATE_RET tkl_ble_gattc_exchange_mtu_request (
    USHORT_T conn_handle,
    USHORT_T client_rx_mtu )
    请求 MTU exchange

适配其他外设接口

完成上述接口,可以保障 TuyaOS 最小功能集的正常运行。其他的接口,可以使用原厂接口,也可以参考 TuyaOS 提供的外设驱动进行适配。

测试验收

  • 您也可以通过开发框架自带的示例集合来验证接口适配的正确性,示例集合存放在开发框架 software/TuyaOS/apps/tuyaos_demo_examples 目录下,可以直接编译这个目录,烧录到开发板上运行,通过命令行来执行功能示例。

  • 您也可以结合您要开发的产品的实际功能,来验证产品的功能和性能。