LCD驱动程序详细讲解(二)

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

上篇文章我们已经对LCD、LCD控制器和时序控制图进行了分析,这篇文章主要介绍怎么写LCD驱动程序;写LCD驱动程序安装传统的规则主要分为以下几个步骤:
1. 分配一个fb_info结构体: 使用framebuffer_alloc
2. 设置:各种参数的设置
3. 注册: register_framebuffer
4. 硬件相关的操作;

在写LCD驱动程序之前我们先详细介绍fb_info结构体,其实LCD驱动程序中的重点内容。fb_info结构体的定义源码如下:

struct fb_info {
	int node;   //次设备号
	int flags;
	struct fb_var_screeninfo var;	//LCD可变参数结构体
	struct fb_fix_screeninfo fix;	//LCD固定参数结构体
	struct fb_monspecs monspecs;	//LCD 显示器标准
	struct work_struct queue;	    //帧缓冲事件队列
	struct fb_pixmap pixmap;	    //图像硬件 mapper
	struct fb_pixmap sprite;	    //光标硬件mapper
	struct fb_cmap cmap;		    //当前的颜色表
	struct list_head modelist;      //模式列表
	struct fb_videomode *mode;	    //当前的显示模式

#ifdef CONFIG_FB_BACKLIGHT
	/* 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;		/* This is the parent */
	struct device *dev;		    //fb设备
	int class_flag;                    /* private sysfs flags */
#ifdef CONFIG_FB_TILEBLITTING
	struct fb_tile_ops *tileops;     //图块Blitting
#endif
	char __iomem *screen_base;	   //虚拟基地址
	unsigned long screen_size;	   //LCD IO映射的虚拟内存大小
	void *pseudo_palette;		   //伪16色颜色表
#define FBINFO_STATE_RUNNING	0
#define FBINFO_STATE_SUSPENDED	1
	u32 state;			//LCD的挂起或恢复状态
	void *fbcon_par;                /* fbcon use-only private area */
	/* From here on everything is device dependent */
	void *par;	
};

其中,比较重要的成员有struct fb_var_screeninfo var、struct fb_fix_screeninfo fix和struct fb_ops *fbops,他们也都是结构体。

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数,这个参数不需要自己配置,而是通过上层在调用checkvar函数传递bpp的时候赋值的
	__u32 grayscale;		//非0时,指的是灰度

	struct fb_bitfield red;		//fb缓存的R位域
	struct fb_bitfield green;	//fb缓存的G位域
	struct fb_bitfield blue;    //fb缓存的B位域
	struct fb_bitfield transp;	//透明度

	__u32 nonstd;			//如果nonstd 不等于0,非标准的像素格式

	__u32 activate;			/* 查看FB_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;			    //看 FB_SYNC_*
	__u32 vmode;			//看 FB_VMODE_*
	__u32 rotate;			/* angle we rotate counter clockwise */
	__u32 reserved[5];		/* Reserved for future compatibility */
};

而fb_fix_screeninfo结构体又主要记录用户不可以修改的控制器的参数,比如屏幕缓冲区的物理地址和长度等,该结构体的定义如下:

struct fb_fix_screeninfo {
	char id[16];			//字符串形式的标识符
	unsigned long smem_start;	/*fb缓存的开始位置 */
					/* (physical address) */
	__u32 smem_len;			/*fb缓存的长度 */
	__u32 type;			/*看FB_TYPE_* */
	__u32 type_aux;			/* 分界 */
	__u32 visual;			//看FB_VISUAL_*
	__u16 xpanstep;			/*如果没有硬件panning就赋值为0 */
	__u16 ypanstep;			/*如果没有硬件panning就赋值为0 */
	__u16 ywrapstep;		/*如果没有硬件ywrap就赋值为0 */
	__u32 line_length;		/*一行的字节数 */
	unsigned long mmio_start;	/*内存映射IO的开始位置*/
					/* (physical address) */
	__u32 mmio_len;		 /*内存映射IO的长度*/
	__u32 accel;			/* Indicate to driver which	*/
					/*  specific chip/card we have	*/
	__u16 reserved[3];		/*保留*/
};

fb_ops结构体是对底层硬件操作的函数指针,该结构体中定义了对硬件的操作有:(这里只列出了常用的操作);

struct fb_ops {
    struct module *owner;
    //检查可变参数并进行设置
    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_blank)(int blank, 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);
};

分析完主要的结构体之后,下篇文章开始写具体驱动程序。

转载于:https://my.oschina.net/cht2000/blog/1021774

你可能感兴趣的:(LCD驱动程序详细讲解(二))