2019独角兽企业重金招聘Python工程师标准>>>
上篇文章我们已经对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);
};
分析完主要的结构体之后,下篇文章开始写具体驱动程序。