framebuffer之应用层代码

1.什么是framebuffer?
framebuffer帧缓冲(简称fb)是linux内核中虚拟出的一个设备,framebuffer向应用层提供一个统一标准接口的显示设备,从驱动来看,fb是一个典型的字符设备,而且创建了一个类/sys/class/graphics。
2.framebuffer的使用
设备文件 /dev/fb0到fb4,主设备号都是29,次设备号从0-4,
获取设备信息要使用这个头文件 #include <linux/fb.h>.,
使用mmap做映射
3.有两个比较重要的结构体,fb_fix_screeninfo和fb_var_screeninfo,前面的结构体里面的数据是固定的,后面的是可变的。
https://blog.csdn.net/qwaszx523/article/details/72954308 有对结构体的详细说明,下面解释摘抄于链接,有部分修改。
struct fb_var_screeninfo {
//struct fb_info的成员(可变参数),其记录用户可修改的显示控制器的参数,包括分辨率和每个像素点的比特数,其成员需要在驱动程序中初始化和设置。

/********可见解析度(实际屏幕)********/             
__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 */                           /*每像素位数(多少BPP),单位为字节 */
__u32 grayscale; /* != 0 Graylevels instead of colors */  /*非0时指灰度*/ 

/********fb缓存的RGB位域**********/
struct fb_bitfield red;/* bitfield in fb mem if true color, */ /* fb缓存的红色位域*/
struct fb_bitfield green;/* else only length is significant *//* fb缓存的绿色位域*/
struct fb_bitfield blue;                                                    /* fb缓存的蓝色位域*/
struct fb_bitfield transp;/* transparency*/                 /*透明度 =0 */ 

__u32 nonstd;/* != 0 Non standard pixel format *//*非标准像素格式时应该为非0值 (标志像素格式时 nonstd=0) */ 

__u32 activate;/* see FB_ACTIVATE_**/   /*查看宏FB_ACTIVATE_NOW */ 

__u32 height;/* height of picture in mm */ /* 高度*/
__u32 width;/* width of picture in mm*/     /* 宽度 */ 

__u32 accel_flags;/* (OBSOLETE) see fb_info.flags */ /*查看fb_info.flags */ 

/这参数必须通过查看LCD数据手册得到**/
/* Timing: All values in pixclocks, except pixclock (of course) /
__u32 pixclock; /
pixel clock in ps (pico seconds) */ /*像素时钟(皮秒),pixclock=1/Dclk=… */

/* 行切换,从同步到绘图之间的延迟即HFPD(有效数据之后无效的像素的个数) ,对应于LCD数据手册的Hsyn的front-porch*/
HFPD 水平同步信号后肩
__u32 left_margin; /* time from sync to picture */  

/*行切换,从绘图到同步之间的延迟即HBPD(Hsyn脉冲下降沿之后的无效像素的个数) ,对应于LCD数据手册的Hsyn的back-porch*/	
HBPD 水平同步信号前肩				   
__u32 right_margin; /* time from picture to sync */  

/*帧切换,从同步到绘图之间的延迟即VFPD(有效数据之后还要经历的无效行数(之后是下一帧数据)) ,对应于LCD数据手册的Vsyn的front-porch*/			
		  VFPD 垂直同步信号后肩
__u32 upper_margin; /* time from sync to picture */   

/*帧切换,从绘图到同步之间的延迟即VBPD(Vsyn脉冲下降沿之后还要经历的无效行数) ,对应于LCD数据手册的Vsyn的back-porch */
VBPD 垂直同步信号前肩
__u32 lower_margin;  

/*水平同步的长度即HSPW(Hsyn信号的脉冲宽度),对应于LCD数据手册的Hsyn的pulse Width */ 					 
HSPW 水平同步信号脉宽
__u32 hsync_len;  /* length of horizontal sync*/

/*垂直同步的长度即VSPW(Vsyn信号的脉冲宽度),对应于LCD数据手册的Vsyn的pulse Width */
HBPD 水平同步信号前肩
__u32 vsync_len;  /* length of vertical sync*/    

__u32 sync;   /* see FB_SYNC_**/            /* 查看宏FB_SYNC_*/
__u32 vmode;  /* see FB_VMODE_**/         /*  查看宏FB_VMODE_ */
__u32 rotate;  /* angle we rotate counter clockwise */ /*顺时钟旋转的角度 */
__u32 reserved[5]; /* Reserved for future compatibility */  /* */

};

struct fb_fix_screeninfo {
// struct fb_info的成员(固定参数),其记录用户不能修改的显示控制器的参数,如屏幕缓冲区物理地址,
//长度,当对帧缓冲设备进行映射操作时,就是从此结构中取得缓冲区物理地址,其成员需要在驱动程序中初始化和设置

char id[16]; /* identification string eg “TT Builtin” */ /*字符串形式的标识符 */

/* fb缓冲内存的开始地址(物理地址),它一般是作为dma_alloc_writecombine的参数,该函数会将物理地址存放在该变量中*/
unsigned long
smem_start; /* Start of frame buffer mem physical address) /
__u32 smem_len; /
Length of frame buffer mem / / fb缓冲的长度,等于max_xres max_yresmax_bpp/8 */

u32 type; /* see FB_TYPE**/ /* 查看宏 FB_TYPE FB_TYPE_PACKED_PIXELS=0 /
__u32 type_aux; /
Interleave for interleaved Planes*/ /* 分界,=0 /
__u32 visual; /
see FB_VISUAL_**/ /* 查看宏FB_VISUAL_,用于记录屏幕使用的色彩模式,一般是FB_VISUAL_TRUECOLOR(真彩色) /
__u16 xpanstep; /
zero if no hardware panning*/ /* 如果没有硬件 panning,=0 /
__u16 ypanstep; /
zero if no hardware panning*/ /* 如果没有硬件 panning,=0 /
__u16 ywrapstep;/
zero if no hardware ywrap / / 如果没有硬件 panning,=0 /
__u32 line_length;/
length of a line in bytes / / 一行的字节数 */

unsigned long mmio_start; /* Start of Memory Mapped I/O*/ /* 内存映射的I/O的开始位置 /
/
(physical address) */

__u32 mmio_len; /* Length of Memory Mapped I/O / / 内存映射的I/O的长度 /
__u32 accel; /
Indicate to driver which / / = FB_ACCEL_NONE */

  /*  specific chip/card we have */

__u16 reserved[3];/* Reserved for future compatibility / / */
};


测试代码:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/fb.h>
#define PATHNAME “/dev/fb0”

int main(void)
{
int fd = -1;
struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;

fd = open(PATHNAME, O_RDWR);
if (fd < 0)
{
	perror("");
	return -1;
}
ioctl(fd, FBIOGET_VSCREENINFO, &vinfo);
ioctl(fd, FBIOGET_FSCREENINFO, &finfo);
printf("vinfo:\n");
printf("x_res = %d\n y_res = %d\n x_res_vir = %d\n \
	y_res_vir = %d\n bpp = %d\n xoffset = %d\n yoffset = %d\n \ 
	height = %d\n width = %d\n\n", 
	vinfo.xres, vinfo.yres, vinfo.xres_virtual, 
	vinfo.yres_virtual, vinfo.bits_per_pixel,
	vinfo.xoffset, vinfo.yoffset, vinfo.height,vinfo.width);
printf("finfo\n");
printf("id = %s\n smem_len = %d\n smem_start = %x\n", 
	finfo.id, finfo.smem_len, finfo.smem_start);
close(fd);
return 0;

}
得到了如下的信息:
vinfo:
x_res = 1024
y_res = 600
x_res_vir = 1024
y_res_vir = 1200
bpp = 32
xoffset = 0
yoffset = 0
height = 0
width = 0

finfo:
id = s3cfb
smem_len = 4915200
smem_start = 475ab000
从以上信息可以得知:
1.我们屏幕的物理分辨率是1024 x 600, 虚拟屏幕的分辨率是1024 x 1200,虚拟屏幕使用了双缓冲
2.bpp 每一个像素点用32bit = 4byte来表示
3.屏幕映射到内存地址对应的虚拟地址是0x475ab000,长度是4915200个字节,1024 x 1200 x4 = 4915200


mmap函数,来源于:http://blog.chinaunix.net/uid-26126915-id-2983776.html
原型:
void *mmap(void *addr, size_t length, int prot, int flags,
int fd, off_t offset);
addr:指定为文件描述符fd应被映射到的进程空间的起始地址。它通常被指定为一个空指针,这样告诉内核自己去选择起始地址。一般默认为NULL。
length:是映射到调用进程地址空间中的字节数,它从被映射文件开头offset个字节处开始算。
prot:负责保护内存映射区的保护。常用值是代表读写访问的PROT_READ | PROT_WRITE.当然还包括数据的执行(PROT_EXEC)、数据不可访问(PROT_NONE)
flags:flags常用值有MAP_SHARED或MAP_PRIVATE这两个标志必须选一个,并可以选上MAP_FIXED。如果指定了,那么调用进程对被映射数据所做的修改只对该进程可见,而不该变其底层支撑对象。如果指定了,那么调用进程对被映射数据所作的修改对于共享该对象的所有进程都可见,而且确实改变了其底层支撑对象。MAP_SHARED 多个进程都可以操作fb MAP_PRIVATE 单个进程可以操作fb,一般MAP_SHARED
参数fd为映射文件的描述符,offset为文件的起点,默认为0.
代码中使用mmap函数地方:

pfb = mmap(NULL, finfo.smem_len, PROT_READ | PROT_WRITE, 
	MAP_SHARED, fd, 0);
if (!pfb)
{
	perror("");
	return -1;
}

以上内容有部分来源于网络,如有侵权,麻烦联系作者删除,谢谢!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Framebuffer应用是指在Linux系统中使用Framebuffer驱动程序来控制LCD显示设备。Framebuffer是一块内存,保存着一帧图像的每一个像素颜色值。通过设置LCD控制器的时序、信号极性以及分配Framebuffer的大小和位置,可以实现在LCD上显示图像。在应用层,可以使用ioctl函数读取屏幕的参数信息,然后通过mmap映射Framebuffer,在Framebuffer中写入数据来实现图像的显示。Framebuffer应用的好处是可以直接对显存缓冲区进行读写操作,不必关心硬件的物理地址,简化了读写速度和方便性。\[2\]\[3\] #### 引用[.reference_title] - *1* [Framebuffer的配置及应用——先转载留着,以后一定要弄懂](https://blog.csdn.net/weixin_33890499/article/details/85844617)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [【嵌入式Linux】嵌入式Linux应用开发基础知识之Framebuffer应用编程和字符汉字显示](https://blog.csdn.net/weixin_43444989/article/details/122918794)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [19.Frambuffer应用编程](https://blog.csdn.net/qq_42174306/article/details/125589673)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值