更新时间:2025-04-25 10:27:46下载pdf
本文为您介绍如何基于 T5 平台完成 GUI 系统的开发,主要包含系统框架(通讯框架、应用框架)、应用接口的具体说明;同时,还为您提供了系统资源相关参考资料,以及系统调试、编译、示例展示等指导。
系统通讯框架 用于实现 CP0 与的 CP1 之间的通讯。
CP0 和 CP1 为 T5 的两个 CPU:
littlefs
格式)位于片外或片内 Flash,统一由 CP0 执行操作。片内 Flash 文件系统生成执行:
#./mklittlefs -c bk/ -b 4096 -p 256 -s 1880064 bk.bin
#./mklittlefs -c bk/ -b 4096 -p 256 -s 1048576 bk.bin
系统应用框架 在系统通讯框架的基础上,进一步展示了框架的各个层级、以及界面应用(GUI App)与 IoT 的产品应用(Product App)之间的联系。
本章节介绍以下应用接口:
单条消息通讯
typedef struct
{
char *tag; //对象标识,具有唯一性
uint32_t obj_type; //对象类型(如 Switch/Slider/Button 等)
uint32_t event; //事件(Widget 器件事件/系统事件)
uint32_t param; //事件内容
} LV_DISP_EVENT_S;
引用头文件
#include "tuya_app_gui_gw_core0.h"
#include "tuya_list.h"
#include "app_ipc_command.h"
#include "tkl_display.h"
#include "smart_frame.h"
#include "tal_sw_timer.h"
#include "uni_log.h"
#include "tdd_lcd.h"
#ifdef TUYA_TFTP_SERVER //调试阶段用于从局域网通过 TFTP 客户端工具上传资源文件
#include "tuya_app_gui_tftp.h"
#endif
初始化入口函数
设备在激活状态下执行以下函数之前,务必完成所有 DP 数据的初始化,否则 GUI 侧控件展示可能出现屏幕刷新现象。
STATIC VOID tuya_gui_start(BOOL_T is_mf_test)
入参:
参数 | 说明 |
---|---|
BOOL_T is_mf_test |
是否为产测模式 |
功能:
在 tuyaos_iot_t5_gui_demo_product_class-T5_gui_demo_quickstart\src\gui\tuya_app_gui_config.h
中定义相关参数,示例如下:
参数 | 示例 |
---|---|
屏幕名称 | TUYA_LCD_IC_NAME |
屏幕宽度 | TUYA_LCD_WIDTH |
屏幕高度 | TUYA_LCD_HEIGHT |
OPERATE_RET tuya_app_gui_set_lfs_partiton_type(TUYA_GUI_LFS_PARTITION_TYPE_E partition_type)
参数 | 说明 |
---|---|
partition_type = TUYA_GUI_LFS_SPI_FLASH |
当前使用芯片片内 Flash 文件系统,片内文件系统由于空间较小,暂不支持资源从云端动态更新 |
partition_type = TUYA_GUI_LFS_QSPI_FLASH |
当前使用外部 QSPI Flash 文件系统 |
处理如 GUI 侧的死机、重启、屏幕保护、语言配置及用户自定义的私有事件等请求。
OPERATE_RET tuya_gui_system_event_hdl_register(GUI_SYS_EVENT_CB cb)
用户需要特殊处理的 GUI 侧控件变换回调。
OPERATE_RET tuya_gui_obj_event_hdl_register(GUI_OBJ_EVENT_CB cb)
此注册函数提供给用户在上电时初始化控件状态,一般在设备没有被激活、无法通过组件的 DP 自身去初始化控件的情况下使用。
OPERATE_RET tuya_gui_dp2obj_pre_init_hdl_register(GUI_DP2OBJ_PRE_INIT_EVENT_CB cb)
用户需要根据实际应用,将 GUI 侧控件事件数据 LV_DISP_EVENT_S
转换为涂鸦的 DP 数据 DP_REPT_CB_DATA
。
OPERATE_RET tuya_gui_obj2dp_convert_hdl_register(GUI_OBJ2DP_CONVERT_CB cb)
VOID tuya_gui_init(BOOL_T is_mf_test, TKL_DISP_INFO_S *info, CHAR_T *weather_code)
如用户对天气预报数据的内容有特殊要求,可自定义入参中的 weather_code
,否则为系统默认的天气数据。更多信息,请参考 MCU 标准协议接入 > 天气服务。
如需要输出天气数据温度、最高温度、最低温度、湿度、天气概况数字编码,可将入参 weather_code
设置为如下 JSON 数组字符串:
["w.temp","w.thigh","w.tlow","w.humidity","w.conditionNum","w.date.1"]
w.date.1
表示需要预报一天的数据,支持 1-7 天的预报。必须包括该参数,否则后续天气数据解析会有问题。联网成功后,每半小时更新一次。应用框架支持开启宏定义 TUYA_TFTP_SERVER
来支持本地资源(图片、语言配置及字库文件)通过 TFTP 的方式上传至设备端。如产品量产固件,建议关闭该功能。
tuya_app_gui_tftp_server_init()
本章节介绍以下 GUI 应用及 GUI 相关接口:
目前支持以下绘图方式:
NXP GUI-Guider-1.7.2 (LVGL v8.3.10)(工具辅助)
将工具生成的代码目录custom&generated
导入到 项目名称\apps\tuyaos_iot_t5_gui_demo_product_class-T5_gui_demo_quickstart\src\gui\
下。
在 项目名称\apps\tuyaos_iot_t5_gui_demo_product_class-T5_gui_demo_quickstart\src\gui\generated\gui_duider.h
中增加以下行:
#include "tuya_app_gui.h"
在 项目名称\apps\tuyaos_iot_t5_gui_demo_product_class-T5_gui_demo_quickstart\src\gui\tuya_app_gui_config.h
中打开宏定义 "NXP_GUI_GUIDER"
,同时关闭宏定义 “EEZ_STUDIO”
。
EEZ Studio (0.13.1) (LVGL v8.3/LVGL v8.3 with EEZ Flow)(工具辅助)
将工具生成的代码目录src
导入到 项目名称\apps\tuyaos_iot_t5_gui_demo_product_class-T5_gui_demo_quickstart\src\gui\
下。
在项目名称\apps\tuyaos_iot_t5_gui_demo_product_class-T5_gui_demo_quickstart\src\gui\src\ui\ui.h
中增加以下行:
#include "tuya_app_gui.h"
在项目名称\apps\tuyaos_iot_t5_gui_demo_product_class-T5_gui_demo_quickstart\src\gui\tuya_app_gui_config.h
中打开宏定义 "EEZ_STUDIO"
,同时关闭宏定义 “NXP_GUI_GUIDER”
。
直接手动绘制
将手动编写的绘图 C 代码导入到 项目名称\apps\tuyaos_iot_t5_gui_demo_product_class-T5_gui_demo_quickstart\src\gui\
下。
在 项目名称\apps\T5s_gui_demo_quickstart\src\gui\tuya_app_gui_config.h
中,同时关闭宏定义 “NXP_GUI_GUIDER"
和 "EEZ_STUDIO"
。
在 项目名称\apps\tuyaos_iot_t5_gui_demo_product_class-T5_gui_demo_quickstart\src\gui\tuya_app_gui_main.c
中,将以下红色框中的函数名修改为您自己的绘图入口函数名(如不需要支持背景图启动和图片预加载,可直接设置为 NULL
):
注意事项
对象标识:由于 GUI 对象状态和业务逻辑相关联,当 GUI 对象发生改变、或业务逻辑端 DP 状态改变需要同步到 GUI 对象时,都会触发事件回调。因此,对象需要有一个唯一在业务与 GUI 之间作为信息交互的身份识别标识( 了解该对象标识,请参考 核间通讯数据结构 )。
用户可以在添加事件回调函数前,通过 lv_obj_set_tag
函数注册控件的标识(此标识必须在整个项目中具有唯一性),如下红色框标记:
事件标志:另外通过接口 aic_lvgl_msg_event_change
给 CP0 发送控件变化事件时,数据 lvglMsg_t
中的 event
成员是否带标志 LLV_EVENT_BY_DIRECT_REPORT
有如下含义:
LLV_EVENT_BY_DIRECT_REPORT
:表示控件对应的 DP 数据直接上报云端,不需要 CP0 处理任何业务逻辑。LLV_EVENT_BY_DIRECT_REPORT
:表示控件对应的 DP 数据先由 CP0 业务处理后,由业务逻辑自己上报。页面切换:如果创建一个屏幕对象,同时给该屏幕对象通过 lv_obj_set_tag
设置过 Tag,切换页面时:
lv_obj_clean()
清除当前页面子对象,一定要手动执行 lvMsgEventDel
来清除当前页面的 Tag。lv_obj_del()
清除当前页面子对象及页面父对象时,无需执行 lvMsgEventDel
来清除当前页面的 Tag。图片放在资源文件系统,程序启动时建议做预解码,以提高系统运行期间的图片加载速度(但可能会占用大量内存)。参考 \apps\tuyaos_iot_t5_gui_demo_product_class-T5_gui_demo_quickstart\src\gui\tuya_basic_demo\lv_example_switch_1.c
中的 void tuya_app_gui_img_pre_decode(void)
实现。
使用jpg_img_load
或png_img_load
做预解码时,必须使用tuya_app_gui_get_picture_full_path
获取文件的全路径。
切换页面时,必须调用 jpg_img_unload
/png_img_unload
释放对应的图片数据内存,否则会有内存泄漏。
使用img_file_load_by_id
做预解码时,用户只需要指定图片 ID。
切换页面时,切记一定调用 img_file_unload
释放对应的图片数据内存,否则会有内存泄漏。
在可以支持多语言的应用中,建议一定按照下图所示步骤使用:
首先,通过接口函数 const void *tuya_app_gui_display_text_font_get(char *node_name)
输入入参文本标签,得到指定的字库信息(语言 > data.file 中提及)。
如获取不到字库信息,请不要强通过 lv_obj_set_style_text_font
函数设置字体,否则会因字库内容异常而导致系统崩溃。
然后,通过接口函数 const void *tuya_app_gui_display_text_get(char *node_name)
输入入参文本标签,得到指定的文本信息(语言 > data.file 中提及)。
如获取不到文本信息,请不要强制通过 lv_label_set_text
函数设置文本,否则会因文本异常而导致系统崩溃。
切换语言时,系统会清除之前的旧语言环境、使用新语言环境,所以在响应语言切换的控件回调处理函数中,必须要更新页面中所有使用到字库的文字控件。
如果只更新部分文字控件,会导致 LVGL 在下一个屏幕刷新周期来到时,因指向旧语言环境的文字控件找不到旧语言环境而导致系统异常。
CP0 侧 DP 数据变化通知注册回调:
捕获 CP0 侧 DP 发生变化时处理回调函数。用户回调处理函数要区分是普通 DP 数据(DP_CNTL_S *
)或是 Raw 类型数据(TY_RAW_DP_REPT_S *
),然后将不同的数据信息转变成对应的控件信息。
void tuya_app_gui_dp_update_notify_callback_register (gui_dp_update_cb_t cb)
CP1 请求获取指定 DP 的相关信息接口(仅在设备激活状态有效):
通过指定的 DPID 获取相关的信息(DP_CNTL_S *
)。Raw 类型数据信息暂不支持获取,需要数据变化时用户自己缓存。
void *tuya_app_gui_get_dp_cntl(unsigned char dpid)
CP1 请求获取当前 Wi-Fi 连接状态信息接口:
查询 Wi-Fi 是否连接上云端。仅当连接上时,输出的 RSSI 及 SSID 为有效。
bool tuya_app_gui_is_wifi_connected(signed char *out_rssi, char *ssid_buff, int ssid_buff_size)
CP1 请求获取当前设备激活状态信息接口:
bool tuya_app_gui_is_dev_activeted(void)
CP1 请求解绑当前设备接口:
void tuya_app_gui_request_dev_unbind(void)
CP1 请求获取当前时间信息接口:
bool tuya_app_gui_request_local_time(char *time_buff, int time_buff_size)
CP1 请求获取天气预报数据接口:
查询当前天气信息(天气预报数据格式为:LKTLV)。更多天气服务相关,请参考 MCU 标准协议接入 > 天气服务。
bool tuya_app_gui_request_local_weather(char **local_weather, uint32_t *weather_len)
local_weather
为输出的天气信息字符串,使用完后需要用户手动释放其指向的内存。
CP1 请求资源更新接口:
查询云端是否有新的资源可供更新。
void tuya_app_gui_query_resource_update(void)
配置读写相关接口(由于以下接口写操作均采用了异步操作,所以不支持执行写操作后立即回读):
读接口:value
所指向的内存空间需要使用者自己释放。
bool tuya_app_gui_kv_common_read(char *key, unsigned char **value, uint32_t *p_len)
写接口:
bool tuya_app_gui_kv_common_write(char *key, unsigned char *value, uint32_t len)
读接口:value
所指向的内存空间需要使用者自己释放。
bool tuya_app_gui_fs_kv_common_read(char *key, unsigned char **value, uint32_t *p_len);
写接口:
bool tuya_app_gui_fs_kv_common_write(char *key, unsigned char *value, uint32_t len)
如果已有的事件类型无法满足用户在 CP0 与 CP1 之间的交互需求,用户可以使用自定义的私有事件 LLV_EVENT_USER_PRIVATE
:
在 CP1 侧定义一个处理函数,其中 data
为 lvglMsg_t
类型的指针。
void tuya_app_gui_user_private_event_process(void *data)
定义一个私有的数据结构,交互时将指针指向 lvglMsg_t
中的 param
参数。
首次使用开发板时,板载的外挂 Flash 挂载失败会导致屏幕无法点亮,需要在日志命令行手动执行以下操作后重启:
xqspi fce
擦除外部 Flash。lfs mkfs
格式化外部 Flash。屏幕点亮后,由于 Flash 中文件系统为空,所以屏幕没有相关图片及文字展示,需要按照以下方法生成文件系统:
在 项目名称\tuyaos_iot_t5_gui_demo_product_classT5_gui_demo_quickstart\sr\gui\project_resource_sample\littlefs
下有一个系统资源例程,其中,bk
文件夹是要打包的文件系统内容(注意:所有资源文件名长度(包含扩展名)不能超过 32 个字符),将要打包的内容按照文件夹的目录树结构方式存放到里面,通过工具生成文件系统镜像 bk.bin
:
片内 Flash 文件系统生成:
./mklittlefs -c bk/ -b 4096 -p 256 -s 1880064 bk.bin
执行完成后,按照下图所示的指导,将 bk.bin
导入工具,并按照 系统通讯框架 中描述的值设置好 起始地址。(“文件长度” 即文件的大小。文件越大,地址的长度会越长;文件长度会自动生成,无需额外操作。)
片外 Flash 文件系统生成(请根据实际使用的 Flash 规则参数确定参数 -b -p -s
):
./mklittlefs -c bk/ -b xxx -p xxx -s xxx bk.bin
bk.bin
烧录至 QSPI Flash。工具参数定义
参数 | 说明 |
---|---|
-b |
块大小,默认 4096 |
-p |
页面大小,默认 256 |
-c |
输入的素材文件夹 |
-s |
输出镜像大小,不能小于实际素材大小(如果使用片外 Flash,就是 Flash 大小的字节数目) |
-bk.bin |
输出的镜像文件名称 |
多语言配置会消耗较大内存资源。如果产品应用只有一种语言,建议不要使用以下配置,而使用静态字库方式。
data_file
:该文件夹中保存 GUI 中所使用的的语言文本定义,请严格按照 JSON 例程中的格式来组织。
中文语言文本定义:
英文语言文本定义:
各种语言文件夹定义见下表。(如有其它语言需求,请联系涂鸦的开发者。)
语言 | 文件夹 |
---|---|
中文 | “ch” |
英文 | “en” |
韩文 | “kr” |
日文 | “jp” |
法文 | “fr” |
德文 | “de” |
俄文 | “ru” |
印度文 | “in” |
font
:该文件夹保存字体库(目前仅支持 TTF 字体库),请使用授权的正版字体库,否则系统字体解析会出现异常。使用时,该字体库的名称(除后缀 .ttf 外)一定要保持与上述语言文件夹中的字库名一致。
使用:例如,lv_label_set_text(language_label, tuya_app_gui_display_text_get("language_test"))
中,表示对象 language_label
使用文本标签 "language_test"
所对应的文字信息。
language_label
则会显示 共以 (展示文字,无实际意义)。picture
:该文件夹保存 GUI 所使用到的图片资源,支持 JPG、PNG 及 GIF 等格式。为保证 GUI 在使用过程中显示图片的流畅性,建议做图片的预解码处理(注意:预解码的图片可能会导致占用大量内存)。了解更多图片预解码相关,请参考 图片预解码。
1.jpg
、1.png
或 1.gif
开始,ID 不能重名,依次往后增加),用户程序在需要使用的地方调用对应的图片名称。138x42
),不要使用像素为奇数的图片(如 135x41
),否则用户可通过相关图片编辑工具将奇数的像素转换为偶数像素。192x192
)。music
:音乐文件的命名方式。每首音乐按照唯一数字 ID 的方式命名(从 1.mp3
开始,ID 不能重名,依次往后增加),用户程序在需要使用的地方调用对应的名称。
该行暂不支持删除。
version.inf
:如 0.1
关于资源的具体使用示例教程,请参考 Demo 文件中的 lv_example_switch_1.c
C 文件。
前往 Tftpd64 下载客户端。
开启设备端 TFTF Server 服务:
在项目名称\apps\tuyaos_iot_t5_gui_demo_product_class-T5_gui_demo_quickstart\src\gui\tuya_app_gui_config.h
中打开宏定义"TUYA_TFTP_SERVER"
。
量产阶段,固件务必关闭此宏定义,避免出现安全问题。
从设备日志端获取 TFTF Server IP 及端口信息,如下:
在 Windows 端打开 TFTP 客户端工具,按照下图所示进行配置:
配置完成后:
目前仅识别如下几种 GUI 相关的文件格式:
文件 | 格式说明 |
---|---|
语言配置文件 | .json |
字体库文件 | .ttf |
音频文件(暂不支持) | .mp3 。音频文件名相关格式,请参考 音乐 |
图片文件 | .jpg/.png/.gif 。图片文件名相关格式,请参考 图片 |
资源信息文件 | version.inf 。固定名称,不可改变 |
上传语言配置文件时(语言前缀相关,请参考 语言 中的详细描述),命名规则必须为 语言_文件名.json
,例如:
xxx.json
时,更改名称为 ch_xxx.json
。yyy.json
时,更改为 en_yyy.json
。jjj.json
时,更改为 kr_jjj.json
。UART1
,波特率为 460800。UART2
,波特率为 2000000。带 GUI 例程的工程名为 tuyaos_iot_t5_gui_demo_product_class-T5_gui_demo_quickstart
,编译代码如下所示:
./build_app.sh apps/tuyaos_iot_t5_gui_demo_product_class-T5_gui_demo_quickstart/ tuyaos_iot_t5_gui_demo_product_class-T5_gui_demo_quickstart 1.0.0
开发包已支持两种屏幕大小的可选宏定义配置:
T35P128CQ
T50P181CQ
用户可根据已有开发板,在路径 \apps\tuyaos_iot_t5_gui_demo_product_class-T5_gui_demo_quickstart\src\gui\tuya_app_gui_config.h
)下进行配置,如下图所示:
文件 tuyaos_iot_t5_gui_demo_product_class\apps\T5_gui_demo_quickstart\default_gpio_config.json
与当前系统使用的 GPIO 中断配置有关。
例如,当 TP 触控屏的中断脚 tp_intr
配置为 TUYA_GPIO_NUM_55
时,对应文件中的配置应同步如下图所示:
该内容对您有帮助吗?
是意见反馈该内容对您有帮助吗?
是意见反馈