Linux 应用基础 Framebuffer应用编程
创始人
2024-04-25 13:55:11
0

文章目录

  • 前言
  • 一、了解Framebuffer
  • 二、了解LCD
    • 1.LCD的操作原理
    • 2.LCD坐标
  • 三. Framebuffer 程序分析
    • 1. 打开设备:(open)
    • 2. 获取LCD参数 : ( ioctl )
    • 3. 映射 framebuffer: ( mmap )
  • 四. 描点函数: ( lcd_put_pixel )
  • 总结


前言

在 Linux应用基础中,Framebuffer 驱动程序主要用来控制 LCD。今天带大家来了解一下如何通过 Framebuffer 来编程 LCD。
在此之前,我们要先了解一下 Framebuffer 和 LCD。


一、了解Framebuffer

Frame是帧的意思,buffer是缓冲的意思,这意味着 Framebuffer 就是一块内存,里面保存着一帧图像。Framebuffer 中保存着一帧图像的每一个像素颜色值,假设LCD的分辨率是1024x768,每一个像素的颜色用32位来表示,那么Framebuffer的大小就是:1024x768x32/8=3145728字节。

二、了解LCD

1.LCD的操作原理

① 根据LCD分辨率、BPP分配Framebuffer
② APP使用ioctl获得LCD分辨率、BPP
③ APP通过mmap映射Framebuffer,在Framebuffer中写入数据

2.LCD坐标

在这里插入图片描述
假设 fb_base 是APP执行 mmap 后得到的Framebuffer地址,可以用以下公式算出(x,y)坐标处像素对应的Framebuffer地址:
(x,y)像素起始地址=fb_base + (xres*bpp/8) * y + x * bpp / 8

三. Framebuffer 程序分析

1. 打开设备:(open)

open (const char pathname, int flags) ;
pathname: 表示打开文件的路径。

73      fd_fb = open("/dev/fb0", O_RDWR);
74      if (fd_fb < 0)
75      {
76              printf("can't open /dev/fb0\n");
77              return -1;
78      }

fd_fb: 打开 LCD 设备返回的文件句柄。
/dev/fb0 :LCD的设备节点。
Flags表示打开文件的方式。

2. 获取LCD参数 : ( ioctl )

ioctl ( int fd, unsigned long request, …);
fd : 文件句柄。

12 static struct fb_var_screeninfo var; /* Current var */
……
79      if (ioctl(fd_fb, FBIOGET_VSCREENINFO, &var))
80      {
81              printf("can't get var\n");
82              return -1;
83      }

FBIOGET_VSCREENINFO : 它表示get var screen info,获得屏幕的可变信息.
获取 lcd 屏幕的信息,并将其存放在 var 结构体中。以下是 var 结构体:

struct fb_var_screeninfo {__u32 xres;			/* visible resolution		*/__u32 yres;__u32 xres_virtual;		/* virtual resolution		*/__u32 yres_virtual;__u32 xoffset;			/* offset from virtual to visible */__u32 yoffset;			/* resolution			*/__u32 bits_per_pixel;		/* guess what			*/__u32 grayscale;		/* 0 = color, 1 = grayscale,	*//* >1 = FOURCC			*/struct fb_bitfield red;		/* bitfield in fb mem if true color, */struct fb_bitfield green;	/* else only length is significant */struct fb_bitfield blue;struct fb_bitfield transp;	/* transparency			*/	__u32 nonstd;			/* != 0 Non standard pixel format */__u32 activate;			/* see FB_ACTIVATE_*		*/__u32 height;			/* height of picture in mm    */__u32 width;			/* width of picture in mm     */__u32 accel_flags;		/* (OBSOLETE) see fb_info.flags *//* Timing: All values in pixclocks, except pixclock (of course) */__u32 pixclock;			/* pixel clock in ps (pico seconds) */__u32 left_margin;		/* time from sync to picture	*/__u32 right_margin;		/* time from picture to sync	*/__u32 upper_margin;		/* time from sync to picture	*/__u32 lower_margin;__u32 hsync_len;		/* length of horizontal sync	*/__u32 vsync_len;		/* length of vertical sync	*/__u32 sync;			/* see FB_SYNC_*		*/__u32 vmode;			/* see FB_VMODE_*		*/__u32 rotate;			/* angle we rotate counter clockwise */__u32 colorspace;		/* colorspace for FOURCC-based modes */__u32 reserved[4];		/* Reserved for future compatibility */
};

3. 映射 framebuffer: ( mmap )

void *mmap ( void *addr, size_t length, int prot, int flags, int fd, off_t offset);

要映射一块内存,需要知道它的地址──这由驱动程序来设置,需要知道它的大小──这由应用程序决定。

85      line_width  = var.xres * var.bits_per_pixel / 8;
86      pixel_width = var.bits_per_pixel / 8;
87      screen_size = var.xres * var.yres * var.bits_per_pixel / 8;
88      fb_base = (unsigned char *)mmap(NULL , screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0);
89      if (fb_base == (unsigned char *)-1)
90      {
91              printf("can't mmap\n");
92              return -1;
93      }

screen_size : 代表整个 framebuffer 的大小。
fb_base : framebuffer 是存在于驱动程序中的,在应用程序中无法使用。则需要使用 mmap 将驱动程序的内存映射到应用程序中。


四. 描点函数: ( lcd_put_pixel )

大家在 lcd 上显示字符时,需要进行描点。pen_8,pen_16,pen_32都是起笔点。(我使用的 lcd 像素是 8 位的,就需计算)

void lcd_put_pixel(int x, int y, unsigned int color)
{unsigned char *pen_8 = fb_base+y*line_width+x*pixel_width;unsigned short *pen_16;	unsigned int *pen_32;	unsigned int red, green, blue;	pen_16 = (unsigned short *)pen_8;pen_32 = (unsigned int *)pen_8;switch (var.bits_per_pixel){case 8:{*pen_8 = color;break;}case 16:{/* 565 */red   = (color >> 16) & 0xff;green = (color >> 8) & 0xff;blue  = (color >> 0) & 0xff;color = ((red >> 3) << 11) | ((green >> 2) << 5) | (blue >> 3);*pen_16 = color;break;}case 32:{*pen_32 = color;break;}default:{printf("can't surport %dbpp\n", var.bits_per_pixel);break;}}
}

总结

到此我们对 framebuffer 有了一定的了解。有不懂的欢迎留言,大家一起讨论。

相关内容

热门资讯

安卓系统焦点变化事件,Andr... 你知道吗?在安卓系统的世界里,最近发生了一件超级有趣的事情——焦点变化事件。这可不是什么小打小闹,它...
一加系统安卓降级,轻松还原经典... 你有没有想过,你的手机系统升级后,突然发现某些功能变得不那么顺心了?别急,今天就来聊聊一加系统安卓降...
日本最好的安卓系统,体验非凡 亲爱的读者们,你是否曾想过,在遥远的东方,有一个国家,他们的智能手机系统独具特色,让人眼前一亮?没错...
荣耀安卓11 系统证书,保障安... 你知道吗?最近手机圈里可是炸开了锅,荣耀安卓11系统证书成了大家热议的话题。这不,我就迫不及待地来和...
安卓手机开机升级系统,体验流畅... 你有没有发现,每次你的安卓手机开机,总会有那么一刹那,屏幕上跳出一个升级系统的提示?是不是觉得这就像...
真正的安卓系统手机,安卓系统手... 你有没有想过,为什么有些人对安卓系统手机情有独钟?是不是觉得市面上的安卓手机千篇一律,缺乏个性?别急...
安卓怎么用定位系统,轻松实现精... 你有没有想过,手机里的定位系统竟然这么神奇?它不仅能帮你找到回家的路,还能在茫茫人海中找到你的好友。...
安卓的哪个系统流畅,探索新一代... 你有没有想过,为什么你的安卓手机有时候像蜗牛一样慢吞吞的,而别人的手机却像风一样快?今天,就让我带你...
安卓系统解锁工具下载,畅享自由 你是不是也和我一样,对安卓系统的解锁工具感兴趣呢?想象你的手机被锁住了,无论是忘记密码还是想尝试新的...
谷歌退出安卓系统停用,停用背后... 你知道吗?最近有个大新闻在科技圈里炸开了锅!谷歌竟然宣布要退出安卓系统,这可真是让人大跌眼镜啊!想象...
安卓系统卡顿修复,轻松提升手机... 手机用久了是不是感觉有点卡卡的呢?别急,今天就来给你支几招,让你的安卓手机重焕生机,告别卡顿的烦恼!...
安卓系统停用怎么解除,轻松恢复... 你是不是也遇到了安卓系统停用的问题,急得像热锅上的蚂蚁?别急,今天就来给你详细解析怎么解除这个让人头...
最初始的安卓系统,技术演进与产... 亲爱的读者,你是否曾好奇过,那个如今无处不在的安卓系统,它的诞生之初是怎样的呢?今天,就让我们一起穿...
patchwall系统和安卓系... 你有没有发现,手机上的界面越来越个性化了?没错,这就是科技的魅力所在。今天,咱们就来聊聊两个在个性化...
汽车安卓系统换主题,焕新视觉体... 你有没有发现,汽车里的安卓系统换主题,简直就像给爱车换了个新衣裳,瞬间感觉焕然一新呢!想象当你驾驶着...
掌柜智囊收银系统安卓,高效便捷... 你有没有想过,在繁忙的店铺里,如何让收银工作既高效又轻松呢?今天,就让我带你一探究竟,看看这款掌柜智...
怎么控制安卓系统内存,安卓系统... 手机用久了是不是感觉越来越卡?别急,今天就来教你怎么控制安卓系统的内存,让你的手机重新焕发活力!一、...
电视机系统安卓系统吗,探索智能... 亲爱的读者,你是不是也和我一样,对家里的电视机系统充满了好奇?尤其是当它运行的是安卓系统时,那种探索...
魅族系统flyme安卓,魅族安... 你有没有发现,手机的世界里,总有一些品牌能让人眼前一亮?今天,咱们就来聊聊魅族旗下的Flyme系统,...
安卓仿ios系统链接,带你领略... 你有没有发现,最近安卓手机界掀起了一股仿iOS系统链接的热潮?这可不是什么小打小闹,而是各大厂商纷纷...