本帖最后由 lovzx 于 2023-11-23 20:03 编辑
本帖最后由 lovzx 于 2023-11-23 17:29 编辑
不得不说这次更新后markdown编辑器好用太多了nice
情景再现
在写WIFI配网程序的时候想测试文本太长滑动功能,刷完固件后测试滑动没反应,于是就找是哪里出了问题
解决思路及DEBUG路程
lvgl_conf.h
- 显示UI用的是LVGL框架,所以首先要去lvgl_conf.h文件查找相关的配置,搜索touch关键字大致看了下没有相关的配置及注释
main.c中初始化lvgl代码
继续看main.c里面初始化lvgl的代码如下
lv_log_register_print_cb(lvgl_log_print_cb);
lv_init();
lv_port_disp_init();
lv_port_indev_init();
见名知意第一行是注册lvgl打印日志函数的,第二行是用来初始化的,第三行就是初始化disp显示屏的,点进去也可以看到Initialize your display的注释,看来确实没毛病,继续看第四行看不懂中间的indev是啥没关系,先进去再说,代码如下
void lv_port_indev_init(void)
{
/* Here you will find example implementation of input devices supported by LittelvGL:
* - Touchpad
* - Mouse (with cursor support)
* - Keypad (supports GUI usage only with key)
* - Encoder (supports GUI usage only with: left, right, push)
* - Button (external buttons to press points on the screen)
*
* The `..._read()` function are only examples.
* You should shape them according to your hardware
*/
static lv_indev_drv_t indev_drv;
#ifndef ENCODER_ENABLE
/*------------------
* Touchpad
* -----------------*/
/*Initialize your touchpad if you have*/
touchpad_init();
/*Register a touchpad input device*/
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = touchpad_read;
indev_touchpad = lv_indev_drv_register(&indev_drv);
#endif
可以看到注释写很清楚查找input device 也就是indev缩写的由来,支持的设备有触摸屏,键鼠等, 第21行就是初始化触摸屏的代码,这次终于找对地方了,继续跟代码
touch.c/touch_init初始化触摸屏
上一步找到21行代码直接调用了touch.c里面的touch_init函数,touch_init里面通过_TOUCHFUNCDEFINE 宏定义调用了 chsc6540_i2c_init (tips:鼠标放在宏定义上VSCODE会显示宏展开的代码)
touch.h里面的宏定义如下
#elif defined TOUCH_I2C_CHSC6540
#include "CHSC6540_i2c.h"
#define TOUCH_INTERFACE_TYPE TOUCH_INTERFACE_I2C
#define TOUCH_MAX_POINT TLSC6X_MAX_TOUCH_POINT
#define _TOUCH_FUNC_DEFINE(_func, ...) chsc6540_i2c_##_func(__VA_ARGS__) //宏展开是chsc6540_i2c_init函数
我手里的设备是小安派S1,通过屏幕下面的芯片丝印可以看出来驱动芯片是CHSC6540,看到是定义了TOUCH_I2C_CHSC6540才会生效,搜索关键字发现项目中缺少touch_conf_user.h文件,复制后重新编译反发现还是无法触摸,于是就在想是不是哪里有include到 touch_conf_user.h文件呢,继续向上看touch.h中有无相关定义,在touch.h第28行include了touch_conf.h,打开touch_conf.h发现果然是在里面include了 touch_conf_user.h 其代码如下
#if __has_include("touch_conf_user.h")
/* User external configuration, User need to use this file as a template */
#include "touch_conf_user.h"
如果有touch_conf_user.h的话就会include进来,而touch_conf_user.h中定义了有#define TOUCH_I2C_CHSC6540,根据上面的分析就会touch_init就会调用到chsc6540_i2c_init函数去初始化触摸屏驱动
最后发现问题
上面分析的按照正常逻辑项目中只要有touch_conf_user.h文件就会去初始化触摸屏驱动,再次重启后观察串口log发现并没有执行到chsc6540_i2c_init没有ft6x36 i2c init这句log,于是就开始怀疑TOUCH_I2C_CHSC6540根本就没有被定义,也就是touch.c编译的时候根本就没有找到touch_conf_user.h文件,于是就查看了CMakeLists.txt文件中,找到了sdk_add_include_directories(.)设置include当前项目根目录的也就是touch_conf_user.h所在的目录,但是看到它是在target_sources语句下面的,直觉告诉我就是这里的顺序出了问题编译的时候还没有设置根目录为include目录,当然就找不到touch_conf_user.h文件,解决办法就是把sdk_add_include_directories(.)放在target_sources前面就好了
总结
这个bug是手误抄都没抄明白手残导致的,之前一直有看相关教程,一般也是看看demo,第一次新建一个项目开始编译要注意的地方确实有不少,共同进步,希望安信可社区越来越好!
最后CMakeLists.txt相关代码
如果触摸屏无效的话,可以参考这个思路确认是不是代码配置问题
sdk_add_include_directories(.)
target_sources(app PRIVATE ${source})