最近发现一个不错的 GUI 库:lvgl,它是支持 Linux Framebuffer 的,下次找机会学习一下并分享给大家,一方面可以看下开源软件是如何进行 Framebuffer 应用编程的,另一方面也学习一下 GUI 库的内部实现,或许以后项目里还能用得上,今天先把 Framebuffer 编程复习一下吧。
Linux项目实战视频更新一节《Framebuffer应用编程》,免费观看。B站,网盘,百问网均已同步更新,本文是视频配套的文档。
一、LCD操作原理
在Linux系统中通过Framebuffer驱动程序来控制LCD。Frame是帧的意思,buffer是缓冲的意思,这意味着 Framebuffer就是一块内存,里面保存着一帧图像。
Framebuffer中保存着一帧图像的每一个像素颜色值,假设LCD的分辨率是1024x768,每一个像素的颜色用32位来表示,那么Framebuffer的大小就是:1024x768x32/8=3145728字节。
LCD的操作原理:
① 驱动程序设置好LCD控制器:根据LCD的参数设置LCD控制器的时序、信号极性;根据LCD分辨率、BPP分配Framebuffer。② APP使用ioctl获得LCD分辨率、BPP③ APP通过mmap映射Framebuffer,在Framebuffer中写入数据
假设需要设置LCD中坐标(x,y)处像素的颜色,首要要找到这个像素对应的内存,然后根据它的BPP值设置颜色。
假设fb_base是APP执行mmap后得到的Framebuffer地址:

可以用以下公式算出(x,y)坐标处像素对应的Framebuffer地址:
(x,y)像素起始地址 = fb_base+(xres*bpp/8)y + xbpp/8
最后一个要解决的问题就是像素的颜色怎么表示?它是用RGB三原色(红、绿、蓝)来表示的,在不同的BPP格式中,用不同的位来分别表示R、G、B:

对于32BPP,一般只设置其中的低24位,高8位表示透明度,一般的LCD都不支持。
对于24BPP,硬件上为了方便处理,在Framebuffer中也是用32位来表示,效果跟32BPP是一样的。
对于16BPP,常用的是RGB565;很少的场合会用到RGB555,这可以通过ioctl读取驱动程序中的RGB位偏移来确定使用哪一种格式。
二、相关 API
1. open 函数
在Ubuntu中执行“man 2 open”,可以看到open函数的说明:
头文件:
#include #include #include
函数原型:int open(const char *pathname, int flags);int open(const char *pathname, int flags, mode_t mode);
函数说明:
① pathname 表示打开文件的路径;② Flags表示打开文件的方式,常用的有以下6种, a. O_RDWR表示可读可写方式打开; b. O_RDONLY表示只读方式打开; c. O_WRONLY表示只写方式打开; d. O_APPEND 表示如果这个文件中本来是有内容的,则新写入的内容会接续到原来内容的后面; e. O_TRUNC表示如果这个文件中本来是有内容的,则原来的内容会被丢弃,截断; f. O_CREAT表示当前打开文件不存在,我们创建它并打开它,通常与O_EXCL结合使用,当没有文件时创建文件,有这个文件时会报错提醒我们;③ Mode表示创建文件的权限,只有在flags中使用了O_CREAT时才有效,否则忽略。④ 返回值:打开成功返回