一、关于交叉编译环境
1、还记得第一节,配置的交叉编译环境吗,u-boot和内核都是通过它编译的,且都可以正常运行。但是当博主使用其编译应用程序的时候,发现执行程序无法在设备上运行。
2、查阅多方面的资料,发现交叉编译环境确实是在x86架构上编译生成arm架构的程序,但是arm同样有多种架构和指令集,博主使用的交叉编译环境默认生成v7指令集的可执行文件,f1c200s是arm926ej-s架构,armv5t指令集,所以每次运行都会失败。
3、于是博主添加了-mcup=arm926ej-s参数,用来指定架构。编译成功后,使用arm-linux-readelf -h (可执行文件名)查看生成的文件,架构依然是v7 。又经过一番查阅,是因为工具链所附加的库,是面向Cortex A7的,所以虽然代码编译后是arm926ej-s架构,但是连接后就变成了A7。
4、最终,博主使用了buildroot的工具链。buildroot在生成文件系统的同时,也会生成相应的交叉编译环境,只需要在~/.bashrc内添加环境变量即可。
export PATH=$PATH:/usr/local/f1c200s/buildroot/buildroot-2018.02.1/output/host/usr/bin
多个环境变量也可以用“:”进行隔开。然后执行source ~/.bashrc就完成了。
二、源码准备
1、首先创建相关的文件夹。
#进入f1c200s的文件夹
cd /usr/local/f1c200s/
#创建名称为lvgl的文件夹
mkdir lvgl
#修改lvgl的权限
chmod 777 lvgl
2、然后进入文件夹,下载指定的代码
#进入lvgl文件夹
cd lvgl
#下载lvgl源码
git clone https://github.com/lvgl/lvgl
#下载lvgl的驱动代码
git clone https://github.com/lvgl/lv_drivers
#下载lvgl在linux端运行的框架
git clone https://github.com/lvgl/lv_port_linux_frame_buffer
3、将lvgl源码和驱动代码,复制到lv_port_linux_frame_buffer内。
#将lvgl源码复制到框架内
cp -r lvgl/* lv_port_linux_frame_buffer/lvgl/
#将lvgl驱动代码复制到框架内
cp -r lv_drivers/* lv_port_linux_frame_buffer/lv_drivers/
#进入目标目录
cd lv_port_linux_frame_buffer
三、源码配置
1、因为博主的硬件目前还没有支持触摸,所以需要把lvgl的输入功能关掉,而对于lvgl的其他配置,则只需要很小的修改。首先配置lv_drv_conf.h文件
#使用命令查看对应配置项的位置
grep -n USE_EVDEV lv_drv_conf.h
在弹出的数据中可以看到,关于输入设备USE_EVDEV的宏定义是在第442行,且是打开状态。
打开文件lv_drv_conf.h,把442行的宏定义改为0,然后保存并且退出。
2、打开main.c文件,把32、33行的disp_drv.hor_res和disp_drv.ver_res改为自己屏幕的参数。
然后把36~50行关于输入设备的函数屏蔽掉。
最后保存退出,main.c就修改完成了。
3、打开Makefile文件,首先把第四行的gcc改为arm-buildroot-linux-uclibcgnueabi-gcc,用来指定make使用的gcc编译器。
然后在第七行的变量CFLAGS上添加参数-std=c99和-mcpu=arm926ej-s,其中变量CFLAGS是编译器选项,参数-std=c99,是指定编译器使用c99标准进行编译,参数-mcpu=arm926ej-s是指定编译器的输出文件架构和指令集。
再在变量LDFLAGS上添加参数-lrt,且需要把参数-lrt放置在变量最后面。其中l和rt需要分开理解,l的意思是连接某个库,rt是指rt库,链接器会查找名为 librt.a
或 librt.so
(对于共享库)的库并将它们与输出文件链接。
接下来可以保存退出,然后执行make,正常情况下会有多个报错是关于CFLAGS的,这是因为gcc不支持这些参数,只需要逐个将其中的参数删除掉,就可以正常编译通过了。也可以使用博主修改好的。
CFLAGS ?= -O3 -g0 -I$(LVGL_DIR)/ -Wall -std=c99 -mcpu=arm926ej-s -Wshadow -Wundef -Wmissing-prototypes -Wall -Wextra -Wno-unused-function -Wno-error=strict-prototypes -Wpointer-arith -fno-strict-aliasing -Wuninitialized -Wno-unused-parameter -Wno-missing-field-initializers -Wtype-limits -Wno-format-nonliteral -Wno-cast-qual -Wunreachable-code -Wno-switch-default -Wreturn-type -Wmultichar -Wformat-security -Wno-ignored-qualifiers -Wno-sign-compare -Wno-error=missing-prototypes -Wclobbered -Wdeprecated -Wempty-body -Wtype-limits -Wno-unused-value -Wno-unused-parameter -Wno-missing-field-initializers -Wuninitialized -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wtype-limits -Wno-format-nonliteral -Wpointer-arith -Wno-cast-qual -Wmissing-prototypes -Wunreachable-code -Wno-switch-default -Wreturn-type -Wmultichar -Wformat-security -Wno-ignored-qualifiers -Wno-sign-compare
最后,保存退出,并且执行make,就可以正常生成输出文件demo了。
4、最后使用命令arm-buildroot-linux-uclibcgnueabi-readelf -h demo查看输出文件,可以看到系统架构一栏是arm。
四、自启动
1、将可执行文件demo复制到tf卡的roots分区(也就是文件系统分区)内的文件夹/usr/soft内。没有soft的时候可以自行创建一个。将tf卡插回设备,上电,进入/usr/soft,执行./demo,就可以看到设备成功显示lvgl的界面啦。
2、/etc/init.d/中包含许多系统服务的启动和停止脚本,如果想要demo程序可以开机自行启动,我们可以在/etc/init.d/中添加一个启动demo的脚本。其中S代表启动脚本,所以
#首先是在设备端,进入指定目录
cd /etc/init.d
#然后是创建一个脚本
vi S10userstart
#打开文件以后,按i件进入编辑状态,添加两行代码
#!/bin/sh
nohup ./usr/soft/demo &
#按Esc键退出编辑模式,然后输入:进入命令状态,并填写命令qw,保存退出。
其中#!/bin/sh是指定shell来解释命令,nohup 命令是让程序一直运行下去,即使终端断开也会一直运行,而命令&是让程序后台运行,而不会占用终端。所以两个一起使用就会让程序挂在后台运行。可以使用ps命令查看,也可以使用kill杀死此程序。
3、最后,关闭设备并且重新上电,就会发现demo程序已经自动启动了,而且终端也正常打开,可以正常使用。
In file included from /home/feng/lvgl/lv_port_linux_frame_buffer/lv_drivers/display/fbdev.c:9:0:
/home/feng/lvgl/lv_port_linux_frame_buffer/lv_drivers/display/fbdev.h:45:18: 错误:未知的类型名‘lv_disp_drv_t’
void fbdev_flush(lv_disp_drv_t drv, const lv_area_t area, lv_color_t color_p);
^
~~~~/home/feng/lvgl/lv_port_linux_frame_buffer/lv_drivers/display/fbdev.c:175:18: 错误:未知的类型名‘lv_disp_drv_t’
void fbdev_flush(lv_disp_drv_t drv, const lv_area_t area, lv_color_t color_p)
^
~~~~Makefile:37: recipe for target ‘/home/feng/lvgl/lv_port_linux_frame_buffer/lv_drivers/display/fbdev.o’ failed
make: *** [/home/feng/lvgl/lv_port_linux_frame_buffer/lv_drivers/display/fbdev.o] Error 1
为什么按照步骤来会出现这些错误?也有很多警告
注意三、3位置,是CC = arm-buildroot-linux-uclibcgnueabi-gcc,没有问号。