电子书编译、测试与总结
一、Makefile文件
CROSSCOMPILE := arm-linux-
CFLAGS := -Wall -O2 -c -g
CFLAGS += -I$(PWD)/include
LDFLAGS := -lm -lfreetype
CC := $(CROSSCOMPILE)gcc
LD := $(CROSSCOMPILE)ld
OBJS := main.o \
display/disp_manager.o \
display/fb.o \
encoding/ascii_encoding.o \
encoding/utf-16be_encoding.o \
encoding/encoding_manager.o \
encoding/utf-8_encoding.o \
encoding/utf-16le_encoding.o \
draw/draw.o \
fonts/ascii_font.o \
fonts/gbk_font.o \
fonts/freetype_font.o \
fonts/fonts_manager.o
all: $(OBJS)
$(CC) $(LDFLAGS) -o show_file $^
clean:
rm -f show_file
rm -f $(OBJS)
%.o:%.c
$(CC) $(CFLAGS) -o $@ $<
备注:编译选项 -g 是调试用的,不用时去掉
二、编译与测试
编译: make
竟然这么顺利?拿到开发板运行下
打脸了,一来就是段错误 : (
注意:core文件默认不会生成(可敲入 ulimit 命令查看,我的显示为0)
为生成core文件方便调试,执行:ulimit -c unlimited
生成了core文件后,我想用gdb远程交叉调试,然后看了一堆文章,终于解决。
1)下载gdb源码:http://ftp.gnu.org/gnu/gdb/
我用的是 version 6.8
2) 解压: tar xjf gdb-6.8a.tar.bz2
3) 配置:进入文件夹gdb-6.8,执行./configure
--target=arm-linux --prefix=/home/book/gdb6.8 --disable-werror
生成Makefile文件。gdb6.8目录是设定的gdb的安装目录。加入
--disable-werror可忽略警告信息,否则会出现编译错误。
4)make
5)make install
然后,在gdb6.8/bin即可看到arm-linux-gdb
---------------------------------------------------------------------
接着,生成arm-linux-gdbserver
进入gdb/gdbserver目录,然后配置-->make-->make install
配置:执行./configure --target=arm-linux
--host=arm-linux --prefix=/home/book/gdb6.8/gdbserver
(注意:gdbserver目录需先创建)
然后mkae 再 make install 即可
最后,把 gdbserver/bin的arm-linux-gdbserver复制到开发板根文件系统的/bin目录下
另外,再把arm-linux-gdb 的所在路径(which arm-linux-gdb)放入环境变量中
在开发板一端,运行如下命令:
arm-linux-gdbserver <虚拟机ip>:<port> show_file
备注:port 可随意设置,>1024即可
在虚拟机一端,运行如下命令
arm-linux-gdb show_file
set sysroot <开发板根文件系统目录> # 这个很关键!
target remote <开发板ip>:<port>
备注:<port> 是 开发板设置的那个端口
注意:gdb调试需要调试信息(符号表),在编译时要加 -g
为啥 set sysroot xxx 很关键呢?如果不加,看下图
这是因为程序是交叉编译出来的,调试时也需要交叉编译工具链的一些库才能找到符号表。
此外,也可把set sysroot /home/book/hardware/first_fs 这条命令放在show_file所在目录下的.gdbinit
文件,前提是事先创建.gdbinit
ok,这样就可以远程调试啦!
说明:上面配置主要参考自以下两篇文章:
http://blog.sina.com.cn/s/blog_627bb2cf0102vfbe.html
https://www.fayewilliams.com/2013/01/31/gdb-unable-to-find-dynamic-linker-breakpoint-function/ (推荐阅读)
https://www.fayewilliams.com/2011/10/05/save-time-with-gdb-init-files/ (推荐阅读)
接下来,用GDB一步一步调试,找到了问题的来源,如下图
应该为 g_ptFontOprHead = ptFontOpr;
好了,发现问题并修改后,再运行测试下,又有一bug : (
修改之后,再运行,看下图把
我是bug之父?好吧,能看到的是,发生重叠现象。
问题还在显示一页那个函数,并且猜测是修正LCD坐标位置位置那里有问题。
终于,运行成功了
但是,有没发现,字母和汉字不在一条线上,再看看下面这张图,很明显啊
看上图,发现遇到某个字符,如果ASCII不支持,则自动换成FreeType,因此,这也是为啥一种编码支持多种字体了。
接着,继续解决上面那个“字母飘了”的问题。
突发一想,如果显示大小改变会如何?
执行命令./show_file -f MSYH.TTF -s 20 utf8.txt
一脸懵逼啊,没有设置时,默认字体大小为16,这里修改为20后,竟然显示正常了!
通过打印每个像素点的位置,发现所谓的“字母飘了”,其实是8x16点阵显示数字/字母偏上而已!
这并不是个bug,只能说是点阵问题。
好了,电子书的编译测试到此结束。
电子书源码我会继续放在我的代码集合那篇博客里面。
二、总结
这个电子书项目讲完了,后面肯定会完善这个项目。
这里总结下这个项目值得学习的地方或技巧。
1> 分层分离思想
从LCD裸板编程就开始提到,分层分离的思想在内核中大量使用,如输入子系统,platform总线等
要掌握这种面向对象的编程方式,以实现程序模块化。
2> 编程习惯
命名变量名要有“顾名思义”的效果。此外,注释要规范,如函数注释、文件注释、全局变量注释等
此外,代码要整齐,方便阅读/查错。
3> 双链表
对于电子书用到双链表,不仅要掌握最基本的链表操作(CURD). 还要意识到,学习数据结构与算法的重要性!
或许,这个电子书项目可以用其它数据结构和算法优化,我想到了用“数组链表”,后面有时间我一定尝试
写出来。敬请期待 :)
4> 解决bug技巧
一个一个解决。这看似没啥技巧。实际bug很多是关联的,解决前面一个,可能后面的全部解决了。
因此,对于error,可以一个解决后重编译,如此循环解决。
此外,还要掌握如何搜索需包含的头文件、如何编译第三方库或交叉编译第三方库
5> 定位bug
出来打印定位问题后,还可以远程交叉调试 或 本地调试。GDB 用好了,绝对省时省力。
对于这个电子书,我觉得难点有两个:
1)位图的笛卡尔坐标与LCD坐标转换。(当然理解了并不难)
2)显示一页(关键不能超出边界) 以及 页的切换
OK,这个总结到此为止,这只是最基本的电子书,精彩的地方还在后面。完善电子书!