T5平台GUI开发指导

Wi-Fi 设备、Wi-Fi 低功耗设备、Wi-Fi BLE 双模设备、Ethernet设备、Ethernet+Wi-Fi设备等
Post Reply
liujt@tuya.com
Posts: 36

  1. 系统通讯框架

    系统通讯框架.png

    目前资源文件系统(统一使用littlefs格式)位于片外flash或片内(起始地址:0x600000,长度:0x1cb000(1836KB=1880064Bytes))(统一由cp0操作)

  2. 系统应用框架

    系统应用框架.png
  3. 应用接口

    1. 核间通讯数据结构

      1. 单条消息通讯

        Code: Select all

            typedef struct
            {
                char *tag;		//对象标识,具有唯一性
                uint32_t obj_type;  	//对象类型(如switch/slider/button等)
                uint32_t event;       	//事件(widget器件事件/系统事件)
                uint32_t param;     	//事件内容
            } LV_DISP_EVENT_S;
                        
    2. CP0(产品应用)

      1. 引用头文件
        #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

      2. 初始化入口函数
        设备在激活状态下执行以下函数前务必完成所有dp数据的初始化,否则gui侧控件展示可能会有屏幕刷新现象
        STATIC VOID tuya_gui_start(BOOL_T is_mf_test)

        1. 入参BOOL_T is_mf_test:是否为产测模式

        2. 屏幕及TP使用引脚初始化
          在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

        3. 设置文件系统所在分区(内部flash或外部flash)
          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文件系统

        4. GUI系统事件处理回调注册:处理如gui侧的死机,重启,屏幕保护,语言配置及用户自定义的私有等请求
          OPERATE_RET tuya_gui_system_event_hdl_register(GUI_SYS_EVENT_CB cb)

        5. 需特殊处理的GUI控件变化事件处理回调注册(产品应用不需要,可忽略):用户需特殊处理的gui侧控件变换回调(组件已经帮忙处理控件对应dp的上报逻辑,如果不需要对特定控件变换进行处理,可无需注册)
          OPERATE_RET tuya_gui_obj_event_hdl_register(GUI_OBJ_EVENT_CB cb)

        6. 用户手动初始化GUI控件状态的处理回调注册(这个注册函数提供给用户在上电时初始化控件状态,一般当设备没有被激活无法通过组件的dp自身去初始化控件的情况下使用)
          OPERATE_RET tuya_gui_dp2obj_pre_init_hdl_register(GUI_DP2OBJ_PRE_INIT_EVENT_CB cb)

        7. GUI控件至涂鸦dp转换回调注册:用户需要根据实际应用,将gui侧控件事件数据LV_DISP_EVENT_S转换为涂鸦的dp数据DP_REPT_CB_DATA.
          OPERATE_RET tuya_gui_obj2dp_convert_hdl_register(GUI_OBJ2DP_CONVERT_CB cb)

        8. 核心函数初始化
          VOID tuya_gui_init(BOOL_T is_mf_test, TKL_DISP_INFO_S *info, CHAR_T weather_code)
          如果用户对天气预报数据的内容有特殊要求,可自定义入参中的weather_code,否则为系统默认的天气数据,可参考:https://developer.tuya.com/cn/docs/mcu- ... fvzw7ny80s,如需要输出天气数据温度,最高温度,最低温度,湿度,天气概况数字编码(这里使用天气概况数字编码主要是为了适用不同国家时多语言配置,),可将入参weather_code设置为如下json数组字符串(w.date.1 :表示需要预报一天的数据,支持17天的预报,一定要包括该参数,否则后面天气数据解析会有问题,联网成功后,每半小时更新一次):
          "[\"w.temp\",\"w.thigh\",\"w.tlow\",\"w.humidity\",\"w.conditionNum\",\"w.date.1\"]"

        9. tftp服务初始化
          应用框架支持开启宏定义TUYA_TFTP_SERVER来支持本地资源(图片,语言配置及字库文件)通过tftp的方式上传至设备端,建议产品量产固件关闭该功能
          tuya_app_gui_tftp_server_init()

    3. CP1(GUI应用)

      1. 目前支持的绘图方式

        1. NXP GUI-Guider-1.7.2(LVGL v8.3.10)(工具辅助)
          a.将工具生成的代码目录custom&generated导入到:项目名称\apps\tuyaos_iot_t5_gui_demo_product_class-T5_gui_demo_quickstart\src\gui\下.
          b.在项目名称\apps\tuyaos_iot_t5_gui_demo_product_class-T5_gui_demo_quickstart\src\gui\generated\gui_duider.h中增加以下行:
          #include "tuya_app_gui.h"
          c.在项目名称\apps\tuyaos_iot_t5_gui_demo_product_class-T5_gui_demo_quickstart\src\gui\tuya_app_gui_config.h中打开宏定义"NXP_GUI_GUIDER"(同时关闭宏定义“EEZ_STUDIO”)

        2. EEZ Studio(0.13.1)(LVGL v8.3/LVGL v8.3 with EEZ Flow)(工具辅助)
          a.将工具生成的代码目录src导入到:项目名称\apps\tuyaos_iot_t5_gui_demo_product_class-T5_gui_demo_quickstart\src\gui\下.
          b.在项目名称\apps\tuyaos_iot_t5_gui_demo_product_class-T5_gui_demo_quickstart\src\gui\src\ui\ui.h中增加以下行:
          #include "tuya_app_gui.h"
          c.在项目名称\apps\tuyaos_iot_t5_gui_demo_product_class-T5_gui_demo_quickstart\src\gui\tuya_app_gui_config.h中打开宏定义"EEZ_STUDIO"(同时关闭宏定义“NXP_GUI_GUIDER")

        3. 直接手动绘制
          a.将手动编写的绘图c代码导入到:项目名称\apps\tuyaos_iot_t5_gui_demo_product_class-T5_gui_demo_quickstart\src\gui\下
          b.在项目名称\apps\T5s_gui_demo_quickstart\src\gui\tuya_app_gui_config.h中同时关闭宏定义“NXP_GUI_GUIDER"及"EEZ_STUDIO"
          c.在项目名称\apps\tuyaos_iot_t5_gui_demo_product_class-T5_gui_demo_quickstart\src\gui\tuya_app_gui_main.c中将以下红色框中的函数名修改为你自己的绘图入口函数名:

          main_init.png

          d.注意点:

          1. 由于GUI对象状态和业务逻辑是相关联的,当GUI对象发生改变时或业务逻辑端dp状态改变需要同步到GUI对象时,此时都会触发事件回调,那么对象需要有一个唯一在业务与GUI之间作为信息交互的身份识别标识,这里会涉及3.1中提及对象标识。用户可以在添加事件回调函数前通过lv_obj_set_tag函数注册控件的标识(注意:这个标识在整个项目中一定具有唯一性),如下红色框中

            tag.png
          2. 另外通过接口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业务处理后,由业务逻辑自己上报

          3. 如果创建一个屏幕对象,同时给该屏幕对象通过lv_obj_set_tag设置过tag,切换页面时:
            仅通过lv_obj_clean()清除当前页面子对象,一定要手动执行lvMsgEventDel来清除当前页面的tag,如下:
            若通过lv_obj_del()清除当前页面子对象及页面父对象时,无需执行lvMsgEventDel来清除当前页面的tag

      2. GUI图片预解码
        图片放在资源文件系统,程序启动时建议做预解码(参考\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)中的实现)

        1. 使用jpg_img_load或png_img_load做预解码时,一定要使用tuya_app_gui_get_picture_full_path获取文件的全路径(切换页面时,切记一定调用jpg_img_unload/png_img_unload释放对应的图片数据内存,否则有内存泄漏)

        2. 使用img_file_load_by_id做预解码时,用户只需要指定图片id(切换页面时,切记一定调用img_file_unload释放对应的图片数据内存,否则有内存泄漏)

      3. 语言文字使用
        在可以支持多语言的应用中,建议一定按照如下图步骤使用:

        language_sw.png
        1. 先通过接口函数const void *tuya_app_gui_display_text_font_get(char node_name),输入入参文本标签得到指定的文本内容(4.1中提及)(注意:获取不到文本内容,就不要强制再通过lv_obj_set_style_text_font函数设置文字,否则文本内容异常会导致系统崩溃)

        2. 然后通过接口函数const void *tuya_app_gui_display_text_font_get(char node_name),输入入参文本标签得到指定的字库信息(4.1中提及)(注意:获取不到字库信息,就不要强制再通过lv_obj_set_style_text_font函数设置字体,否则字库异常会导致系统崩溃)

        3. 切换语言时,系统会清除之前的老的语言环境而使用新的语言环境,所以在响应语言切换的控件回调处理函数中,必须要更新页面中所有使用到字库的文字控件(如果只更新部分文字控件会导致lvgl在下一个屏幕刷新周期来到的时候,指向老的语言环境的文字控件因找不到老的语言环境而导致系统异常)

      4. GUI相关接口使用

        1. 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)

        2. cp1请求获取指定dp的相关信息接口(仅在设备激活状态有效):通过指定的dpid获取相关的信息(DP_CNTL_S *), (raw类型数据信息暂不支持获取,需要数据变化时用户自己缓存)
          void tuya_app_gui_get_dp_cntl(unsigned char dpid)

        3. cp1请求获取当前wifi连接状态信息接口:查询wifi是否连接上云端(仅当连接上时,输出的rssi及ssid为有效)
          bool tuya_app_gui_is_wifi_connected(signed char *out_rssi, char ssid_buff, int ssid_buff_size)

        4. cp1请求获取当前设备激活状态信息接口:bool tuya_app_gui_is_dev_activeted(void)

        5. cp1请求解绑当前设备接口:void tuya_app_gui_request_dev_unbind(void)

        6. cp1请求获取当前时间信息接口:bool tuya_app_gui_request_local_time(char time_buff, int time_buff_size)

        7. cp1请求获取天气预报数据接口:查询当前天气信息(天气预报数据格式为:LKTLV),参考https://developer.tuya.com/cn/docs/mcu-standard-protocol/mcusdk-wifi-weather?id=Kd2fvzw7ny80s#title-3-%E4%B8%8B%E5%8F%91%E5%A4%A9%E6%B0%94%E6%95%B0%E6%8D%AE%EF%BC%880x21%EF%BC%89
          bool tuya_app_gui_request_local_weather(char **local_weather, uint32_t *weather_len)
          **注意:local_weather为输出的天气信息字符串,使用完后需要用户手动释放其指向的内存

        8. cp1请求资源更新接口:该接口会查询云端是有有新的资源可供更新
          void tuya_app_gui_query_resource_update(void)

        9. 配置读写相关接口(由于以下接口写操作均采用了异步操作,所以不支持执行写操作后立即回读):

          1. kv操作相关(配置保存在片内kv区域)
            a.读接口:bool tuya_app_gui_kv_common_read(char *key, unsigned char **value, uint32_t *p_len)
            "value"所指向的内存空间需要使用者自己释放
            b.写接口:bool tuya_app_gui_kv_common_write(char *key, unsigned char value, uint32_t len)

          2. kv文件操作相关(配置保存在flash的文件系统区域)
            a.读接口:bool tuya_app_gui_fs_kv_common_read(char *key, unsigned char **value, uint32_t *p_len);
            "value"所指向的内存空间需要使用者自己释放
            b.写接口:bool tuya_app_gui_fs_kv_common_write(char *key, unsigned char value, uint32_t len)

      5. tuya手势功能
        关闭宏定义“NXP_GUI_GUIDER"及"EEZ_STUDIO",另外在\apps\T5s_gui_demo_quickstart\src\gui\tuya_app_gui_config.h中开启“TUYA_PAGE_TILEVIEW”宏定义外,同时还要在vendor\T5\t5_os\projects\tuya_app\config\bk7258_cp1\config中设置"CONFIG_TUYA_PAGE_TILEVIEW=y”

      6. 用户自定义的私有事件
        如果已有的事件类型无法满足用户在cp0与cp1之间交互需求,用户可以使用自定义的私有事件LLV_EVENT_USER_PRIVATE,需要
        a.在cp1侧定义一个处理函数: void tuya_app_gui_user_private_event_process(void *data)
        b.定义一个私有的数据结构,交互时将指针指向lvglMsg_t中的param参数

  4. 系统资源(littlefs格式)

    1. 开发板首次使用时,板载的外挂flash挂载失败会导致屏幕无法点亮,需要在日志命令行手动执行以下操作后重启:

      1. 首先执行擦除外部flash:

        • xqspi fce\r\n

      2. 然后执行格式化外部flash:

        • lfs mkfs\r\n

    2. 屏幕点亮后,由于flash中文件系统为空,所以屏幕没有相关图片及文字展示,需要按照以下方法生成文件系统生成:
      在项目名称\tuyaos_iot_t5_gui_demo_product_classT5_gui_demo_quickstart\sr\gui\project_resource_sample\littlefs
      下有一个系统资源例程,bk文件夹是要打包的文件系统内容(注意:所有资源文件名长度(包含扩展名)<=32个字符),将要打包的内容按照文件夹的目录树结构方式存放到里面,通过工具生成文件系统镜像bk.bin:

      1. 片内flash文件系统生成执行:
        ./mklittlefs -c bk/ -b 4096 -p 256 -s 1880064 bk.bin
        执行完成后按照文件"如何烧录文件系统镜像文件.png"的指导,将bk.bin导入工具,按照第1节描述的值设置好"起始地址“("文件长度"会自动生成,不要操作)

      2. 片外flash文件系统生成执行(以下参数-b -p -s请根据实际使用的flash规则参数确定):
        ./mklittlefs -c bk/ -b xxx -p xxx -s xxx bk.bin
        执行完成后将bk.bin烧录至qspi-flash.

      3. 工具参数定义如下:
        -b 块大小,默认4096
        -p 页面大小,默认256
        -c 输入的素材文件夹
        -s 输出镜像大小,不能小于实际素材大小(如果使用片外flash,就是flash大小的字节数目)
        -bk.bin 输出的镜像文件名称

    3. 目录结构树如下:

      res_folder.png
    4. 语言
      多语言配置会消耗较大内存资源,如果产品应用只有一种语言,建议不要使用以下配置而使用静态字库方式.

      1. data_file:该文件夹中保存gui中所使用的的语言文本定义,请严格按照json例程中的格式来组织,如:
        中文语言文本定义:

        lang_chinese.png

        英文语言文本定义:

        lang_english.png

        各种语言文件夹定义如下(如有其它语言需求,请联系开发者):
        中文:“ch”;
        英文:“en”;
        韩文:“kr”;
        日文:“jp”;
        法文:“fr”;
        德文:“de”;
        俄文:“ru”;
        印度文:“in”.

      2. font:该文件夹保存字体库(目前仅支持ttf字体库),请使用授权的正版字体库,否则系统字体解析会出现异常。使用时,该字体库的名称(除后缀.ttf外)一定要保持与上述语言文件夹中的字库名一致。

      3. 使用:如lv_label_set_text(language_label, tuya_app_gui_display_text_get("language_test"));
        表示对象language_label使用文本标签"language_test"所对应的文字信息,如果当前语言设置为中文,该language_label则会显示“共以”,若当前语言设置为英文,则会显示“ENGLISH”。

    5. 图片
      picture:该文件夹保存gui所使用到的图片资源,支持jpg,png及gif等格式。为保证gui在使用过程中显示图片的流畅性建议做图片的预解码处理(这样也会导致占用过多内存),参考3.3.

      1. 图片的命名方式:每张图片按照唯一数字ID的方式命名(从1.jpg或1.png或1.gif,开始,ID不能重名,依次往后增加),用户程序在需要使用的地方调用对应的图片名称

      2. 由于系统内部解码图像时是按照4字节搬运的,使用jpg图片时,切记图片的像素一定是偶数(如138x42),不要使用像素为奇数的图片(如135x41),否则用户可通过相关图片编辑工具将奇数的像素转换为偶数像素。

    6. 音乐
      music:

      • 暂不支持
        音乐文件的命名方式:每首音乐按照唯一数字ID的方式命名(从1.mp3开始,ID不能重名,依次往后增加),用户程序在需要使用的地方调用对应的名称

    7. 资源版本信息

      • version.inf:如 0.1

    8. 使用例程

      • 资源具体使用参考:lv_example_switch_1.c

    9. 使用TFTP下载资源至设备(调试阶段)

      1. 从如下地址下载客户端:
        https://pjo2.github.io/tftpd64/

      2. 开启设备端TFTF Serverq服务:
        在项目名称\apps\tuyaos_iot_t5_gui_demo_product_class-T5_gui_demo_quickstart\src\gui\tuya_app_gui_config.h中打开宏定义"TUYA_TFTP_SERVER"(量产阶段固件务必关闭此宏定义,避免出现安全问题)

      3. 从设备日志端获取TFTF Server ip及端口信息,如下:

        tftp_log.png
      4. windows端打开tftp 客户端工具,按如下配置:

        tftp_tool.png
      5. 目前仅识别GUI相关的如下几种文件格式:

        • 语言配置文件:.json

        • 字体库文件:.ttf

        • 音频文件(暂不支持):.mp3(具体文件名按照4.6所示)

        • 图片文件:.jpg/.png/.gif(上传的文件名按照4.5所示)

        • 资源信息文件(固定名称,不可改变):version.inf

      6. 上传语言配置文件时(语言前缀参考4.1描述),命名规则,必须是:“语言_文件名.json“,如:

        • 上传一个中文配置文件xxx.json时,更改名称为:ch_xxx.json;

        • 上传一个英文配置文件yyy.json时,更改为en_yyy.json;

        • 上传一个韩文配置文件jjj.json时,更改为kr_jjj.json等。

  5. 系统调试

    1. 日志口UART1,波特率为460800

    2. 固件烧录口UART2,波特率2000000

  6. 系统编译
    带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

  7. 屏幕切换
    开发包已支持两种屏幕大小的可选宏定义配置(3.5寸屏幕厂商型号:T35P128CQ,5寸屏幕厂商型号:T50P181CQ),用户可根据手头拿到的开发板进行相应配置(\apps\tuyaos_iot_t5_gui_demo_product_class-T5_gui_demo_quickstart\src\gui\tuya_app_gui_config.h),如下图:

    screen_sw.png
  8. 示例屏幕展示

    screen_show.png
愚者千虑必有一得
Posts: 520

Re: T5平台GUI开发指导

up

Post Reply