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 有了一定的了解。有不懂的欢迎留言,大家一起讨论。

相关内容

热门资讯

安卓系统通知管理,全面解析与优... 你有没有发现,手机里的通知就像是一群调皮的小精灵,时不时地跳出来和你互动?没错,说的就是安卓系统的通...
安卓系统手机哪买,揭秘哪里购买... 你有没有想过,拥有一部安卓系统手机是多么酷的事情呢?想象你可以自由安装各种应用,不受限制地探索各种功...
安卓系统 ipv4,基于安卓系... 你知道吗?在智能手机的世界里,有一个系统可是无人不知、无人不晓,那就是安卓系统。而在这个庞大的安卓家...
目前安卓是什么系统,探索安卓系... 亲爱的读者,你是否曾好奇过,如今安卓系统究竟是什么模样?在这个科技飞速发展的时代,操作系统如同人体的...
安卓6.0系统比5.0,从5.... 你有没有发现,自从手机更新了安卓6.0系统,感觉整个人都清爽了不少呢?没错,今天咱们就来聊聊这个话题...
安卓2.36系统升级,功能革新... 你知道吗?最近安卓系统又来了一次大变身,那就是安卓2.36系统升级!这可不是一个小打小闹的更新,而是...
安卓系统源码怎么打开,并可能需... 你有没有想过,安卓系统的源码就像是一扇神秘的门,隐藏着无数的技术秘密?想要打开这扇门,你得掌握一些小...
安卓8.0系统体验视频,智能革... 你有没有听说安卓8.0系统最近可是火得一塌糊涂啊!作为一个紧跟科技潮流的数码达人,我当然要来给你好好...
宣传系统漫画app安卓,探索安... 亲爱的读者们,你是否曾在某个午后,百无聊赖地打开手机,想要寻找一些轻松愉悦的读物?今天,我要给你介绍...
鸿蒙替换安卓系统吗,开启智能生... 你知道吗?最近科技圈里可是炸开了锅,因为华为的新操作系统鸿蒙系统,据说要大举进军手机市场,替换掉安卓...
手机安卓系统深度清理,解锁手机... 手机里的东西是不是越来越多,感觉就像一个装满了杂物的储物柜?别急,今天就来教你一招——手机安卓系统深...
安卓上的windows系统,融... 你有没有想过,在安卓手机上也能体验到Windows系统的魅力呢?没错,这就是今天我要跟你分享的神奇故...
安卓系统焦点变化事件,Andr... 你知道吗?在安卓系统的世界里,最近发生了一件超级有趣的事情——焦点变化事件。这可不是什么小打小闹,它...
一加系统安卓降级,轻松还原经典... 你有没有想过,你的手机系统升级后,突然发现某些功能变得不那么顺心了?别急,今天就来聊聊一加系统安卓降...
日本最好的安卓系统,体验非凡 亲爱的读者们,你是否曾想过,在遥远的东方,有一个国家,他们的智能手机系统独具特色,让人眼前一亮?没错...
荣耀安卓11 系统证书,保障安... 你知道吗?最近手机圈里可是炸开了锅,荣耀安卓11系统证书成了大家热议的话题。这不,我就迫不及待地来和...
安卓手机开机升级系统,体验流畅... 你有没有发现,每次你的安卓手机开机,总会有那么一刹那,屏幕上跳出一个升级系统的提示?是不是觉得这就像...
真正的安卓系统手机,安卓系统手... 你有没有想过,为什么有些人对安卓系统手机情有独钟?是不是觉得市面上的安卓手机千篇一律,缺乏个性?别急...
安卓怎么用定位系统,轻松实现精... 你有没有想过,手机里的定位系统竟然这么神奇?它不仅能帮你找到回家的路,还能在茫茫人海中找到你的好友。...
安卓的哪个系统流畅,探索新一代... 你有没有想过,为什么你的安卓手机有时候像蜗牛一样慢吞吞的,而别人的手机却像风一样快?今天,就让我带你...