LCD设备驱动

  • 一、LCD硬件原理

  利用液晶制成的显示器LCD,依据驱动方式可分为静态驱动、简单矩阵驱动以及主动矩阵驱动3中。其中,简单矩阵型又可再区分扭转向列型(TN)和超扭转式向列型(STN)两种,而主动矩阵型则以薄膜式晶体管型(TFT)为主流。

  一块LCD屏显示图像不但需要LCD驱动器,还需要有相应的LCD控制器。通常LCD驱动器会议COF/COG与LCD玻璃基板制作在一起,而LCD控制则由外部电路来实现。许多MCU北部直接集成了LCD控制,通过LCD控制器可以方便地控制STN和TFT屏。

  下图给出了LCD控制器中应该设置的TFT屏的参数,其中的上边界和下边界即为帧切换的回归时间,左边界和右便捷即为行切换的回归时间,水平同步和垂直同步分别是行和帧同步本身需要的时间。xres和yres则分别是屏幕的水平和垂直分辨率,常见的嵌入式设备的LCD分辨率主要为320*240、640*480等。

二、帧缓冲

  2.1 帧缓冲的概念

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

  帧缓冲设备为标准的字符设备,主设备号位29,对应/dev/fbn设备文件。帧缓冲驱动的应用非常广泛,在Linux的桌面系统中,X Window服务器就是利用帧缓冲进行窗口的绘制,嵌入式系统中的Qt/Embedded等图形用户界面环境也基于帧缓冲而设计。

  2.2 显示缓冲区与显示点

  在帧缓冲设备中,对屏幕现实点的操作通过读写显示缓冲区来完成,在不同的色彩模式下,显示缓冲区和屏幕上的现实点有不同的对应关系,下表分别给出了16级灰度、8位色和16位情况下显示缓冲区与显示点的对应关系。

16级灰度显示缓冲区与显示点的对应关系

31~28 27~24 23~20 19~16 15~12 11~8 7~4 3~0
0x00   点7   点6   点5   点4   点3   点2   点1   点0  
0x04 点15   点14   点13   点12   点11   点10   点9   点8  
... ... ... ... ... ... ... ... ...
                 
                 
                 

8位色时显示缓冲区与显示点的对应关系

  RGB       BGR
  7~5     4~2     1~0     7~5     4~2     1~0  
    R     G     B      

16位色时显示缓冲区与显示点的对应关系

  位     15~11     10~5     4~0  
  RGB565         R         G     B
  RGB555       R         G     B

2.3 Linux帧缓冲相关数据结构与函数

2.3.1 fb_info结构体

struct fb_info {  int node;  int flags;  struct mutex lock;  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 fb_vediomode      *mode;   /* 目前的vedio模式 */  struct list_head       modelist;

#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         *fops;  /* fb_ops,帧缓冲操作 */  struct device         *device; /* 父设备 */  struct device         *dev;   /* fb设备 */  int class_flag;             /* 私有sysfs标志 */#ifdef CONFIG_FB_TILEBLITING  struct fb_tile_ops      *tileops; /* 土块Blitting */#endif

  char __iomem         *screen_base;  unsigned long         screen_size;  void              *pseudo_palette;#define FBINFO_STATE_RUNNING  0#define FBINFO_STATE_SUSPENDED  1  u32               state;  void              *fbcon_ptr;  void              *par;};

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

2.3.2 fb_ops结构体

  FBI的成员变量fbops为指向底层操作的函数指针,这些函数是需要驱动程序驱动程序人员编写的,其定义如下:

struct fb_ops {  struct module *owner;    /* 打开/关闭函数 */  int (*fb_open) (struct fb_info *info, int user);  int (*fb_close) (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);   /* 矩形填充 */  int (*fb_fillract) (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空闲(可选) */  void (*fb_sync) (struct fb_info *info);

  /* fb特定的ioctl(可选) */  void (*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_get_state) (struct fb_info *info, struct fb_blit_caps *caps, struct fb_var_screeninfo *var);};

  fb_ops的fb_check_var()成员函数用于检查可以修改的屏幕参数并调整到合适的值,而fb_set_par()则是的用户设置的屏幕参数在硬件上有效。

2.3.3 fb_var_screeninfo和fb_fix_screeninfo结构体

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

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;  /* 每像素位数,BPP */  u32  qrayscale;      /* 非0时指灰度 */    /* fb缓存的R/G/B位域 */  struct fb_bitfield red;  struct fb_bitfield green;  struct fb_bitfield blue;  struct fb_bitfield transp;  /* 透明度 */  
  /* != 0 非标准像素格式 */  u32  nonstd;  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[5];    /* 保留 */
};

fb_fix_screeninfo结构体

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

fb_bitfield结构体

struct fb_bitfield {  __u32 offset;  /* 位域偏移 */  __u32 length;  /* 位域长度 */  __u32 msb_right; /* !=0;MSB在右边 */};

fb_cmap结构体

fb_cmap结构体记录设备无关的颜色表信息,用户空间可以通过ioctl()的FBIOGETCMAP和FBIOPUTCMAP命令读取或设定颜色表。

struct fb_cmap{  u32 start;    /* 第一个元素入口 */  u32 len;     /* 元素数量 */  /* R,G,B 透明度 */  u16 *red;  u16 *green;  u16 *blue;  u16 *transp;};

2.3.6 文件操作结构体

struct file_operations fb_ops = {  .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中被统一实现,一般不需要由驱动工程师在编写。

2.3.7注册和主线帧缓冲设备

  Linux内核提供了register_framebuffer()和unregister_framebuffer()函数分别注册和注销帧缓冲设备,这两个函数渡劫否FBI指针为参数。

int register_framebuffer(struct fb_info *info);int unregister_framebuffer(struct fb_info *info);

三、Linux帧缓冲设备驱动结构

  Linux帧缓冲设备驱动的主要结构,帧缓冲设备提供给用户空间的file_operations结构由fbmem.c中的file_operation提供,而特定帧缓冲设别fb_info结构体的注册、注销以及其中成员的维护,尤其是fb_ops中成员函数的实现则由对应的xxxfb.c文件实现,fb_ops中的成员函数最终会操作LCD控制器硬件寄存器。

四、帧缓冲设备驱动的模块加载与卸载函数

  在帧缓冲设备的模块加载函数中,应该完成如下4个工作:

1、申请FBI结构体的内存空间,初始化FBI结构体中固定和可变的屏幕参数,即填充FBI中的fb_var_screeninfo和fb_fix_screeninfo成员。

2、根据具体的LCD屏幕的特点,完成LCD控制器硬件的初始化。

3、申请帧缓冲设备的显示缓冲区空间。

4、注册帧缓冲设备。

在适用平台驱动的情况下,释放FBI结构体内存,关闭LCD、释放显示缓冲区以及注销帧缓冲区设备的工作也移交到平台驱动的移除函数中完成。

static struct platform_device {  .proce = xxxfb_probe,  .remove = xxxfb_remove,  .suspend = xxxfb_suspend,  .resume = xxxfn_resume,  .driver = {    .name = "xxx-lcd",    .owner = THIS_MODULE,  }};

/* 平台驱动探测函数 */static int __init xxxfb_probe(...){  struct fb_info *info;  info = framebuffer_alloc(...);    info->screen_var = xxxfb_var;  info->fix = xxxfb->fix;

  alloc_dis_buffer(...);  lcd_init(...);  xxxfb_check_var(&info->var,info);

  if(register_framebuffer(info) < 0)  {    return -EINVAL;  }    

  return 0;}

static void __exit xxxfb_remove(...){
  struct fb_info *info = dev_get_drv_data(dev);  if(info)  {    unregister_framebuffer(info);    dealloc_dis_buffer(...);    framebuffer_release(info);  }

  return 0;}

static int __init xxxfb_init(void){  return platfrom_driver_register(&xxxfb_driver);}

static void __exit xxxfb_exit(void){  platform_driver_unregister(&xxxfb_driver);}

五、帧缓冲设备显示缓冲区的申请与释放

  在嵌入式系统中,一种常见的方式是直接在RAM空间中分配一段显示缓冲区,典型的结构如下:

  writecombining意味着写合并,它允许写入的数据被合并,兵临时保存在写合并缓冲区中,直到进行一次brust传输而不再需要多次single传输,通过dma_alloc_writeconbine()分配的显示缓冲区不会出现cache一致性问题,这一点类似于dma_alloc_coherent()。

static int __init xxxfb_map_video_memory(struct xxxfb_info *fbi){  fbi->map_size = PAGE_ALIGN(fbi->fb->fix.smem_len+PAGE_SIZE);  fbi->map_cpu = dma_alloc_writecombine(fbi->dev,fbi->map_size,&fbi->map_dma,GFP_KERNEL);

  fbi->map_size = fbi->fb->fix.smem_len;   if(fbi->mem_cpu)  {    memset(fbi->mem_cpu,0xf0,fbi->map_size);    fbi->screen_dma = fbi->map_dma;    fbi->fb->screen_base = fbi->map_cpu;    fbi->fb->fix.smem_start = fbi->screen_dma;  }

  return fbi->mem_cpu?0:-ENOMEM;}

static inline void xxxfb_unmap_vedio_memory(struct s3c2410fb_info *fbi){  dma_free_writeconbine(fbi->dev, fbi->map_size, fbi->map_cpu, fbi->map_dma);}

六、帧缓冲设备的参数设置

  6.1 定时参数

  FBI结构体可变参数var中的left_margin、right_margin、upper_margin、lower_margin、hsync_len和vsync_len直接查LCD的数据手册就可以得到。 

  6.2 像素时钟

  FBI可变参数var中的pixclock意味着像素时钟。

  6.3 颜色位域

  6.4 固定参数

  FBI固定参数fix中的smem_start指示帧缓冲设备显示缓冲区的首地址,smem_len为帧缓冲设备显示缓冲区的大小。

  smem_len = max_xres*max_yres*max_bpp。

七、帧缓冲设备驱动的fb_ops成员函数

  FBI中的fb_ops是使得帧缓冲设备工作所需函数的集合,他们最终于LCD控制器硬件打交道。

  fb_check_var()用于调整可变参数,并修正硬件所支持的值;fb_set_par()则根据屏幕参数设置具体读写LCD控制器的寄存器以使得LCD控制器进入相应的工作状态。对于fb_ops中的fb_fillrect()、fb_copyarea()和fb_imageblit()成员函数,通常直接使用对应的通用的cfb_fillrect()、cfb_copyarea()和cfb_imageblit()函数即可。cfb_fillrect()函数定义在drivers/vedio/cfbfill.c文件中。cfb_copyarea()函数定义在drivers/video/cfbcopyarea.c文件中。cfb_imageblit()函数定义在drivers/video/cfbimgblt.c文件中。

  fb_ops中的fb_setcolreg()成员函数实现伪颜色表(针对FB_VISUAL_TRUECOLOR、FB_VISUAL_DIRECTCOLOR模式)和颜色表的填充。

static int xxxfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info){  struct xxxfb_info *fbi = info->par;  unsigned int val;    switch(fbi->fb->fix.visual)  {  case FB_VISUAL_TRUECOLOR:    /* 真彩色,设置为伪颜色表 */    if(regno < 16)    {      u32 *pal = fbi->fb->pseudo_palette;      val = chan_to_field(red,&fbi->fb->var.red);      val |= chan_to_field(green,&fbi->fb->var.green);      val |= chan_to_field(blue,&fbi->fb->var.blue);

      pal[reqno] = val;    }    break;

  case FB_VISUAL_PSEUDOCOLOR:    if(regno < 256)    {      val = (red >> 0) & 0xf800;      val |= (green >> 5) & 0x7a0;      val |= (blue >> 11) & 0x1f;      writel(val,XXX_TFTPAL(regno));      schedule_palette_update(fbi,regno,val);    }    break;  }

  return 0;}

八、LCD设备驱动的读写、mmap和ioctl函数

  虽然帧缓冲设备的file_operations中的成员函数,即文件操作函数已经由内核在fbmem.c文件中实现,一般不再需要驱动工程师修改,但分析这些函数对于巩固自读设备驱动的指示以及加深对真缓冲设备驱动的理解是大有脾益的。

static ssize_t fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos){  unsigned long p = *ppos;

  struct inode *inode = file->f_path.dentry->d_inode;  int fbidx = iminor(inode);    struct fb_info *info = registered_fb(fbidx);  u32 *buffer, *dst;  u32 __iomem *src;  int c,i,cnt = 0, err = 0;  unsigned long total_size;  ......  buffer = kmalloc((count > PAGE_SIZE)?PAGE_SIZE:count,GFP_KERNEL);  if(!buffer)  {    return -ENOMEM;  }  src = (u32 __iomem *)(info->screen_base + p);  if()}

九、帧缓冲设备的用户空间

通过/dev/dbn,应用程序可进行的针对真缓冲设备的操作主要有如下几种:

  • 读/写dev/dbn:相当于读/写屏幕的缓冲区,例如cp /dev/fb0 tmp命令可将当前屏幕上的内容复制到一个文件中,而命令cp tmp>/dev/fb0 则将图形文件tmp显示在屏幕上。
  • 映射操作,对于帧缓冲设备,可通过mmap()应设操作将屏幕缓冲区的物理地址映射到用户空间的一段虚拟地址中,之后用户就可以通过读/写这段虚拟地址访问缓冲区,在屏幕绘图了。而且若干个进程可以映射到同一个娴熟缓冲区。实际上,使用帧缓冲设备的应用程序都是通过映射操作来显示图形的。
  • I/O控制:对于帧缓冲设备,对设备文件的ioctl()操作可读取/设置显示设备及屏幕的参数,分辨率、显示颜色数、屏幕大小等。

如图18.6所示,在应用程序中,操作/dev/fbn的一般步骤如下:

1、打开/dev/fbn设备文件

2、用ioctl()操作区的当前显示屏幕的参数,如分辨率、每个像素点的比特殊和偏移。根据屏幕参数可计算屏幕缓冲区的大小。

3、将屏幕缓冲区映射到用户空间。

4、映射后就可以直接读/写屏幕缓冲区,进行绘图和图片显示了。

#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <fcntl.h>#include <linux/fb.h>#include <sys/mman.h>

int main(void){  int fbfd = 0;  struct fb_var_screeninfo vinfo;  char *fbp = 0;  

  fbfd = open("/dev/fb0",O_RDWR);  if(fnfd == 0)  {    printf("Error:cannot open framebuffer device.\n");    return 1;  }  ptintf("The frambuffer device was opened successfully.\n");

  if(ioctl(fbfd,FBIOGET_VSCEENINFO,&vinfo))  {
    printf("Error: reading variable information.\n");      return 1;  }    printf("%dx%d,%dbpp\n",vinfo.xres,vinfo.yres,vinfo.bits_per_pixel);  if(vinfo.bits_per_pixel != 16)  {    printf("Error: not supported bits_per_pixel,it onlu supports 16 bit color.\n");    return 1;  }

  fbp = (char *)mmap(0,screensize,PROT_READ|PROT_WRITE,MAP_SHARD,fbfd,0);  if((int)fbp == -1)  {    printf("Error: failed to map framebuffer device to memory.\n");    return 4;  }  printf("The framebuffer device was mapped to memory successfully.\n");

  for(i = 0;i < 3;i++)  {    for(y = i*(vinfo.yres/3);y < (i+1)*(vinfo/yres/3);y++)    {      for(x = 0;x < vinfo.xres;x++)      {        long location = x*2 + y * vinfo.res*2;        int r = 0,g = 0, b = 0;        if(i == 0)        {          r = ((x*1.0)/vinfo.xres)*32;        }        if(i == 1)        {          g = ((x*1.0)/vinfo.xres)*64;        }        if(i == 2)        {          b = ((x*1.0)/vinfo.xres)*32;        }        rgb = (r<<11)|(q<<5)|b;        *((unsigned short *)(fbp + location)) = rgb;      }    }  }  munmap(fbp,screensize);  close(fbfd);  return 0;}

总结

  帧缓冲设备是一种典型的字符设备,他统一了显存,将显示缓冲区直接映射到用户空间。真缓冲设备驱动file_operations中VFS接口函数由fbmem.c文件统一实现。这样,驱动工程师的工作重点监视实现针对特定设备的fb_ops中的fb_ops的成员函数。另外,理解并能灵活地修改fb_info中的varhe fix参数非常关键。fb_info中的参数直接和LCD控制器的硬件设备以及LCD屏幕对应。

  在用户空间,应用程序直接按照预先设置的R/G/B位数和偏移写经过mmap()映射后的显示缓冲区就可实现图形的显示,省去了内存从用户空间到内核空间的复制过程。

时间: 2024-10-14 18:20:50

LCD设备驱动的相关文章

《Linux设备驱动开发详解(第3版)》海量更新总结

本博实时更新<Linux设备驱动开发详解(第3版)>的最新进展. 2015.2.26 几乎完成初稿. [F]是修正或升级:[N]是新增知识点:[D]是删除的内容 第1章 <Linux设备驱动概述及开发环境构建>[D]删除关于LDD6410开发板的介绍[F]更新新的Ubuntu虚拟机[N]添加关于QEMU模拟vexpress板的描述 第2章 <驱动设计的硬件基础> [N]增加关于SoC的介绍:[N]增加关于eFuse的内容:[D]删除ISA总线的内容了:[N]增加关于SP

《Linux设备驱动开发具体解释(第3版)》进展同步更新

本博实时更新<Linux设备驱动开发具体解释(第3版)>的最新进展. 2015.2.26 差点儿完毕初稿. 本书已经rebase到开发中的Linux 4.0内核,案例多数基于多核CORTEX-A9平台. [F]是修正或升级:[N]是新增知识点:[D]是删除的内容 第1章 <Linux设备驱动概述及开发环境构建>[D]删除关于LDD6410开发板的介绍[F]更新新的Ubuntu虚拟机[N]加入关于QEMU模拟vexpress板的描写叙述 第2章 <驱动设计的硬件基础> [

LCD驱动分析(一)字符设备驱动框架分析

LCD驱动也是字符设备驱动,也遵循字符设备驱动的流程: a. 分配主设备号 b. 构建file_operations结构体中的open,write,read...等函数 c. 调用register_chrdev()函数注册字符设备 d. 调用class_register()注册类 e. 调用device_create()创建设备,linux会在sysfs目录下自动创建字符设备. 以上的步骤同样适用于分析输入子系统,只不过上面的各个步骤可能分散在不同的文件与函数中完成. 1.linux/drive

linux设备驱动之platform平台总线工作原理(二)

5.5.5.platform平台总线工作原理2 5.5.5.1.平台总线体系的工作流程 (1)第一步:linux内核系统启动时在bus系统中注册platform. 1.什么叫做bus系统,操作系统中有一套管理总线的体系,内核里有一个子系统,就叫做总线子系统.就是内核来管理总线的.bus系统在内核启动时建立起来,比platform建立的时间还要早,bus系统的是由内核编写的人提供的,我们将来分析代码的时候不需要去分析他.在bus系统起来以后,就需要在bus系统中注册这个platform平台总线的b

字符设备驱动、平台设备驱动、设备驱动模型、sysfs的关系

Linux驱动开发的童鞋们来膜拜吧:-)  学习Linux设备驱动开发的过程中自然会遇到字符设备驱动.平台设备驱动.设备驱动模型和sysfs等相关概念和技术.对于初学者来说会非常困惑,甚至对Linux有一定基础的工程师而言,能够较好理解这些相关技术也相对不错了.要深刻理解其中的原理需要非常熟悉设备驱动相关的框架和模型代码.网络上有关这些技术的文章不少,但多是对其中的某一点进行阐述,很难找到对这些技术进行比较和关联的分析.对于开发者而言,能够熟悉某一点并分享出来已很难得,但对于专注传授技术和经验给

Linux设备驱动开发基础

1.驱动概述和开发环境搭建 1.1驱动设备的作用 对设备驱动最通俗的解释就是"驱动硬件设备行动".驱动与底层硬件直接打交道,按照硬件设备的具体工作方式,读写设备的寄存器,完成设备的轮训.中断处理.DMA通信,进行物理内存向虚拟内存的映射等,最终让通信设备能收发数据,让显示设备能显示文字和画面,让存储设备能记录文件和数据. 由此可见,设备驱动充当了硬件和应用软件之间的纽带,他使得应用软件只需要调用系统软件的应用编程接口(API)就可让硬件去完成要求的工作.在系统中没有操作系统的情况下,工

LCD设备驱动程序

LCD是Liquid  Crystal  Display的简称,也就是经常所说的液晶显示器 LCD能够支持彩色图像的显示和视频的播放,是一种非常重要的输出设备 Framebuffer 是Linux系统为显示设备提供的一个接口,它将显示缓冲区抽象,屏蔽图像硬件的底层差异,允许上层应用程序在图形模式下直接对显示缓冲区进行操作 Framebuffer又叫帧缓冲,是Linux为操作显示设备提供的一个用户接口.用户应用程序可以通过Framebuffer透明地访问不同类型的显示设备. 从这个方面来说,Fra

[kernel]字符设备驱动、平台设备驱动、设备驱动模型、sysfs几者之间的比较和关联

转自:http://www.2cto.com/kf/201510/444943.html Linux驱动开发经验总结,绝对干货! 学习Linux设备驱动开发的过程中自然会遇到字符设备驱动.平台设备驱动.设备驱动模型和sysfs等相关概念和技术.对于初学者来说会非常困惑,甚至对Linux有一定基础的工程师而言,能够较好理解这些相关技术也相对不错了.要深刻理解其中的原理需要非常熟悉设备驱动相关的框架和模型代码.网络上有关这些技术的文章不少,但多是对其中的某一点进行阐述,很难找到对这些技术进行比较和关

platform设备驱动全透析

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://21cnbao.blog.51cto.com/109393/337609 1.1 platform总线.设备与驱动 在Linux 2.6的设备驱动模型中,关心总线.设备和驱动这3个实体,总线将设备和驱动绑定.在系统每注册一个设备的时候,会寻找与之匹配的驱动:相反的,在系统每注册一个驱动的时候,会寻找与之匹配的设备,而匹配由总线完成. 一个现实的Linux设备和驱动通常都需要挂接在