这里是目录
本文使用环境:
电脑:Ubuntu 18.04.5 LTS
开发板:orangepi-zero2
交叉编译器:aarch64-none-linux-gnu-
显示屏:openmv 1.8英寸SPI显示屏
显示屏资料:https://openmv.io/products/lcd-shield (128,为什么会这么贵,搞不清楚,建议淘宝随便买)
写在前面,强烈建议打开log,要不然你都不知道你程序在什么地方出错
凡是涉及到宏的修改,都需要重新编译,make clean,然后再make
一、linux移植
1、参考
这里不再赘述,参考别人的东西。
参考: link
参考: link
二、编译调试
默认参数运行的时候发现会报段错误,使用gdb,定位发现是内存不足导致的。
2.1、打开log并关闭输入设备
2.1.1、关闭输入设备
不要定义以下宏,或者定义为0
#define USE_EVDEV 0 //define by zxx
改宏默认为0,即不用定义
在main函数中注释掉事件输入相关的函数:
2.1.2、打开log
/*Enable the log module*/
#define LV_USE_LOG 1 //by zxx
#if LV_USE_LOG
注意,此时的等级是:WARN,INFO打印的东西太多了没必要。
#define LV_LOG_LEVEL LV_LOG_LEVEL_WARN
2.2、使用gdb
2.2.1、添加编译选项:
2.2.2、gdb调试
–使用:gdb ./app 运行程序
–输入:run
可以看出程序在4的位置停止,从3可以看出程序传入的参数为0x00,即obj没有初始化成功,给NULL赋值导致的段错误。
输入:up
可以看出程序上一次调用的函数,即程序的运行轨迹,
最终查出是mem_alloc申请内存失败了。
进入函数发现是lvgl自定义的函数:
查找对应的宏,改宏为0会使用定义的481024内存,问题就在这里,内存太小了,改大一点X2就行(482*1024)。
这里也可以将该宏LV_MEM_CUSTOM 定义为1,将会使用系统默认的malloc函数,但这样效率可能会低一些,lvgl是有优化算法的
至此程序可以正常运行了,但是还有bug没有处理。
三、LVGL异常分析
程序编译通过,可以运行了。但还是会有警告输出。
3.1、ioctl(FBIOBLANK): Invalid argument
这里报错表示不支持这个参数,貌似也不影响使用,但需要注意的是,不能直接return。需要将return注释掉。为了更好的打印log,我将部分的info改成了warn,以便更好的输出关键log。
3.2、It seems lv_tick_inc() is not called.
这个地方表明lv_tick_inc需要被调用。创建一个1ms的定时器,调用该函数即可。
参考链接: 移植指南
明确要求需要定时器定时调用,至少需要5ms,且优先级要高于handler。
3.3、LVGL触控不准
在使用触控板的时候,出现鼠标和触控点差异很大的情况,左上角都是0,但是越往下差距越大。
如图点击的位置和鼠标差距很大:
如何查看自己触控板的触控范围?接入触控板然后使用
evtest
1:输入命令
2:选择对应的触控id,如果错了退出重新打开
3:ABS_X X的最大坐标
4:ABS_Y Y的最大坐标
发现是因为触控板的分辨率和屏幕的分辨率不一样。屏幕使用的1024X600,但是触控板是2048*2048。问题就出现在这里。
需要单独配置一下。
配置下列文件:
将EVDEV_HOR_MAX和EVDEV_VER_MAX改成最大值即可
可以打印log观察室哪里的问题,找到对应的函数,该函数用于读取设备触控板的返回值进行操作确认。
在如下位置新增打印
#if EVDEV_CALIBRATE
// 使能后用map做映射
data->point.x = map(evdev_root_x, EVDEV_HOR_MIN, EVDEV_HOR_MAX, 0, drv->disp->driver->hor_res);
data->point.y = map(evdev_root_y, EVDEV_VER_MIN, EVDEV_VER_MAX, 0, drv->disp->driver->ver_res);
#else
data->point.x = evdev_root_x;
data->point.y = evdev_root_y;
#endif
// 新增
printf("root_x:%d root_y:%d point.x:%d point.y:%d h:%d v:%d\r\n",evdev_root_x,evdev_root_y,data->point.x,data->point.y,drv->disp->driver->hor_res,drv->disp->driver->ver_res);
运行代码后手指点击屏幕,对应的坐标既有打印。可以看出屏幕最大是1024X600,超过次区域的触控都会有问题,所以需要修改触控横竖的最大值,程序中再使用map做映射。
配置如下:
# define EVDEV_CALIBRATE 1 //by zxx /*Scale and offset the touchscreen coordinates by using maximum and minimum values for each axis*/
# if EVDEV_CALIBRATE
# define EVDEV_HOR_MIN 0 /*to invert axis swap EVDEV_XXX_MIN by EVDEV_XXX_MAX*/
# define EVDEV_HOR_MAX 2048 /*"evtest" Linux tool can help to get the correct calibraion values>*/
# define EVDEV_VER_MIN 0
# define EVDEV_VER_MAX 2048
# endif /*EVDEV_CALIBRATE*/
#endif /*USE_EVDEV*/
匹配后的触控非常丝滑,展示视频:
LVGL触控
四、成功显示
由于屏幕非常非常小,所以显示非常有限
五、优化
注意:
所有涉及.h文件的修改都需要重新编译。
make clean
make
5.1、显示参数
参考链接: link
5.2、字号优化
屏幕很小,因此修改字号为最小:8
/*Always set a default font*/
#define LV_FONT_DEFAULT &lv_font_montserrat_8
/*Montserrat fonts with ASCII range and some symbols using bpp = 4
*https://fonts.google.com/specimen/Montserrat*/
#define LV_FONT_MONTSERRAT_8 1
#define LV_FONT_MONTSERRAT_10 0
#define LV_FONT_MONTSERRAT_12 0
#define LV_FONT_MONTSERRAT_14 0
#define LV_FONT_MONTSERRAT_16 0
#define LV_FONT_MONTSERRAT_18 0
#define LV_FONT_MONTSERRAT_20 0
5.3、显示帧率优化
默认帧率是33fps,如果需要修改可以调整下列宏:
/*Default display refresh period. LVG will redraw changed areas with this period time*/
#define LV_DISP_DEF_REFR_PERIOD 30 /*[ms]*/
fps = 1000ms / 30ms
改成10ms就是100fps