十七、(正点原子)Linux LCD驱动

一、Framebuffer设备

        在 Linux 中应用程序通过操作 RGB LCD 的显存来实现在 LCD 上显示字符、图片等信息。

        先来看一下裸机 LCD 驱动如下:
        ①、初始化 I.MX6U 的 eLCDIF 控制器,重点是 LCD 屏幕宽(width)、高(height)、 hspw、
hbp、 hfp、 vspw、 vbp 和 vfp 等信息。
        ②、初始化 LCD 像素时钟。
        ③、设置 RGBLCD 显存。
        ④、应用程序直接通过操作显存来操作 LCD,实现在 LCD 上显示字符、图片等信息。

         在裸机中我们可以随意的分配显存,但是在 Linux 系统中内存的管理很严格,显存是需要申请的,不是你想用就能用的。而且因为虚拟内存的存在,驱动程序设置的显存和应用程序访问的显存要是同一片物理内存。

        为了解决上述问题, Framebuffer 诞生了, Framebuffer 翻译过来就是帧缓冲,简称 fb,因此大家在以后的 Linux 学习中见到“Framebuffer”或者“fb”的话第一反应应该想到 RGBLCD或者显示设备。 fb 是一种机制,将系统中所有跟显示有关的硬件以及软件集合起来,虚拟出一个 fb 设备,当我们编写好 LCD 驱动以后会生成一个名为/dev/fbX(X=0~n)的设备,应用程序通过访问/dev/fbX 这个设备就可以访问 LCD。
        NXP 官方的 Linux 内核默认已经开启了 LCD 驱动,因此我们是可以看到/dev/fb0 这样一个设备,如图所示:

        图中的/dev/fb0 就是 LCD 对应的设备文件, /dev/fb0 是个字符设备,因此肯定有file_operations 操作集, fb 的 file_operations 操作集,如下所示:

定义在 drivers/video/fbdev/core/fbmem.c 文件中

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,
};

         Linux 内核将所有的 Framebuffer 抽象为一个叫做 fb_info 的结构体, fb_info 结构体包含了 Framebuffer 设备的完整属性和操作集合,因此每一个 Framebuffer 设备都必须有一个 fb_info。换言之就是, LCD 的驱动就是构建 fb_info,并且向系统注册 fb_info的过程。

定义在 include/linux/fb.h 文件里
struct fb_info {
	atomic_t count;
	int node;
	int flags;
	struct mutex lock;		        /* 互斥锁 */
	struct mutex mm_lock;		    /* 互斥锁,用于 fb_mmap 和 smem_*域*/
	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        /* 如果 LCD 支持背光的话 */
	/* assigned backlight device */
	/* set before framebuffer registration, 
	   remove after unregister */
	struct backlight_device *bl_dev;    /* 背光设备 */

	/* Backlight level curve */
	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;       /* 帧缓冲操作函数集 */
	struct device *device;		/* 父设备 */
	struct device *dev;		    /* 当前 fb 设备 */
	int class_flag;             * 私有 sysfs 标志 */
	struct fb_tile_ops *tileops;    /* Tile Blitting */
#endif
	char __iomem *screen_base;	/* 虚拟内存基地址(屏幕显存) */
	unsigned long screen_size;	/* 虚拟内存大小(屏幕显存大小) */ 
	void *pseudo_palette;		/* 伪 16 位调色板 */ 
#define FBINFO_STATE_RUNNING	0
#define FBINFO_STATE_SUSPENDED	1
	u32 state;			/* Hardware state i.e suspend */
	void *fbcon_par;                /* fbcon use-only private area */
	/* From here on everything is device dependent */
	void *par;
	/* we need the PCI or similar aperture base/size not
	   smem_start/size as smem_start may just be an object
	   allocated inside the aperture so may not actually overlap */
	struct apertures_struct {
		unsigned int count;
		struct aperture {
			resource_size_t base;
			resource_size_t size;
		} ranges[0];
	} *apertures;

	bool skip_vt_switch; /* no VT switch on suspend/resume required */
};

        fb_info 结构体的成员变量很多,我们重点关注 var、 fix、 fbops、 screen_base、screen_size和 pseudo_palette。

        fb_info结构体创建好初始化完成之后,使用register_framebuffer 函数向 Linux 内核注册初始化好的 fb_info。函数原型:

定义在 drivers/video/fbdev/mxsfb.c 种

int register_framebuffer(struct fb_info *fb_info)

        fb_info:需要注册的 fb_info。
        返回值: 0,成功;负值,失败。
       

        卸载 f

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tofu_Cabbage

你的打赏是我的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值