framebuffer设备的参数

本文介绍了如何通过ioctl()系统调用获取Framebuffer设备的相关参数,并展示了如何使用FBIOGET_FSCREENINFO和FBIOGET_VSCREENINFO命令来读取固定和可变屏幕信息。此外,还提供了具体的编程实例,包括打开设备、获取信息及内存映射等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如果应用程序需要知道Framebuffer设备的相关参数,必须通过ioctl()系统调用来完成。

在头文件<linux/fb.h>中定义了所有的ioctl命令字,不过,最常用的ioctl命令字是下面这两个:FBIOGET_FSCREENINFO和FBIOGET_VSCREENINFO。

前者返回与Framebuffer有关的固定的信息,比如图形硬件上实际的帧缓存空间的大小、能否硬件加速等信息。

而后者返回的是与Framebuffer有关的可变信息。

之所以可变,是因为对同样的图形硬件,可以工作在不同的模式下。

简单来讲,一个支持1024x768x24图形模式的硬件通常也能工作在800x600x16的图形模式下。

可变的信息就是指Framebuffer的长度、宽度以及颜色深度等信息。

 

这两个命令字相关的结构体有两个:struct fb_fix_screeninfo和struct fb_var_screeninfo。

这两个结构体都比较大,前者用于保存Framebuffer设备的固定信息,后者用于保存Framebuffer设备的可变信息。

在调用ioctl()的时候,要用到这两个结构体。

应用程序中通常要用到struct fb_var_screeninfo的下面这几个字段:

xres、yres、bits_per_pixel,分别表示x轴的分辨率、y轴的分辨率以及每像素的颜色深度(颜色深度的单位为bit/pixel),其类型定义都是无符号32位整型数。

http://hi.baidu.com/atoe/blog/item/e8da6416912a8a4a20a4e94f.html

http://hi.baidu.com/excellentderek/blog/item/f387e64e24b713cdd0c86a59.html

图形系统开发基础(挺详细)

http://linux.chinaunix.net/bbs/thread-1063136-1-1.html

又一个framebuffer编程的例子。

-------------------------------------
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <string.h>
#include <stdlib.h>

char *fb_addr;
unsigned fb_size;

int print_screen(char *buf,int width,int height);

int main(int argc,char *argv[])
{
int screen_fbd=0;

struct fb_fix_screeninfo fb_fix;
struct fb_var_screeninfo fb_var;

char *env=NULL;

short *picture;

env="/dev/fb0";

screen_fbd=open(env,O_RDWR);

printf("Success opening framebuffer device %s/n",env);

ioctl(screen_fbd,FBIOGET_FSCREENINFO,&fb_fix);

printf("fb_fix.line_length=%d/n",fb_fix.line_length);
printf("fb_fix.accel=%d/n",fb_fix.accel);

ioctl(screen_fbd,FBIOGET_VSCREENINFO,&fb_var);

printf("fb_var.xres=%d/n",fb_var.xres);
printf("fb_var.yres=%d/n",fb_var.yres);

fb_size=fb_var.yres*fb_fix.line_length;

fb_addr=(char *)mmap(NULL,fb_size,PROT_READ|PROT_WRITE,MAP_SHARED,screen_fbd,0);
        /*fb_addr的获取,是很核心的步骤,表示成功获得了framebuffer设备*/

picture=(char *)malloc(fb_var.yres*fb_fix.line_length);
memset(picture,0xFF,fb_var.yres*fb_fix.line_length);
        /*注意,这里对颜色的赋值只是一次赋一半值,也就是一个字节,8bit*/
        /*而事实上,一个像素的颜色值是16bit*/
        /*0xFFFF就是白色*/
        /*介绍一下16bit的颜色的类型,颜色是由RGB组成,如果是565排列,
        则依次为Red Green Blue
                11111 111111 11111
                                       */

print_screen(picture,fb_var.xres,fb_var.yres);

return 0;
}

int print_screen(char *buf,int width,int height)
{
short *t_data=(short *)buf;

short *t_fb_addr=(short *)fb_addr;

int bytew=width<<1; /*像素数乘以2即是字节数,因为颜色深度是2个字节(16bit)*/

while(--height>=0)
{
   memcpy(t_fb_addr,t_data,bytew); /*一行的数据赋值*/
   t_fb_addr += width;
   t_data += width;
}
}

### Framebuffer 设备树配置 在 Linux 中,Framebuffer设备树配置用于描述 LCD 硬件特性以及指定相应的驱动程序。以下是典型的设备树节点配置: ```dts lcd@0 { compatible = "vendor,lcd"; reg = <0>; status = "okay"; display-timings { native-mode = <&timing0>; timing0: timing0 { clock-frequency = <33260700>; hactive = <800>; vactive = <480>; hfront-porch = <40>; hback-porch = <128>; hsync-len = <48>; vfront-porch = <1>; vback-porch = <4>; vsync-len = <4>; hsync-active = <0>; vsync-active = <0>; de-active = <1>; pixelclk-active = <0>; }; }; port { lcd_out: endpoint { remote-endpoint = <&display_in>; }; }; }; ``` 此段代码定义了一个名为 `lcd` 的节点,并设置了其兼容属性、状态以及其他必要的参数,如显示定时器等[^2]。 ### Framebuffer 驱动开发流程 #### 注册平台驱动 为了使 Framebuffer 正常工作,在内核空间需编写对应的驱动模块并完成注册过程。这一般涉及到调用 `platform_driver_register()` 函数来向系统注册一个新的平台驱动实例。 ```c static struct platform_driver my_fb_driver = { .probe = my_probe, .remove = my_remove, .driver = { .name = "my-fb", .of_match_table = of_match_ptr(my_fb_of_match), }, }; module_platform_driver(my_fb_driver); ``` 这段 C 语言代码展示了如何创建一个简单的平台驱动结构体,并将其与特定的匹配表关联起来以便于自动加载。 #### 探测与初始化 当新设备被连接至系统时会触发 probe 方法执行,此时应该进行必要的硬件检测和资源分配操作,比如申请 I/O 地址范围或中断线号等。 ```c static int __init my_probe(struct platform_device *pdev) { struct resource *res; void __iomem *base; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); base = devm_ioremap_resource(&pdev->dev, res); /* Initialize hardware here */ return 0; } ``` 上述代码片段说明了怎样获取设备所占用的内存区域,并映射到虚拟地址空间供后续访问使用。 #### 分配 Framebuffer 内存 对于实际的应用来说,还需要为图形缓冲区预留足够的连续物理页框。这部分可以通过 kmalloc 或者 dma_alloc_coherent 来实现。 ```c struct fb_info *info; int ret; info = framebuffer_alloc(0, &pdev->dev); if (!info) return -ENOMEM; ret = alloc_console_memory(info); // 自定义函数负责具体分配逻辑 if (ret) { framebuffer_release(info); return ret; } /* 设置其他成员变量 */ register_framebuffer(info); ``` 此处展示的是从内核堆栈中请求一块适合做帧缓存使用的内存块,并最终通过 register_framebuffer 将它加入全局链表管理之中[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值