lcd_framebuffer使用

framebuffer其实主要针对LCD屏幕,

对于驱动,一般开发板厂商会做好,如果没有做好,那么就需要编写对应的framebuffer驱动,参考:

  • Linux内核自带的framebuffer驱动
  • Linux中的绑定文档
  • 百度

对于应用编程,主要有几步:

  • 找到LCD屏幕对应的设备结点,一般是/dev/fb0;
  • 获取LCD的参数,主要是LCD的可变参数
  • 用mmap映射LCD的显存,后面就可以直接操作这块区域了
  • 操作LCD也是一样的,最基础的就是画一个像素,后面的操作都是基于这个API的。
//获得LCD文件句柄
fd_fb = open("/dev/fb0", O_RDWR);
//获得LCD可变参数(包含分辨率等信息,这些是驱动中设定的)
ioctl(fd_fb, FBIOGET_VSCREENINFO, &var);
line_width  = var.xres * var.bits_per_pixel / 8;
pixel_width = var.bits_per_pixel / 8;
screen_size = var.xres * var.yres * var.bits_per_pixel / 8;
//mmap映射
fb_base = (unsigned char *)mmap(NULL , screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0);
//将LCD屏幕设为白色(每个点都是0xff,即0xffffff)
memset(fb_base, 0xff, screen_size);
//设置某点为红色
lcd_put_pixel(var.xres/2+i, var.yres/2, 0xFF0000);
//取消映射
munmap(fb_base , screen_size);
//关闭LCD文件
close(fd_fb);

嵌入式Linux应用变成之操作屏幕就是这么简单,下面来说一下其它方面的知识。

字符编码字体类型之间的关系。

  • 首先明白,最终都是一个一个像素的设置
  • 所以在屏幕上显示一个字符时,先获得其点阵,然后再一个一个像素的设置。

字符编码:比如有ASCII、GB2312、UTF-8等。字符编码就是用不同的数字表示一个字符,比如对于ASCII来说,字符0就是48,即0x30;而对于其它编码来说就不一定了。

字体类型:比如有新宋体、黑体、隶书等。它们其实就是具体的点阵不同(外观不同)。

所以应用编程时是这样的,比如要在LCD屏幕上显示一个“我”字,那么先确定编码方式,得到其编码值,再从字体类型文件中找到其点阵,最后显示到LCD屏幕上去即可。

还有一个问题就是对于LCD屏幕来说,一个像素点颜色的格式,比如RGB888、RGB565,所以在画一个像素时需要转换。我就不关心这些了,网上应该有api。

例子

lcd_put_ascii(var.xres/2, var.yres/2, 'A');
unsigned char str[] = "中";
lcd_put_chinese(var.xres/2 + 8,  var.yres/2, str);
//从上面可以看出,显示字符和汉字时对于接口来说没有什么不同

//技巧
//对于中文字符库,我们可以把文件直接映射到内存,这样读取时都很块

freetype的使用

它是一个开源的字体引擎,用于渲染文字。分为以下几大步:

  1. 初始化FreeType Library;

    声明一个Library对象,我感觉它里面应该包含了一些api,后面加载具体字体时会使用到其中的api来进行配置。

  2. 初始化和载入Font Face;

    读入字体文件,通过Library对象来对FontFace进行一些基本配置。

  3. 设置字符大小;

  4. 渲染字符,得到相应的bitmap;

  5. 拷贝并排版文字。

wchar_t *chinese_str = L"繁";
FT_Library	  library;
FT_Face 	  face;
FT_Vector     pen;
FT_GlyphSlot  slot;
int font_size = 24;

error = FT_Init_FreeType( &library );
//argv[1]是具体的字体文件,比如新宋体
error = FT_New_Face( library, argv[1], 0, &face );
slot = face->glyph;
FT_Set_Pixel_Sizes(face, font_size, 0);
//获得位图,保存在face->glyph.bitmap中
error = FT_Load_Char(
    face, 
    chinese_str[0],
    FT_LOAD_RENDER );
//向LCD输出
draw_bitmap( &slot->bitmap,
                 var.xres/2,
                 var.yres/2);

freetype传入一串字符串后,固定其第一个字符原点后,后面的字符的位置也就固定了,可以通过结构体中各成员获得,具体就不说了。直接使用api。

此文件下的show_line.c就是使用freetype在某个位置显示一行文字的例程。

  • 打开LCD设备结点,即/dev/fb0
  • 通过ioctl获得LCD的可变参数(如分辨率)
  • 映射LCD显存
  • 定义一个Library、Face、pen、slot
  • 初始化Library、加载字体
  • 配置,渲染并获得位图
  • 更新LCD显存
赞赏