linux的lcd驱动详细讲解
嵌⼊式驱动程序Day12
Top
1. LCD驱动设计开发
1 LCD驱动设计开发
1.1问题
通过led驱动开发掌握linux内核framebuffer 驱动开发通⽤⽅法。
1.2⽅案
⼀、帧缓冲(Framebuffer )。
帧缓冲(Framebuffer )是Linux为显⽰设备提供的⼀个接⼝,Linux抽象出FrameBuffer这个设备来供⽤户态进程实现直接写屏。Framebuffer机制模仿显卡的功
能,将显卡硬件结构抽象掉,可以通过Framebuffer的读写直接对显存进⾏操作。⽤户
可以将Framebuffer看成是显⽰内存的⼀个映像,将其映射到进程地址空间之后,就可以直接进⾏读写操作,⽽写操作可以⽴即反应在屏幕上。这种操作是抽象的,统⼀的。⽤户不必关⼼物理显存的位置、换页机制等等具体细节。这些都是由Framebuffer 设备驱动
来完成的。
Framebuffer本⾝不具备任何运算数据的能⼒,就只好⽐是⼀个暂时存放⽔的⽔池。CPU将运算后的结果放到这个⽔池,⽔池再将结果流到显⽰器,中间不会对数据做处
理。应⽤程序也可以直接读写这个⽔池的内容。在应⽤程序中,⼀般通过将FrameBuffer 设备映射到进程地址空间的⽅式使⽤,⽐如下⾯的程序就打开/dev/fbO 设备,并通过mmap系统调⽤进⾏地址映射。
FrameBuffer设备还提供了若⼲ioctl 命令,通过这些命令,可以获得显⽰设备的
⼀些固定信息(⽐如显⽰内存⼤⼩)、与显⽰模式相关的可变信息(⽐如分辨率、象素结构、每扫描线的字节宽度),以及伪彩⾊模式下的调⾊板信息等等。
⼆、FrameBuffer 在Linux中的实现和机制。
Framebuffer对应的源⽂件在linux/drivers/video/ ⽬录下。总的抽象设备⽂件为fbcon.c,在这个⽬录下还有与各种显卡驱动相关的源⽂件。
1. 分析Framebuffer设备驱动。
FrameBuffer设备驱动基于如下两个⽂件:
(1) linux/include/linux/fb.h
(2) linux/drivers/video/fbmem.c
2. 分析这两个⽂件。
( 1) fb.h 。
⼏乎主要的结构都是在这个中⽂件定义的。这些结构包括:
1) fb_var_screeninfo 结构体。
这个结构描述了显⽰卡的特性:
__u32 是表⽰unsigned 不带符号的32 bits 的数据类型,其余类推。这是Linux 内核中所⽤到的数据类型,如果是开发⽤户空间( user-space )的程序,可以根据具体计算机平台的情况,⽤unsigned long 等等来代替。
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;
linux内核设计与实现 pdf
struct fb_bitfield green; /* else only length is significant */
struct fb_bitfield blue;
struct fb_bitfield transp; // 透明
__u32 nonstd; // 不是标准格式
__u32 activate; /* see FB_ACTIVATE_* */
__u32 height; // 内存中的图像⾼度
__u32 width; // 内存中的图像宽度
__u32 accel_flags; // 加速标志
// 时序-_- 这些部分就是显⽰器的显⽰⽅法
__u32 pixclock; /* pixel clock in ps (pico seconds) */
__u32 left_margin; /* time from sync to picture */
__u32 right_margin; /* time from picture to sync */
__u32 upper_margin; /* time from sync to picture */
__u32 lower_margin;
__u32 hsync_len; /* length of horizontal sync */ ⽔平可视区域
__u32 vsync_len; /* length of vertical sync */ __u32 sync; /* see FB_SYNC_* */ __u32 vmode; /* see FB_VMODE_* */ __u32 reserved[6]; // 备⽤-以后开发
};
2) fb_fix_screeninfon
结构体。这个结构在显卡被设定模式后创建,它描述显⽰卡的属性,并且系统运⾏时不能被修改;⽐如 FrameBuffer 内存的起始地址。它依赖于被设定的模式,当⼀个模式被设定后,内存信息由显⽰卡
硬件给出,内存的位置等信息就不可以修改。
struct fb_fix_screeninfo {
char id[16]; /* identification string eg "TT Builtin" */ID unsigned long smem_start; /* Start of frame buffer mem */ 内存起始
/* (physical address) */ 物理地址
__u32 smem_len; /* Length of frame buffer mem */ 内存⼤⼩
__u32 type; /* see FB_TYPE_* */
__u32 type_aux; /* Interleave for interleaved Planes */ 插⼊区域?
__u32 visual; /* see FB_VISUAL_* */ __u16 xpanstep; //
没有硬件设备就为零
__u16 ypanstep; /* zero if no hardware panning */ __u16 ywrapstep; /* zero if no hardware ywrap */ __u32 line_length; //⼀⾏的字节表⽰
unsigned long mmio_start; // 内存映射的 I/O 起始 /* (physical address) */ __u32 mmio_len; // I/O
的⼤⼩
__u32 accel; /* Type of acceleration available */ 可⽤的加速类型
__u16 reserved[3]; /* Reserved for future compatibility */ };
3) fb_cmap 结构体。
描述设备⽆关的颜⾊映射信息。可以通过 FBIOGETCMA 和FBIOPUTCMAP 对应的
ioctl 操作设定或获取颜⾊映射信息。
struct fb_cmap {
__u32 start; /* First entry */ __u32 len; /* Number of entries */ __u16 *red; /* Red values */
垂直可视区域
第⼀个⼊⼝
⼊⼝的数字
__u16 *green;
__u16 *blue;
__u16 *transp; /* transparency, can be NULL
*/ };
透明,可以为零
4) fb_info 结构体。
定义当显卡的当前状态;fb_info 结构仅在内核中可见,在这个结构中有⼀个指
针,指向驱动设备⼯作所需的函数集。
fb_ops
struct fb_info {
char modename[40]; // 默认的视频卡类型
kdev_t node;
int flags;
int open; // 被打开过么?
#define FBINFO_FLAG_MODULE 1 /* Low-level driver is a module */
struct fb_var_screeninfo var; // struct fb_fix_screeninfo fix; // 现在的视频信息修正的信息
struct fb_monspecs monspecs; // 现在的显⽰器模式
struct fb_cmap cmap; // 当前优先级
struct fb_ops *fbops;
char *screen_base; // 物理基址
struct display *disp; // 初始化
struct vc_data *display_fg; /* Console visible on this display */
char fontname[40]; // 默认的字体
devfs_handle_t devfs_handle; /* Devfs handle for new name */
devfs_handle_t devfs_lhandle; // 兼容int (*changevar)(int); //
告诉console 变量修改了int (*switch_con)(int, struct fb_info*);
// 告诉fb 选择consoles
int (*updatevar)(int, struct fb_info*);
/* tell fb to update the vars */ 告诉fb 更新变量
void (*blank)(int, struct fb_info*); /* tell fb to (un)blank the screen */ 告诉fb 使⽤⿊⽩模式(或者不⿊)
/* arg = 0: unblank */arg = 0 的时候⿊⽩模式
/
* arg > 0: VESA level (arg-1) */ arg>0 时候选择VESA模式void *pseudo_palette; /* Fake palette of 16 colors and the cursor's color for non
palette mode */ 修正调⾊板
/* From here on everything is device dependent */ void *par;
现在就可以使⽤了};
5) struct fb_ops 结构体。
⽤户应⽤可以使⽤ioctl() 系统调⽤来操作设备,这个结构就是⽤⼀⽀持ioctl() 的这些操作的。
struct fb_ops {
/* open/release and usage marking */ struct module *owner;
int (*fb_open)(struct fb_info *info, int user); int (*fb_release)(struct fb_info *info, int user);
/* get non settable parameters */
int (*fb_get_fix)(struct fb_fix_screeninfo *fix, int con,
struct fb_info *info);
/* get settable parameters */
int (*fb_get_var)(struct fb_var_screeninfo *var, int con, struct fb_info *info);
/* set settable parameters */
int (*fb_set_var)(struct fb_var_screeninfo *var, int con, struct fb_info *info);
/* get colormap */
int (*fb_get_cmap)(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info);
/* set colormap */
int (*fb_set_cmap)(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info);
/* pan display (optional) */
int (*fb_pan_display)(struct fb_var_screeninfo *var, int con, struct fb_info *info);
/
* perform fb specific ioctl (optional) */
int (*fb_ioctl)(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg, int con, struct fb_info *info);
/* perform fb specific mmap */
int (*fb_mmap)(struct fb_info *info, struct file *file, struct vm_area_struct *vma);
/* switch to/from raster image mode */
int (*fb_rasterimg)(struct fb_info *info, int start);
};
( 2) fbmem.c 。
fbmem.c 处于Framebuffer 设备驱动技术的中⼼位置。它为上层应⽤程序提供系统调⽤也为下⼀层的特定硬件驱动提供接⼝;那些底层硬件驱动需要⽤到这⼉的接⼝来向系统内核注册它们⾃
⼰。fbmem.c 为所有⽀持FrameBuffer 的设备驱动提供了通⽤的接⼝,避免重复⼯作。
1) 全局变量。
struct fb_info *registered_fb[FB_MAX];
int num_registered_fb;
这两变量记录了所有fb_info 结构的实例,fb_info 结构描述显卡的当前状态,所有设备对应的fb_info 结构都保存在这个数组中,当⼀个FrameBuffer 设备驱动向系统注册⾃⼰时,其对应的fb_info 结构就会添加到这个结构中,同时num_registered_fb 为⾃动加1。
static struct {
const char *name;
int (*init)(void);
int (*setup)(void);
} fb_drivers[] __initdata= { ... };
如果FrameBuffer 设备被静态链接到内核,其对应的⼊⼝就会添加到这个表中;如果是动态加载的,
即使⽤insmod/rmmod ,就不需要关⼼这个表。
static struct file_operations fb_ops ={
owner: THIS_MODULE,
read: fb_read,
write: fb_write,
ioctl: fb_ioctl,
mmap: fb_mmap,
open: fb_open,
release: fb_release
};
这是⼀个提供给应⽤程序的接⼝。
2)fbmem.c 实现了如下函数。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。