帧缓冲设备

1.1帧缓冲设备:
帧缓冲(framebuffer)是 Linux 系统为显示设备提供的一个接口,它将显示缓冲区抽象,屏蔽图像硬件的底层差异,允许上层应用程序在图形模式下直接对显示缓冲区进行读写操作。用户不必关心物理显示缓冲区的具体位置及存放方式,这些都由帧缓冲设备驱动本身来完成。对于帧缓冲设备而言,只要在显示缓冲区中与显示点对应的区域写入颜色值,对应的颜色会自动在屏幕上显示。

1.2 Linux帧缓冲相关数据结构与函数
   fb_info结构体
     帧缓冲设备最关键的一个数据结构体是fb_info结构体(为了便于记忆,我们把它简称为“FBI”),
  FBI中包括了关于帧缓冲设备属性和操作的完整描述。

FBI 中记录了帧缓冲设备的全部信息,包括设备的设置参数、状态以及操作函数指针。每一个帧缓冲设备都必须对应一个 FBI。

  struct fb_info {
int node;
int flags;
struct mutex lock; /* 用于 open/release/ioctl 的锁 */
struct fb_var_screeninfo var; /*可变参数 */
struct fb_fix_screeninfo fix; /*固定参数 */
struct fb_monspecs monspecs; /*显示器标准 */
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; /* 目前的 video 模式 */ #ifdef CONFIG_FB_BACKLIGHT
/* 对应的背光设备 */
struct backlight_device *bl_dev;
/* 背光调整 */
struct mutex bl_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_ops,帧缓冲操作 */
struct device *device; /* 父设备 */
struct device *dev; /* fb 设备 */
int class_flag; /* 私有 sysfs 标志 */
#ifdef CONFIG_FB_TILEBLITTING
struct fb_tile_ops *tileops; /* 图块 Blitting */
#endif
char _ _iomem *screen_base; /* 虚拟基地址 */
unsigned long screen_size; /* ioremapped 的虚拟内存大小 */
void *pseudo_palette; /* 伪 16 色颜色表 */
#define FBINFO_STATE_RUNNING 0
#define FBINFO_STATE_SUSPENDED 1
u32 state; /* 硬件状态,如挂起 */
void *fbcon_par;
void *par;
};

fb_info结构体

  fb_ops 结构体
 FBI 的成员变量 fbops 为指向底层操作的函数的指针,这些函数是需要驱动程序开发人员编
写的。

  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 file *file, char _ _user *buf, size_t count,
loff_t*ppos);
ssize_t(*fb_write)(struct file *file, const char _ _user *buf, size_t count,
loff_t *ppos); /* 检测可变参数,并调整到支持的值*/
int(*fb_check_var)(struct fb_var_screeninfo *var, struct fb_info *info); /* 根据 info->var 设置 video 模式 */
int(*fb_set_par)(struct fb_info *info); /* 设置 color 寄存器 */
int(*fb_setcolreg)(unsigned regno, unsigned red, unsigned green, unsigned
blue, unsigned transp, struct fb_info *info); /* 批量设置 color 寄存器,设置颜色表 */
int(*fb_setcmap)(struct fb_cmap *cmap, struct fb_info *info); /*显示空白 */
int(*fb_blank)(int blank, struct fb_info *info); /* pan 显示 */
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); /* 等待 blit 空闲 (可选) */
int(*fb_sync)(struct fb_info *info); /* fb 特定的 ioctl (可选) */
int(*fb_ioctl)(struct fb_info *info, unsigned int cmd, unsigned long arg); /* 处理 32 位的 compat ioctl (可选) */
int(*fb_compat_ioctl)(struct fb_info *info, unsigned cmd, unsigned long arg); /* fb 特定的 mmap */
int(*fb_mmap)(struct fb_info *info, struct vm_area_struct *vma); /* 保存目前的硬件状态 */
void(*fb_save_state)(struct fb_info *info); /* 恢复被保存的硬件状态 */
void(*fb_restore_state)(struct fb_info *info); void (*fb_get_caps)(struct fb_info *info, struct fb_blit_caps *caps,
struct fb_var_screeninfo *var);
};

fb_ops 结构体

 

 fb_var_screeninfo 和 fb_fix_screeninfo 结构体

   FBI 的 fb_var_screeninfo 和 fb_fix_screeninfo 成员也是结构体,fb_var_screeninfo 记录用户可修改的显示控制器参数,包括屏幕分辨率和每个像素点的比特数。fb_var_screeninfo 中的 xres 定义屏幕一行有多少个点,yres 定义屏幕一列有多少个点,bits_per_pixel 定义每个点用多少个字节表示。而 fb_fix_screeninfo 中记录用户不能修改的显示控制器的参数,如屏幕缓冲区的物理地址、长度。当对帧缓冲设备进行映射操作的时候,就是从 fb_fix_screeninfo 中取得缓冲区物理地址的。上述数据成员都需要在驱动程序中初始化和设置。

  struct fb_var_screeninfo {
/* 可见解析度 */
u32 xres;
u32 yres;
/* 虚拟解析度 */
u32 xres_virtual;
u32 yres_virtual;
/* 虚拟到可见之间的偏移 */
u32 xoffset;
u32 yoffset; u32 bits_per_pixel; /* 每像素位数,BPP */
u32 grayscale; /非 时指灰度 */ /* fb 缓存的 R\G\B 位域 */
struct fb_bitfield red;
struct fb_bitfield green;
struct fb_bitfield blue;
struct fb_bitfield transp; /* 透明度 */ u32 nonstd; /* != 0 非标准像素格式 */ u32 activate; u32 height; /*高度 */
u32 width; /*宽度 */ u32 accel_flags; /* 看 fb_info.flags */ /* 定时: 除了 pixclock 本身外,其他的都以像素时钟为单位 */
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[]; /* 保留 */
};

fb_var_screeninfo 结构体

  struct fb_fix_screeninfo {
char id[]; /* 字符串形式的标识符 */
unsigned long smem_start; /* fb 缓冲内存的开始位置(物理地址) */
u32 smem_len; /* fb 缓冲的长度 */
u32 type; /* FB_TYPE_* */
u32 type_aux; /* Interleave */
u32 visual; /* FB_VISUAL_* */
u16 xpanstep; /* 如果没有硬件 panning ,赋 0 */
u16 ypanstep;
u16 ywrapstep;/
u32 line_length; /* 1 行的字节数 */
unsigned long mmio_start; /* 内存映射 I/O 的开始位置 */
u32 mmio_len; /* 内存映射 I/O 的长度 */
u32 accel;
u16 reserved[]; /* 保留*/
};

fb_fix_screeninfo 结构体

文件操作结构体 
      作为一种字符设备,帧缓冲设备的文件操作结构体定义于/linux/drivers/vedio/fbmem.c文件中。
 代码清单 帧缓冲设备文件操作结构体

  static struct file_operations fb_fops = {
.owner = THIS_MODULE,
.read = fb_read,
.write = fb_write,
.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
};

文件操作结构体

帧缓冲设备驱动的文件操作接口函数已经在 fbmem.c 中被统一实现,一般不需要由驱动工程师再编写。

注册与注销帧缓冲设备
    Linux 内核提供了 register_framebuffer()和 unregister_framebuffer()函数分别注册和注销帧缓冲设备,这两个函数都接受 FBI 指针为参数,原型为:
int register_framebuffer(struct fb_info *fb_info); 
int unregister_framebuffer(struct fb_info *fb_info); 
对于 register_framebuffer()函数而言,如果注册的帧缓冲设备数超过了 FB_MAX(目前定义为32),则函数返回-ENXIO,注册成功则返回 0。

在帧缓冲设备驱动的模块加载函数中,应该完成如下 4 个工作。
(1)申请 FBI 结构体的内存空间(framebuffer_alloc),初始化 FBI 结构体中固定和可变的屏幕参数,即填充 FBI
中 fb_var_screeninfo var 和 struct fb_fix_screeninfo fix 成员。
(2)根据具体 LCD 屏幕的特点,完成 LCD 控制器硬件的初始化。
(3)申请帧缓冲设备的显示缓冲区空间(dma_alloc_writecombine)。
(4)注册帧缓冲设备。

在帧缓冲设备驱动的模块卸载函数中,应该完成相反的工作,包括释放 FBI 结构体内存、关闭 LCD、释放显示缓冲区以及注销帧缓冲设备。
     由于LCD控制器经常被集成在SoC上作为一个独立的硬件模块而存在(成为platform_device),因此,LCD 驱动中也经常包含平台驱动,这样,在帧缓冲设备驱动的模块加载函数中完成的工作只是注册平台驱动,而初始化FBI结构体中的固定和可变参数、LCD 控制器硬件的初始化、申请帧缓冲设备的显示缓冲区空间和注册帧缓冲设备的工作则移交到平台驱动的探测函数中完成。 同样地,在使用平台驱动的情况下,释放 FBI 结构体内存、关闭 LCD、释放显示缓冲区以及注销帧缓冲设备的工作也移交到平台驱动的移除函数中完成。

帧缓冲设备驱动的模块加载/卸载及平台驱动的探测/移除函数的模板 :

  /* 平台驱动结构体 */
static struct platform_driver xxxfb_driver = {
.probe = xxxfb_probe,
.remove = xxxfb_remove,
.suspend = xxxfb_suspend,
.resume = xxxfb_resume,
.driver = {
.name = "xxx-lcd", /* 驱动名 */
.owner = THIS_MODULE,
}
}; /* 平台驱动探测函数 */
static int _ _init xxxfb_probe(...)
{
struct fb_info *info; /*分配 fb_info 结构体*/
info = framebuffer_alloc(...); info->screen_base = framebuffer_virtual_memory;
info->var = xxxfb_var; /* 可变参数 */
info->fix = xxxfb_fix; /* 固定参数 */ /*分配显示缓冲区*/
alloc_dis_buffer(...); /*初始化 LCD 控制器*/
lcd_init(...); /*检查可变参数*/
xxxfb_check_var(&info->var, info); /*注册 fb_info*/
if (register_framebuffer(info) < )
return - EINVAL; return ;
} /* 平台驱动移除函数 */
static void _ _exit xxxfb_remove(...)
{
struct fb_info *info = dev_get_drv_data(dev); if (info) {
unregister_framebuffer(info); /* 注销 fb_info */
dealloc_dis_buffer(...); /* 释放显示缓冲区 */
framebuffer_release(info); /* 注销 fb_info */
} return ;
} /* 帧缓冲设备驱动模块加载与卸载函数 */
int __init xxxfb_init(void)
{
return platform_driver_register(&xxxfb_driver); /* 注册平台设备 */
} static void __exit xxxfb_cleanup(void)
{
platform_driver_unregister(&xxxfb_driver); /* 注销平台设备 */
} module_init(xxxfb_init);
module_exit(xxxfb_cleanup);

模板

总结:
     帧缓冲设备是一种典型的字符设备,它统一了显存,将显示缓冲区直接映射到用户空间。帧缓冲设备驱动 file_operations 中 VFS 接口函数由 fbmem.c 文件统一实现。这样,驱动工程师的工作重点将是实现针对特定设备 fb_info 中的 fb_ops 的成员函数,另外,理解并能灵活地修改fb_info 中的 var 和 fix 参数非常关键。fb_info 中的 var 参数直接和 LCD 控制器的硬件设置以及LCD 屏幕对应。 在用户空间,应用程序直接按照预先设置的 R、G、B 位数和偏移写经过 mmap()映射后的显示缓冲区就可实现图形的显示,省去了内存从用户空间到内核空间的复制过程。

lcd驱动实例:(基于Smart210)

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/cpufreq.h> #include <asm/io.h>
#include <asm/div64.h> #include <asm/mach/map.h>
#include <mach/regs-gpio.h> //lcd控制器寄存器
struct lcd_regs {
unsigned long VIDCON0;
unsigned long VIDCON1;
unsigned long VIDCON2;
unsigned long VIDCON3;
unsigned long VIDTCON0;
unsigned long VIDTCON1 ;
unsigned long VIDTCON2 ;
unsigned long VIDTCON3 ;
unsigned long WINCON0 ;
unsigned long WINCON1 ;
unsigned long WINCON2 ;
unsigned long WINCON3 ;
unsigned long WINCON4 ;
unsigned long SHADOWCON;
};
static unsigned long *VIDOSD0A;
static unsigned long *VIDOSD0B;
static unsigned long *VIDOSD0C;
static unsigned long *VIDW00ADD0B0;
static unsigned long *VIDW00ADD1B0; static struct lcd_regs *lcd_reg; static unsigned long *DISPLAY_CONTROL; /* LCD参数 */
#define VSPW 9
#define VBPD 13
#define LINEVAL 479
#define VFPD 21 #define HSPW 19
#define HBPD 25
#define HOZVAL 799
#define HFPD 209 #define LINEVAL 479
#define HOZVAL 799 #define LeftTopX_F 0
#define LeftTopY_F 0
#define RightBotX_F 799
#define RightBotY_F 479 /* 用于LCD的GPIO */
static unsigned long *gpf0con;
static unsigned long *gpf1con;
static unsigned long *gpf2con;
static unsigned long *gpf3con;
static unsigned long *gpd0con;
static unsigned long *gpd0dat; static struct fb_info *lcd_info; static unsigned int pseudo_palette[]; static inline unsigned int chan_to_field(unsigned int chan, struct fb_bitfield *bf)
{
chan &= 0xffff;
chan >>= - bf->length;
return chan << bf->offset;
} static int smart210_lcdfb_setcolreg(unsigned regno, unsigned red, unsigned green,
unsigned blue, unsigned transp,
struct fb_info *info)
{
unsigned int val; if (regno > )
return ; /* 用red,green,blue三原色构造出val */
val = chan_to_field(red, &info->var.red);
val |= chan_to_field(green, &info->var.green);
val |= chan_to_field(blue, &info->var.blue); //((u32 *)(info->pseudo_palette))[regno] = val;
pseudo_palette[regno] = val;
return ; } static struct fb_ops smart210_lcd_ops = {
.owner = THIS_MODULE,
.fb_setcolreg = smart210_lcdfb_setcolreg,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
}; static int __init my_lcd_init(void)
{
struct clk *lcd_clk;
/*分配一个fb_info的结构体*/
lcd_info = framebuffer_alloc( ,NULL);
if(IS_ERR(lcd_info)) {
printk(KERN_ALERT"framebuffer_alloc error\n");
return -ENOMEM;
}
/*设置*/
/*配置fix固定参数*/
strcpy(lcd_info->fix.id, "Smart210_lcd");
//lcd_info->fix.smem_start
lcd_info->fix.smem_len = * * ; /*7寸屏,rgb 8:8:8*/
lcd_info->fix.type = FB_TYPE_PACKED_PIXELS;
lcd_info->fix.visual = FB_VISUAL_TRUECOLOR; //真彩
lcd_info->fix.line_length = * ;
/*配置可变参数var*/
lcd_info->var.xres = ;
lcd_info->var.yres = ;
lcd_info->var.xres_virtual = ;
lcd_info->var.yres_virtual = ;
lcd_info->var.xoffset = ;
lcd_info->var.yoffset = ;
lcd_info->var.bits_per_pixel = ; //每个像素多少位 32位
lcd_info->var.grayscale = ; //灰度级设为0 lcd_info->var.red.length = ;
lcd_info->var.red.offset = ;
lcd_info->var.green.length = ;
lcd_info->var.green.offset = ;
lcd_info->var.blue.length = ;
lcd_info->var.blue.offset = ; lcd_info->var.nonstd = ; //标准像素
lcd_info->var.activate = FB_ACTIVATE_NOW; /*配置操作函数*/
lcd_info->fbops = &smart210_lcd_ops;
//lcd_info->screen_base = ; /*虚拟基地址*/
lcd_info->screen_size = * * ;
lcd_info->pseudo_palette = pseudo_palette; //调色板 /*硬件相关的操作*/
gpf0con = ioremap(0xE0200120, );
gpf1con = ioremap(0xE0200140, );
gpf2con = ioremap(0xE0200160, );
gpf3con = ioremap(0xE0200180, );
gpd0con = ioremap(0xE02000A0, );
gpd0dat = ioremap(0xE02000A4, ); *gpf0con = 0x22222222;
*gpf1con = 0x22222222;
*gpf2con = 0x22222222;
*gpf3con = 0x22222222;
*gpd0con |= <<;
*gpd0dat |= <<; lcd_clk = clk_get(NULL, "lcd");
if(IS_ERR(lcd_clk)) {
printk(KERN_ALERT"clk_get error\n");
return -EINVAL;
}
clk_enable(lcd_clk); DISPLAY_CONTROL = ioremap( 0xE0107008, );
lcd_reg = ioremap(0xF8000000, sizeof(struct lcd_regs));
VIDOSD0A = ioremap(0xF8000040, );
VIDOSD0B = ioremap(0xF8000044, );
VIDOSD0C = ioremap(0xF8000048, );
VIDW00ADD0B0 = ioremap(0xF80000A0 , );
VIDW00ADD1B0 = ioremap(0xF80000D0 , ); *DISPLAY_CONTROL |= ( << ); //显示路径,必须 /*
*vidcon0[28:26] 000 = WB interface and RGB interface
*vidcon0[18] 0
*vidcon0[13:6] 0x4 5分频
*vidcon0[4] 1 = Divided by CLKVAL_F
*vidcon0[2] 0 = HCLK 166.75 MHz
*vidcon0[1]:ENVID 0 = Disables the video output and display control signal
*vidcon0[0]:ENVID_F 0 = Disables the video output and display control signal.
*NOTE: Display On: ENVID and ENVID_F are set to “1”.
Direct Off: ENVID and ENVID_F are set to “0” simultaneously.
Per Frame Off: ENVID_F is set to “0” and ENVID is set to “1”.
*/
lcd_reg->VIDCON0 &= ~(( << ) | ( << ) | (0xff << ) | ( << ));
lcd_reg->VIDCON0 |= (0x4 << ) | ( << ); /*
*vidcon1[6] IHSYNC 1 = 反转 根据芯片手册和lcd手册
*vidcon1[5] IVSYNC 1 = 反转
*/
lcd_reg->VIDCON1 &= ~(<<); /* 在vclk的下降沿获取数据 */
lcd_reg->VIDCON1 |= ( << ) | ( << ); /* 设置时序(需要修改) */
lcd_reg->VIDTCON0 = (VBPD << ) | (VFPD << ) | (VSPW << );
lcd_reg->VIDTCON1 = (HBPD << ) | (HFPD << ) | (HSPW << ); /*设置水平大小,垂直大小*/
lcd_reg->VIDTCON2 |= LINEVAL << ;
lcd_reg->VIDTCON2 |= HOZVAL << ; /*
*WSWP_F [15] :1 = Swap Enable(为什么要使能),,能够解决掉重影问题
*BPPMODE_F [5:2] 0xb = 24bpp
*ENWIN_F [0] 1 Enables/ disables video output and logic immediately.
*/
lcd_reg->WINCON0 |= << ;
lcd_reg->WINCON0 &= ~(0xf << );
lcd_reg->WINCON0 |= 0xb << | << ; /*窗口0 指定左上方,右下方像素的水平屏幕坐标*/
*VIDOSD0A |= (LeftTopX_F << ) | (LeftTopY_F << );
*VIDOSD0B |= (RightBotX_F << ) | (RightBotX_F << );
*VIDOSD0C |= ((LINEVAL + ) * (HOZVAL + )); /*分配显存*/
lcd_info->screen_base = dma_alloc_writecombine(NULL, lcd_info->fix.smem_len, (dma_addr_t *)&(lcd_info->fix.smem_start), GFP_KERNEL);
*VIDW00ADD0B0 = lcd_info->fix.smem_start; //显存的起始地址
*VIDW00ADD1B0 = lcd_info->fix.smem_start + lcd_info->fix.smem_len;//显存的结束地址 lcd_reg->SHADOWCON |= 0x1; //我们使用的是 Window0,所有需要使能 DMA 通道 0 /* LCD控制器开启 */
lcd_reg->VIDCON0 |= 0x3;
lcd_reg->WINCON0 |= 0x1; /*注册*/
register_framebuffer(lcd_info);
return ;
} static void __exit my_lcd_exit(void)
{
unregister_framebuffer(lcd_info);
dma_free_writecombine(NULL, lcd_info->fix.smem_len, &(lcd_info->fix.smem_start), GFP_KERNEL);
iounmap(gpf0con);
iounmap(gpf1con);
iounmap(gpf2con);
iounmap(gpf3con);
iounmap(gpd0con);
iounmap(gpd0dat);
iounmap(lcd_reg);
iounmap(VIDOSD0A);
iounmap(VIDOSD0B);
iounmap(VIDOSD0C);
iounmap(VIDW00ADD0B0);
iounmap(VIDW00ADD1B0);
framebuffer_release(lcd_info);
} MODULE_LICENSE("GPL");
module_init(my_lcd_init);
module_exit(my_lcd_exit);

lcd驱动实例:

s5pv210 lcd裸机分析网址:

http://blog.csdn.net/a158337/article/details/39802159

Smart210学习-----lcd驱动的更多相关文章

  1. Linux学习: LCD驱动

    一.LCD驱动框架: 1.分配一个fb_info结构体:s3c_lcd = framebuffer_alloc(0,NULL); 2.设置fb_info(s3c_lcd): ID.固定参数.可变参数. ...

  2. LCD驱动学习笔记

    通过这几天的学习发现驱动的框架感觉都差不多,一般分为以下几个步骤: 分配一个结构体 struct x *x = amlloc(); 设置结构体的参数 硬件寄存器 file_operations 注册 ...

  3. 嵌入式Linux驱动学习之路(十八)LCD驱动

    驱动代码: /************************************************************************* > File Name: lcd ...

  4. FL2440驱动添加(3)LCD驱动添加学习笔记

    FL2440 LCD内置控制器,320*240 TFT型LCD. 自我理解总结的两种添加驱动模式: 非platform方式添加驱动: 加载驱动: 1,硬件初始化,申请内存,并作地址映射 2,分配设备号 ...

  5. AM335x(TQ335x)学习笔记——LCD驱动移植

    TI的LCD控制器驱动是非常完善的,共通的地方已经由驱动封装好了,与按键一样,我们可以通过DTS配置完成LCD的显示.下面,我们来讨论下使用DTS方式配置内核完成LCD驱动的思路. (1)初步分析 由 ...

  6. LCD驱动的学习

    简介: LCD是基于液晶的. LCD(liquid crystal display)按驱动方式分类可以分为静态驱动,简单矩阵驱动,主动矩阵驱动.其中,简单矩阵又可以分为扭转向列型(TN)和超转向列型( ...

  7. S3C2440 LCD驱动(FrameBuffer)实例开发<一>(转)

    1. 背景知识 在多媒体的推动下,彩色LCD越来越多地应用到嵌入式系统中,PDA和手机等大多都采用LCD作为显示器材,因此学习LCD的应用很有实际意义! LCD工作的硬件需求:要使一块LCD正常的显示 ...

  8. sc7731 Android 5.1 LCD驱动简明笔记之三

    此篇笔记基于sc7731 - android 5.1,对lcd的gralloc库做一个简明笔记. 第一部分 调用gralloc.sc8830.so所谓的Gralloc模块,它就是一个模块,一个操作ke ...

  9. sc7731 Android 5.1 LCD驱动简明笔记之二

    此篇笔记基于sc7731 - android 5.1,对lcd的framebuffer做一个简明笔记. 一共分为两大部分:第一部分,关于LCD的硬件方面的:第二部分,关于lcd核心处理(framebu ...

随机推荐

  1. 20145236 《Java程序设计》实验一实验报告

    北京电子科技学院(BESTI)实验报告 课程:Java程序设计 班级:1452 指导教师:娄嘉鹏 实验日期:2016.04.08 实验名称:Java开发环境的熟悉(Linux + Eclipse) 实 ...

  2. JDE910笔记2--OMW项目建立及简单使用

    1.打开JDE的OBJECT MANAGEMENT WORKBENCH.在工作区中选择ADD,建立项目并选择OMW PROJECT,添加相关信息,如下图所示 其中,ProjectID可以对应不同的数据 ...

  3. ORACLE 日期比较

    oracle sql日期比较:在今天之前: select * from up_date where update < to_date('2007-09-07 00:00:00','yyyy-mm ...

  4. vsftp 配置

    安装和基本配置网上很多文章,但他们的最终效果不是我想要的: 我想要的是,ftp上传的文件用户可以通过apache的http服务访问,也就是ftp上传的文件可以通过浏览器访问,并且可以通过ftp客户端修 ...

  5. elasticsearch插件之一:kibana

    介绍: 要说kibana,就不得不先说一下logstash.这里呢,先要讲个故事.故事是开头是这样的,Logstash早期曾经自带了一个特别简单的logstash-web用来查看ES中的数据,其功能太 ...

  6. 设置groupBox背景透明

    步骤:属性-BackColor-WEB面板-Transparent

  7. 编码为multipart/form-data自定义类型(包括文件)如何自动绑定到webapi的action的参数里

    application/x-www-form-urlencoded与 multipart/form-data: Fom表单中如果没有type=file的控件,用默认的application/x-www ...

  8. 由于lightdm.conf 错误无法进入ubuntu 的办法

    由于自己向默认登录GNOME桌面,所以修改了lightdm,由于参数错误,结果无法启动桌面? 这是需要进入shell界面: 1.选择cancel ,如果虚拟机下无法点击cancel按钮,可以使用快捷键 ...

  9. jQuery Ajax之load()方法

    jQuery对Ajax操作进行了封装,在jQuery中$.ajax()方法属于最底层的方法,第2层是load().$.get()和$.post()方法,第3层是$.getScript()和$.getJ ...

  10. 使用icon替换你的网页图标(转)

    第一次使用 Font Awesome 发现相当的爽呀!它的图标很全,能够帮你节约时间去找图片.下面就来一起学习吧: 1: 去官方网站下载解压 http://fontawesome.io/ 2: 解压后 ...