linux framebuffer设备驱动

本文深入探讨Linux系统的framebuffer设备驱动,包括framebuffer结构体的fb_info、fb_var_screeninfo和fb_fix_screeninfo,以及系统初始化过程。详细介绍了字符设备的fb_fops操作函数集,如何分配和注册framebuffer,以及应用层的测试实例和截图、显示图片的方法。
摘要由CSDN通过智能技术生成

一. framebuffer结构体

     1. fb_info

struct fb_info {
	int node;		//次设备号
	int flags;
	struct mutex lock;		
	struct mutex mm_lock;
	struct fb_var_screeninfo var;	//可变参数
	struct fb_fix_screeninfo fix;	//不可变参数
	struct fb_monspecs monspecs;
	struct work_struct queue;
	struct fb_pixmap pixmap;
	struct fb_pixmap sprite;
	struct fb_cmap cmap;
	struct list_head modelist;
	struct fb_videomode *mode;		//显示模式
#ifdef CONFIG_FB_BACKLIGHT
	struct backlight_device *bl_dev;//背光设备
	struct mutex bl_curve_mutex;	
	u8 bl_curve[FB_BACKLIGHT_LEVELS]; //背光级别
#endif
#ifdef CONFIG_FB_DEFERRED_IO
	struct delayed_work deferred_work;
	struct fb_deferred_io *fbdefio;
#endif
	struct fb_ops *fbops;	//fb操作函数集
	struct device *device;	//设备文件
	struct device *dev;	//设备文件
	int class_flag;
#ifdef CONFIG_FB_TILEBLITTING
	struct fb_tile_ops *tileops;
#endif
	char __iomem *screen_base;	//虚拟基地址
	unsigned long screen_size; 	//虚拟显存大小
	void *pseudo_palette;	//调色板 一般设置为PALETTE_BUFF_CLEAR 
#define FBINFO_STATE_RUNNING	0
#define FBINFO_STATE_SUSPENDED	1
	u32 state;		//状态 状态值为上面两个宏
	void *fbcon_par;
	void *par;
	struct apertures_struct {
		unsigned int count;
		struct aperture {
			resource_size_t base;
			resource_size_t size;
		} ranges[0];
	} *apertures;
};

     2. fb_var_screeninfo

struct fb_var_screeninfo {
	__u32 xres;	//水平分辨率
	__u32 yres;	//垂直分辨率
	__u32 xres_virtual;	//水平虚拟分辨率
	__u32 yres_virtual;	//存执虚拟分辨率
	__u32 xoffset;//水平可视区域的偏移
	__u32 yoffset;//垂直可视区域的偏移
	__u32 bits_per_pixel;	//每像素占用多少bit
	__u32 grayscale;		//灰度等级

	struct fb_bitfield red;	//红色位域		offset=11 length=5 (RGB565)	
	struct fb_bitfield green;	//绿色位域		offset=5  length=6
	struct fb_bitfield blue;	//蓝色位域		offset=0	 length=5
	struct fb_bitfield transp;	//透明度位域

	__u32 nonstd;	//非标准标志
	__u32 activate;	//激活标志
	__u32 height;	//物理高度
	__u32 width;	//物理宽度
	__u32 accel_flags;//硬件加速标志
	__u32 pixclock;
	__u32 left_margin;		//左边缘宽度	
	__u32 right_margin;	//右边缘宽度
	__u32 upper_margin;	//上边缘宽度
	__u32 lower_margin;	//下边缘宽度
	__u32 hsync_len;		//水平同步长度
	__u32 vsync_len;		//垂直同步长度
	__u32 sync;
	__u32 vmode;
	__u32 rotate;//旋转
	__u32 reserved[5];
};

     2.1 位域 fb_bitfield

struct fb_bitfield {
	__u32 offset;	//偏移量
	__u32 length;	//长度
	__u32 msb_right;	//高位有效?对齐方式
};

 

     3.fb_fix_screeninfo

struct fb_fix_screeninfo {
	char id[16];
	unsigned long smem_start;	//物理显存起始地址
	__u32 smem_len;	//显示长度(xres*yres*bits_per_pixel/8)
	__u32 type;	//显示类型(FB_TYPE_PACKED_PIXELS)
	__u32 type_aux;
	__u32 visual;	//颜色模式(FB_VISUAL_TRUECOLOR)
	__u16 xpanstep;
	__u16 ypanstep;
	__u16 ywrapstep;
	__u32 line_length;	//一行像素的字节数(xres*bits_per_pixel/8)
	unsigned long mmio_start;
	__u32 mmio_len;
	__u32 accel;//加速类型
	__u16 reserved[3];
};


     4. 操作函数集

struct fb_ops {
	struct module *owner;
	int (*fb_open)(struct fb_info *info, int user);	//打开
	int (*fb_release)(struct fb_info *info, int user);	//释放
	ssize_t (*fb_read)(struct fb_info *info, char __user *buf,size_t count, loff_t *ppos);	//读
	ssize_t (*fb_write)(struct fb_info *info, const char __user *buf,size_t count, loff_t *ppos);	//写
	int (*fb_check_var)(struct fb_var_screeninfo *var, struct fb_info *info);	//检测参数
	int (*fb_set_par)(struct fb_info *info);	//设置参数
	int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green,unsigned blue, unsigned transp, struct fb_info *info);	//设置调色板
	int (*fb_setcmap)(struct fb_cmap *cmap, struct fb_info *info);
	int (*fb_blank)(int blank, struct fb_info *info);	//清屏
	int (*fb_pan_display)(struct fb_var_screeninfo *var, struct fb_info *info);	//
	void (*fb_fillrect) (struct fb_info *info, const struct fb_fillrect *rect);	//填充区域
	void (*fb_copyarea) (struct fb_info *info, const struct fb_copyarea *region);	//复制区域
	void (*fb_imageblit) (struct fb_info *info, const struct fb_image *image);	//图形填充
	int (*fb_cursor) (struct fb_info *info, struct fb_cursor *cursor);	//绘制光标
	void (*fb_rotate)(struct fb_info *info, int angle);		//旋转屏幕
	int (*fb_sync)(struct fb_info *info);	//同步 等待blit空闲
	int (*fb_ioctl)(struct fb_info *info, unsigned int cmd,unsigned long arg);	//控制
	int (*fb_compat_ioctl)(struct fb_info *info, unsigned cmd,unsigned long arg);	//32位兼容控制
	int (*fb_mmap)(struct fb_info *info, struct vm_area_struct *vma);	//映射
	void (*fb_get_caps)(struct fb_info *info, struct fb_blit_caps *caps,struct fb_var_screeninfo *var);
	void (*fb_destroy)(struct fb_info *info);	//销毁
	int (*fb_debug_enter)(struct fb_info *info);
	int (*fb_debug_leave)(struct fb_info *info);
};

二. fb系统初始化

     1. 主设备号

#define FB_MAJOR		29

     2. fbmem_init

static int __init fbmem_init(void)
{
	proc_create("fb", 0, NULL, &fb_proc_fops);	//创建"/proc/fb"文件
	if (register_chrdev(FB_MAJOR,"fb",&fb_fops))	//注册所有的fb字符设备,并捆绑fb_fops操作函数集合
		printk("unable to get major %d for fb devs\n", FB_MAJOR);

	fb_class = class_create(THIS_MODULE, "graphics");	//创建"/sys/class/graphics"
	if (IS_ERR(fb_class)) {
		printk(KERN_WARNING "Unable to create fb class; errno = %ld\n", PTR_ERR(fb_class));
		fb_class = NULL;
	}
	return 0;
}

    3. /proc下的接口fb_proc_fops

    3.1 操作函数集

static const struct file_operations fb_proc_fops = {
	.owner		= THIS_MODULE,
	.open		= proc_fb_open,	//打开
	.read		= seq_read,	//读取
	.llseek		= seq_lseek,	//读写指针
	.release	= seq_release,
};

     3.2 cat /prco/fb

cat /proc/fb
0 ti81xxfb
1 ti81xxfb
2 ti81xxfb

     先调用open方法

static int proc_fb_open(struct inode *inode, struct file *file)
{
	return seq_open(file, &proc_fb_seq_ops);	//主要做了file->private_data->op=proc_fb_seq_ops
}

     proc_fb_seq_ops

static const struct seq_operations proc_fb_seq_ops = {
	.start	= fb_seq_start,	//读写位置开头
	.next	= fb_seq_next,	//下一个读写位置
	.stop	= fb_seq_stop,	//无操作
	.show	= fb_seq_show,	//显示
};

     fb_seq_show函数

static int fb_seq_show(struct seq_file *m, void *v)
{
	int i = *(loff_t *)v;
	struct fb_info *fi = registered_fb[i];	//获取fb_info结构体

	if (fi)
		seq_printf(m, "%d %s\n", fi->node, fi->fix.id);	//打印其设备编号及设备信息到seq_file文件
	return 0;
}

     接着调用read方法

seq_read方法调用proc_fb_seq_ops的各个方法,最终将seq_file文件里的打印信息,复制到用户空间的buf里面

     4. 字符设备捆绑的fb_fops

     4.1 操作函数集

static const struct file_operations fb_fops = {
	.owner =	THIS_MODULE,	//模块所有者
	.read =	fb_read,		//读
	.write =	fb_write,		//写
	.unlocked_ioctl = fb_ioctl,	//控制
#ifdef CONFIG_COMPAT
	.compat_ioctl = fb_compat_ioctl,
#endif
	.mmap =	fb_mmap,		//映射
	.open =	fb_open,		//打开
	.release = fb_release,	//是否
#ifdef HAVE_ARCH_FB_UNMAPPED_AREA
	.get_unmapped_area = get_fb_unmapped_area,
#endif
#ifdef CONFIG_FB_DEFERRED_IO
	.fsync =	fb_deferred_io_fsync,
#endif
	.llseek =	default_llseek,	//读写指针
};

     4.1.1 打开

static int fb_open(struct inode *inode, struct file *file)
__acquires(&info->lock)
__releases(&info->lock)
{
	int fbidx = iminor(inode);	//根据节点算出次设备号
	struct fb_info *info;
	int res = 0;

	if (fbidx >= FB_MAX)
		return -ENODEV;
	info = registered_fb[fbidx];	//从全局registered_fb数组中获取fb_info
	if (!info)
		request_module("fb%d", fbidx);
	info = registered_fb[fbidx];
	if (!info)
		return -ENODEV;
	mutex_lock(&info->lock);
	if (!try_module_get(info->fbops->owner)) {
		res = -ENODEV;
		goto out;
	}
	file->private_data = info;		//将fb_info数据存放在文件的私有数据里
	if (info->fbops->fb_open) {		//若fb_info的fb操作函数集有实现open方法
		res = info->fbops->fb_open(info,1);	//则调用其open方法
		if (res)
			module_put(info->fbops->owner);
	}
#ifdef CONFIG_FB_DEFERRED_IO
	if (info->fbdefio)
		fb_deferred_io_open(info, inode, file);
#endif
out:
	mute
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值