移植指南

更新时间:2023-11-09 09:17:38下载pdf

TuyaOS 定义了一套标准化的 TuyaOS Kernel Layer(TKL),旨在屏蔽硬件和系统的差异性,实现跨平台兼容性。TKL 接口涵盖了系统和业务相关的功能,例如内存分配、互斥锁、信号量等。

针对 Linux 操作系统,系统相关的接口遵循统一的 POSIX 标准。因此,如果没有特殊需求,您可以直接使用 TuyaOS 开发环境提供的示例代码。然而,业务相关的接口在不同的硬件和芯片上可能存在差异,您需要根据具体情况进行适配。

本文将详细介绍如何适配 TKL 接口,以便您能够轻松地实现 TKL 接口的适配,从而确保 TuyaOS 开发框架在特定的硬件平台上顺利运行。

TKL 接口简介

TuyaOS Kernel Layer(TKL)是 TuyaOS 定义的一套标准化的 API 接口,旨在屏蔽硬件和系统的差异性。TKL 接口的定义和示例实现代码放置在开发环境中,跟随开发环境更新和发布。

  • TKL 接口定义:software/TuyaOS/vendor/<开发环境>/tuyaos/tuyaos_adapter/include
  • TKL 接口示例:software/TuyaOS/vendor/<开发环境>/tuyaos/tuyaos_adapter/src

只有使用 TuyaOS SDK 模式时才需要适配 TKL 接口,TuyaOS OS 模式涂鸦已经给特定的芯片平台适配了 TKL 接口。

TKL 接口说明

系统相关接口:

模块 描述
tkl_fs 提供操作文件系统的接口,包括文件的创建、打开、读写等操作
tkl_system 提供 OS 相关的接口,包括获取系统时间、延时、重启等操作
tkl_memory 提供内存管理的接口,包括内存分配、释放、拷贝等操作
tkl_thread 提供线程管理的接口,包括线程的创建、销毁等操作
tkl_mutex 提供互斥锁管理的接口,包括互斥锁的创建、上锁、解锁、销毁等操作
tkl_semaphore 提供信号量管理的接口,包括信号量的创建、等待、发送、销毁等操作
tkl_uart 提供串行通信的接口,包括 UART 的初始化、发送、接收等操作

业务相关接口:

模块 描述
tkl_wired 自动发现配网以及 4G 扫码配网的接口,包括获取 IP 地址、获取网络接口连接状态等
tkl_wifi AP 配网的接口,包括启动热点、连接路由器、获取 IP 地址、获取无线连接状态等
tkl_bluetooth 蓝牙配网的接口,包括蓝牙协议栈初始化、注册 GAP/GATT 回调、设置广播数据、设置扫描响应数据等
tkl_output 日志输出的接口

TKL 接口适配

tkl_wired

自动发现配网以及 4G 扫码配网接口。无论采用以太网连接、4G 连接,还是通过屏幕连接 Wi-Fi,该接口适用于无需 TuyaOS 参与、即可分配 IP 地址的场景。

TuyaOS 需要指定网卡与涂鸦 App、涂鸦 IoT 云通信,并需感知网卡的连通性。不同产品可能使用不同网卡,不同硬件检查网卡连通性的方式亦有差异。因此,该接口需您进行适配,示例代码仅供参考。

详细的适配指南,请参考 有线连接

tkl_wifi

AP 配网接口。设备需要通过 TuyaOS 与涂鸦 App 通信(Wi-Fi 链路)获取路由器的 SSID 和密码,然后连接路由器访问互联网,TuyaOS 提供 AP 配网能力以实现此功能。

详细的适配指南,请参考 无线连接

tkl_bluetooth

蓝牙配网接口。设备需要通过 TuyaOS 与涂鸦 App 通信(蓝牙链路)获取路由器的 SSID 和密码,然后连接路由器访问互联网,TuyaOS 提供蓝牙配网能力以实现此功能。

详细的适配指南,请参考 蓝牙连接

tkl_output

日志输出接口。TuyaOS 提供分级别的日志记录功能,您可以自由选择输出媒介,包括串口、文件、终端和网络等。TuyaOS 已经把日志进行格式化处理,您只需要把日志输出到对应的媒介。

接口 说明
VOID_T tkl_log_output(CONST CHAR_T *format, …) 日志输出

tkl_fs

文件系统接口,Linux 遵循统一的 POSIX 标准,无需适配,直接使用示例代码即可。

接口 说明
INT_T tkl_fs_mkdir(CONST CHAR_T *path) 创建目录
INT_T tkl_fs_remove(CONST CHAR_T *path) 删除目录
INT_T tkl_fs_mode(CONST CHAR_T *path, UINT_T *mode) 修改目录权限
INT_T tkl_fs_is_exist(CONST CHAR_T *path, BOOL_T *is_exist) 文件或目录是否存在
INT_T tkl_fs_rename(CONST CHAR_T *path_old, CONST CHAR_T *path_new) 重命名文件或目录
INT_T tkl_dir_open(CONST CHAR_T *path, TUYA_DIR *dir) 打开目录
INT_T tkl_dir_close(TUYA_DIR dir) 关闭目录
INT_T tkl_dir_read(TUYA_DIR dir, TUYA_FILEINFO *info) 读取目录
INT_T tkl_dir_name(TUYA_FILEINFO info, CONST CHAR_T **name) 读取目录名称
INT_T tkl_dir_is_directory(TUYA_FILEINFO info, BOOL_T *is_dir) 是否是目录
INT_T tkl_dir_is_regular(TUYA_FILEINFO info, BOOL_T *is_regular) 是否是文件
TUYA_FILE tkl_fopen(CONST CHAR_T *path, CONST CHAR_T *mode) 打开文件
INT_T tkl_fclose(TUYA_FILE file) 关闭文件
INT_T tkl_fread(VOID_T *buf, INT_T bytes, TUYA_FILE file) 读取文件
INT_T tkl_fwrite(VOID_T *buf, INT_T bytes, TUYA_FILE file) 写入文件
INT_T tkl_fsync(INT_T fd) 文件同步到磁盘
CHAR_T *tkl_fgets(CHAR_T *buf, INT_T len, TUYA_FILE file) 读取文件
INT_T tkl_feof(TUYA_FILE file) 是否已经到文件结尾
INT_T tkl_fseek(TUYA_FILE file, INT64_T offs, INT_T whence) 设置偏移量
INT64_T tkl_ftell(TUYA_FILE file) 获取当前位置
INT_T tkl_fgetsize(CONST CHAR_T *filepath) 获取文件大小
INT_T tkl_fgetc(TUYA_FILE file) 读取下一个字符
INT_T tkl_fflush(TUYA_FILE file) 刷新 IO 缓冲区
INT_T tkl_fileno(TUYA_FILE file) 获取文件描述符
INT_T tkl_ftruncate(INT_T fd, UINT64_T length) 截断文件

tkl_system

OS 接口,无需适配,直接使用示例代码即可。

接口 说明
SYS_TICK_T tkl_system_get_tick_count(VOID_T) 获取系统运行的时间
SYS_TIME_T tkl_system_get_millisecond(VOID_T) 获取系统的毫秒计数
VOID_T tkl_system_sleep(CONST UINT_T num_ms) 睡眠
VOID_T tkl_system_reset(VOID_T) 重启
INT_T tkl_system_get_free_heap_size(VOID_T) 获取剩余内存
TUYA_RESET_REASON_E tkl_system_get_reset_reason(CHAR_T **describe) 获取重启原因
INT_T tkl_system_get_random(CONST UINT_T range) 生成随机数
UINT_T tkl_system_enter_critical(VOID_T) 进入临界区
VOID_T tkl_system_exit_critical(UINT_T irq_mask) 退出临界区
VOID_T tkl_system_delay(UINT_T num_ms) 延时
OPERATE_RET tkl_system_get_cpu_info(TUYA_CPU_INFO_T **cpu_ary, INT_T *cpu_cnt) 获取 CPU 信息

tkl_memory

内存管理的接口,无需适配,直接使用示例代码即可。

接口 说明
VOID_T *tkl_system_malloc(CONST SIZE_T size) 分配内存
VOID_T tkl_system_free(VOID_T *ptr) 释放内存
VOID_T *tkl_system_memset(VOID_T *src, INT_T ch, CONST SIZE_T n) 清空数据
VOID_T *tkl_system_memcpy(VOID_T *src, CONST VOID_T *dst, CONST SIZE_T n) 内存拷贝
VOID_T *tkl_system_calloc(size_t nitems, size_t size) 分配并清空内存
VOID_T *tkl_system_realloc(VOID_T *ptr, size_t size) 重新分配内存

tkl_thread

线程管理接口,无需适配,直接使用示例代码即可。

接口 说明
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(CONST TKL_THREAD_HANDLE thread) 销毁并结束线程
OPERATE_RET tkl_thread_get_id(TKL_THREAD_HANDLE *thread) 获取线程句柄
OPERATE_RET tkl_thread_set_self_name(CONST CHAR_T* name) 获取线程名称

tkl_mutex

互斥锁管理接口,无需适配,直接使用示例代码即可。

接口 说明
OPERATE_RET tkl_mutex_create_init(TKL_MUTEX_HANDLE *handle) 创建互斥锁
OPERATE_RET tkl_mutex_lock(CONST TKL_MUTEX_HANDLE handle) 上锁
OPERATE_RET tkl_mutex_trylock(CONST TKL_MUTEX_HANDLE handle) 尝试上锁
OPERATE_RET tkl_mutex_unlock(CONST TKL_MUTEX_HANDLE handle) 解锁
OPERATE_RET tkl_mutex_release(CONST TKL_MUTEX_HANDLE handle) 释放互斥锁

tkl_semaphore

信号量管理接口,无需适配,直接使用示例代码即可。

接口 说明
OPERATE_RET tkl_semaphore_create_init(TKL_SEM_HANDLE *handle, CONST UINT_T sem_cnt, CONST UINT_T sem_max) 创建信号量
OPERATE_RET tkl_semaphore_wait(CONST TKL_SEM_HANDLE handle, CONST UINT_T timeout) 等待信号量
OPERATE_RET tkl_semaphore_post(CONST TKL_SEM_HANDLE handle) 发送信号量
OPERATE_RET tkl_semaphore_release(CONST TKL_SEM_HANDLE handle) 释放信号量

tkl_uart

串行通信接口,如无特殊需求,直接使用示例代码即可。

示例代码适配了串口设备名称为 /dev/ttyS*/dev/ttyUSB*。如果您的硬件平台串口设备名称不是这两种类型,则需要修改串口设备名称。

接口 说明
OPERATE_RET tkl_uart_init(UINT_T port_id, TUYA_UART_BASE_CFG_T *cfg) 初始化串口
OPERATE_RET tkl_uart_deinit(UINT_T port_id) 反初始化串口
INT_T tkl_uart_write(UINT_T port_id, VOID_T *buff, UINT16_T len) 写数据
INT_T tkl_uart_read(UINT_T port_id, VOID_T *buff, UINT16_T len) 读数据