一、LCD驱动程序架构

1.裸机驱动代码分析

①LCD初始化:控制器初始化,端口初始化,指明帧缓冲

②LCD图形显示:将图形数据写入帧缓冲

  1. void lcd_init()
  2. {
  3. lcd_port_init();     //初始化gpdcon和gpccon初始化
  4. lcd_control_init();   //时序初始化和帧缓冲初始化
  5. //打开LCD电源
  6. GPGCON |= 0b11<<8;
  7. LCDCON5 |= (1<<3);
  8. LCDCON1 |= 1;
  9. }

2.帧缓冲体验

帧缓冲:内存中的一段区域,通过对内存的修改。LCD控制器从内存中获取数据,自动的控制LCD的显示。

  1. # cat tq2440.bin > /dev/fb0

将图片显示到lcd。



3.帧缓冲架构

/dev/fb0就是帧缓冲,字符设备

fbmem_init():

  1. static int __init
  2. fbmem_init(void)
  3. {
  4. proc_create("fb", 0, NULL, &fb_proc_fops);
  5. if (register_chrdev(FB_MAJOR,"fb",&fb_fops))                                                    //注册设备文件,注册帧缓冲,fp_fops是操作函数集
  6. printk("unable to get major %d for fb devs\n", FB_MAJOR);
  7. fb_class = class_create(THIS_MODULE, "graphics");
  8. if (IS_ERR(fb_class)) {
  9. printk(KERN_WARNING "Unable to create fb class; errno = %ld\n", PTR_ERR(fb_class));
  10. fb_class = NULL;
  11. }
  12. return 0;
  13. }

fb_ops:

  1. static const struct file_operations fb_fops = {
  2. .owner =    THIS_MODULE,
  3. .read =        fb_read,                                        //写入
  4. .write =    fb_write,
  5. .unlocked_ioctl = fb_ioctl,
  6. #ifdef CONFIG_COMPAT
  7. .compat_ioctl = fb_compat_ioctl,
  8. #endif
  9. .mmap =        fb_mmap,
  10. .open =        fb_open,
  11. .release =    fb_release,
  12. #ifdef HAVE_ARCH_FB_UNMAPPED_AREA
  13. .get_unmapped_area = get_fb_unmapped_area,
  14. #endif
  15. #ifdef CONFIG_FB_DEFERRED_IO
  16. .fsync =    fb_deferred_io_fsync,
  17. #endif
  18. };

fb_write:

  1. static ssize_t
  2. fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
  3. {
  4. unsigned long p = *ppos;
  5. struct inode *inode = file->f_path.dentry->d_inode;
  6. int fbidx = iminor(inode);
  7. struct fb_info *info = registered_fb[fbidx];
  8. u32 *buffer, *src;
  9. u32 __iomem *dst;
  10. int c, i, cnt = 0, err = 0;
  11. unsigned long total_size;
  12. if (!info || !info->screen_base)
  13. return -ENODEV;
  14. if (info->state != FBINFO_STATE_RUNNING)
  15. return -EPERM;
  16. if (info->fbops->fb_write)
  17. return info->fbops->fb_write(info, buf, count, ppos);
  18. total_size = info->screen_size;
  19. if (total_size == 0)
  20. total_size = info->fix.smem_len;
  21. if (p > total_size)
  22. return -EFBIG;
  23. if (count > total_size) {
  24. err = -EFBIG;
  25. count = total_size;
  26. }
  27. if (count + p > total_size) {
  28. .........各种info
  29. }



info结构:

  1. struct fb_info {
  2. int node;
  3. int flags;
  4. struct mutex lock;                                //控制io操作锁
  5. struct fb_var_screeninfo var;/*LCD可变参数*/
  6. struct fb_fix_screeninfo fix;/*LCD固定参数*/
  7. struct fb_monspecs monspecs; /*LCD显示器标准*/
  8. struct work_struct queue; /*帧缓冲事件队列*/
  9. struct fb_pixmap pixmap; /*图像硬件mapper*/
  10. struct fb_pixmap sprite; /*光标硬件mapper*/
  11. struct fb_cmap cmap; /*当前的颜色表*/
  12. struct fb_videomode *mode; /*当前的显示模式*/
  13. #ifdef CONFIG_FB_BACKLIGHT
  14. struct backlight_device *bl_dev;/*对应的背光设备*/
  15. struct mutex bl_curve_mutex;
  16. u8 bl_curve[FB_BACKLIGHT_LEVELS];/*背光调整*/
  17. #endif
  18. #ifdef CONFIG_FB_DEFERRED_IO
  19. struct delayed_work deferred_work;
  20. struct fb_deferred_io *fbdefio;
  21. #endif
  22. struct fb_ops *fbops; /*对底层硬件操作的函数指针*/
  23. struct device *device;
  24. struct device *dev; /*fb设备*/
  25. int class_flag;
  26. #ifdef CONFIG_FB_TILEBLITTING
  27. struct fb_tile_ops *tileops; /*图块Blitting*/
  28. #endif
  29. char __iomem *screen_base; /*虚拟基地址*/
  30. unsigned long screen_size; /*LCD IO映射的虚拟内存大小*/
  31. void *pseudo_palette; /*伪16色颜色表*/
  32. #define FBINFO_STATE_RUNNING 0
  33. #define FBINFO_STATE_SUSPENDED 1
  34. u32 state; /*LCD的挂起或恢复状态*/
  35. void *fbcon_par;
  36. void *par;
  37. };

主要是fb_var_screeninfo、fb_fix_screeninfo、fb_ops三个结构体:

struct fb_var_screeninfo:主要记录用户可以修改的控制器的参数。

  1. struct fb_var_screeninfo {
  2. __u32 xres;            /* visible resolution        */
  3. __u32 yres;
  4. __u32 xres_virtual;        /* virtual resolution        */
  5. __u32 yres_virtual;
  6. __u32 xoffset;            /* offset from virtual to visible */
  7. __u32 yoffset;            /* resolution            */
  8. __u32 bits_per_pixel;        /* guess what            */每个像素的位数即BPP
  9. __u32 grayscale;        /* != 0 Graylevels instead of colors */
  10. struct fb_bitfield red;        /* bitfield in fb mem if true color, */
  11. struct fb_bitfield green;    /* else only length is significant */
  12. struct fb_bitfield blue;
  13. struct fb_bitfield transp;    /* transparency            */
  14. __u32 nonstd;            /* != 0 Non standard pixel format */
  15. __u32 activate;            /* see FB_ACTIVATE_*        */
  16. __u32 height;            /* height of picture in mm */
  17. __u32 width;            /* width of picture in mm */
  18. __u32 accel_flags;        /* (OBSOLETE) see fb_info.flags */
  19. /* Timing: All values in pixclocks, except pixclock (of course) */
  20. __u32 pixclock;            /* pixel clock in ps (pico seconds) */
  21. __u32 left_margin;        /* time from sync to picture    */
  22. __u32 right_margin;        /* time from picture to sync    */
  23. __u32 upper_margin;        /* time from sync to picture    */
  24. __u32 lower_margin;
  25. __u32 hsync_len;        /* length of horizontal sync    */
  26. __u32 vsync_len;        /* length of vertical sync    */
  27. __u32 sync;            /* see FB_SYNC_*        */
  28. __u32 vmode;            /* see FB_VMODE_*        */
  29. __u32 rotate;            /* angle we rotate counter clockwise */
  30. __u32 reserved[5];        /* Reserved for future compatibility */
  31. };

fb_fix_screeninfo:主要记录用户不可以修改的控制器的参数

  1. struct fb_fix_screeninfo {
  2. char id[16];            /* identification string eg "TT Builtin" */
  3. unsigned long smem_start;    /* Start of frame buffer mem */
  4. /* (physical address) */
  5. __u32 smem_len;            /* Length of frame buffer mem */
  6. __u32 type;            /* see FB_TYPE_*        */
  7. __u32 type_aux;            /* Interleave for interleaved Planes */
  8. __u32 visual;            /* see FB_VISUAL_*        */
  9. __u16 xpanstep;            /* zero if no hardware panning */
  10. __u16 ypanstep;            /* zero if no hardware panning */
  11. __u16 ywrapstep;        /* zero if no hardware ywrap */
  12. __u32 line_length;        /* length of a line in bytes */
  13. unsigned long mmio_start;    /* Start of Memory Mapped I/O */
  14. /* (physical address) */
  15. __u32 mmio_len;            /* Length of Memory Mapped I/O */
  16. __u32 accel;            /* Indicate to driver which    */
  17. /* specific chip/card we have    */
  18. __u16 reserved[3];        /* Reserved for future compatibility */
  19. };

fb_ops:底层硬件操作的函数指针

  1. struct fb_ops {
  2. /* open/release and usage marking */
  3. struct module *owner;
  4. int (*fb_open)(struct fb_info *info, int user);
  5. int (*fb_release)(struct fb_info *info, int user);
  6. /* For framebuffers with strange non linear layouts or that do not
  7. * work with normal memory mapped access
  8. */
  9. ssize_t (*fb_read)(struct fb_info *info, char __user *buf,
  10. size_t count, loff_t *ppos);
  11. ssize_t (*fb_write)(struct fb_info *info, const char __user *buf,
  12. size_t count, loff_t *ppos);
  13. /* checks var and eventually tweaks it to something supported,
  14. * DO NOT MODIFY PAR */
  15. int (*fb_check_var)(struct fb_var_screeninfo *var, struct fb_info *info);
  16. /* set the video mode according to info->var */
  17. int (*fb_set_par)(struct fb_info *info);
  18. /* set color register */
  19. int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green,
  20. unsigned blue, unsigned transp, struct fb_info *info);
  21. /* set color registers in batch */
  22. int (*fb_setcmap)(struct fb_cmap *cmap, struct fb_info *info);
  23. /* blank display */
  24. int (*fb_blank)(int blank, struct fb_info *info);
  25. /* pan display */
  26. int (*fb_pan_display)(struct fb_var_screeninfo *var, struct fb_info *info);
  27. /* Draws a rectangle */
  28. void (*fb_fillrect) (struct fb_info *info, const struct fb_fillrect *rect);
  29. /* Copy data from area to another */
  30. void (*fb_copyarea) (struct fb_info *info, const struct fb_copyarea *region);
  31. /* Draws a image to the display */
  32. void (*fb_imageblit) (struct fb_info *info, const struct fb_image *image);
  33. /* Draws cursor */
  34. int (*fb_cursor) (struct fb_info *info, struct fb_cursor *cursor);
  35. /* Rotates the display */
  36. void (*fb_rotate)(struct fb_info *info, int angle);
  37. /* wait for blit idle, optional */
  38. int (*fb_sync)(struct fb_info *info);
  39. /* perform fb specific ioctl (optional) */
  40. int (*fb_ioctl)(struct fb_info *info, unsigned int cmd,
  41. unsigned long arg);
  42. /* Handle 32bit compat ioctl (optional) */
  43. int (*fb_compat_ioctl)(struct fb_info *info, unsigned cmd,
  44. unsigned long arg);
  45. /* perform fb specific mmap */
  46. int (*fb_mmap)(struct fb_info *info, struct vm_area_struct *vma);
  47. /* save current hardware state */
  48. void (*fb_save_state)(struct fb_info *info);
  49. /* restore saved state */
  50. void (*fb_restore_state)(struct fb_info *info);
  51. /* get capability given var */
  52. void (*fb_get_caps)(struct fb_info *info, struct fb_blit_caps *caps,
  53. struct fb_var_screeninfo *var);
  54. };

http://www.cnblogs.com/lishixian/articles/2999923.html



二、LCD驱动程序分析

s3c2410fb_init:

  1. int __init s3c2410fb_init(void)
  2. {
  3. int ret = platform_driver_register(&s3c2410fb_driver);                        //注册平台驱动设备
  4. if (ret == 0)
  5. ret = platform_driver_register(&s3c2412fb_driver);;
  6. return ret;
  7. }

s3c2410fb_driver:

  1. static struct platform_driver s3c2410fb_driver = {
  2. .probe        = s3c2410fb_probe,                                                //probe函数,里面调用了s3c24xxfb_probe
  3. .remove        = s3c2410fb_remove,
  4. .suspend    = s3c2410fb_suspend,
  5. .resume        = s3c2410fb_resume,
  6. .driver        = {
  7. .name    = "s3c2410-lcd",
  8. .owner    = THIS_MODULE,
  9. },
  10. };

s3c24xxfb_probe:

  1. static int __init s3c24xxfb_probe(struct platform_device *pdev,
  2. enum s3c_drv_type drv_type)
  3. {
  4. struct s3c2410fb_info *info;
  5. struct s3c2410fb_display *display;
  6. struct fb_info *fbinfo;
  7. struct s3c2410fb_mach_info *mach_info;
  8. struct resource *res;
  9. int ret;
  10. int irq;
  11. int i;
  12. int size;
  13. u32 lcdcon1;
  14. mach_info = pdev->dev.platform_data;
  15. if (mach_info == NULL) {
  16. dev_err(&pdev->dev,
  17. "no platform data for lcd, cannot attach\n");
  18. return -EINVAL;
  19. }
  20. if (mach_info->default_display >= mach_info->num_displays) {
  21. dev_err(&pdev->dev, "default is %d but only %d displays\n",
  22. mach_info->default_display, mach_info->num_displays);
  23. return -EINVAL;
  24. }
  25. display = mach_info->displays + mach_info->default_display;
  26. irq = platform_get_irq(pdev, 0);                                                       //获取中断号
  27. if (irq < 0) {
  28. dev_err(&pdev->dev, "no irq for device\n");
  29. return -ENOENT;
  30. }
  31. fbinfo = framebuffer_alloc(sizeof(struct s3c2410fb_info), &pdev->dev);                 //分配fb_info结构
  32. if (!fbinfo)
  33. return -ENOMEM;
  34. platform_set_drvdata(pdev, fbinfo);
  35. info = fbinfo->par;
  36. info->dev = &pdev->dev;
  37. info->drv_type = drv_type;
  38. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);                                   //获取寄存器地址
  39. if (res == NULL) {
  40. dev_err(&pdev->dev, "failed to get memory registers\n");
  41. ret = -ENXIO;
  42. goto dealloc_fb;
  43. }
  44. size = (res->end - res->start) + 1;
  45. info->mem = request_mem_region(res->start, size, pdev->name);
  46. if (info->mem == NULL) {
  47. dev_err(&pdev->dev, "failed to get memory region\n");
  48. ret = -ENOENT;
  49. goto dealloc_fb;
  50. }
  51. info->io = ioremap(res->start, size);                                                 //转化成虚拟地址
  52. if (info->io == NULL) {
  53. dev_err(&pdev->dev, "ioremap() of registers failed\n");
  54. ret = -ENXIO;
  55. goto release_mem;
  56. }
  57. info->irq_base = info->io + ((drv_type == DRV_S3C2412) ? S3C2412_LCDINTBASE : S3C2410_LCDINTBASE);
  58. dprintk("devinit\n");
  59. strcpy(fbinfo->fix.id, driver_name);
  60. /* Stop the video */                                                                   //初始化fbinfo结构
  61. lcdcon1 = readl(info->io + S3C2410_LCDCON1);
  62. writel(lcdcon1 & ~S3C2410_LCDCON1_ENVID, info->io + S3C2410_LCDCON1);
  63. fbinfo->fix.type     = FB_TYPE_PACKED_PIXELS;
  64. fbinfo->fix.type_aux     = 0;
  65. fbinfo->fix.xpanstep     = 0;
  66. fbinfo->fix.ypanstep     = 0;
  67. fbinfo->fix.ywrapstep     = 0;
  68. fbinfo->fix.accel     = FB_ACCEL_NONE;
  69. fbinfo->var.nonstd     = 0;
  70. fbinfo->var.activate     = FB_ACTIVATE_NOW;
  71. fbinfo->var.accel_flags = 0;
  72. fbinfo->var.vmode     = FB_VMODE_NONINTERLACED;
  73. fbinfo->fbops         = &s3c2410fb_ops;
  74. fbinfo->flags         = FBINFO_FLAG_DEFAULT;
  75. fbinfo->pseudo_palette = &info->pseudo_pal;
  76. for (i = 0; i < 256; i++)
  77. info->palette_buffer[i] = PALETTE_BUFF_CLEAR;
  78. ret = request_irq(irq, s3c2410fb_irq, IRQF_DISABLED, pdev->name, info);                      //注册中断函数
  79. if (ret) {
  80. dev_err(&pdev->dev, "cannot get irq %d - err %d\n", irq, ret);
  81. ret = -EBUSY;
  82. goto release_regs;
  83. }
  84. info->clk = clk_get(NULL, "lcd");
  85. if (!info->clk || IS_ERR(info->clk)) {
  86. printk(KERN_ERR "failed to get lcd clock source\n");
  87. ret = -ENOENT;
  88. goto release_irq;
  89. }
  90. clk_enable(info->clk);
  91. dprintk("got and enabled clock\n");
  92. msleep(1);
  93. /* find maximum required memory size for display */
  94. for (i = 0; i < mach_info->num_displays; i++) {
  95. unsigned long smem_len = mach_info->displays[i].xres;
  96. smem_len *= mach_info->displays[i].yres;
  97. smem_len *= mach_info->displays[i].bpp;
  98. smem_len >>= 3;
  99. if (fbinfo->fix.smem_len < smem_len)
  100. fbinfo->fix.smem_len = smem_len;
  101. }
  102. /* Initialize video memory */
  103. ret = s3c2410fb_map_video_memory(fbinfo);                                                   //为帧缓冲分配内存空间。同时使用了dma
  104. if (ret) {
  105. printk(KERN_ERR "Failed to allocate video RAM: %d\n", ret);
  106. ret = -ENOMEM;
  107. goto release_clock;
  108. }
  109. dprintk("got video memory\n");
  110. fbinfo->var.xres = display->xres;
  111. fbinfo->var.yres = display->yres;
  112. fbinfo->var.bits_per_pixel = display->bpp;
  113. s3c2410fb_init_registers(fbinfo);                                                           //GPIO初始化
  114. s3c2410fb_check_var(&fbinfo->var, fbinfo);                                                  //设置fb_var_screeninfo
  115. ret = register_framebuffer(fbinfo);                                                         //注册帧缓冲-register_framebuffer
  116. if (ret < 0) {
  117. printk(KERN_ERR "Failed to register framebuffer device: %d\n",
  118. ret);
  119. goto free_video_memory;
  120. }
  121. /* create device files */
  122. ret = device_create_file(&pdev->dev, &dev_attr_debug);
  123. if (ret) {
  124. printk(KERN_ERR "failed to add debug attribute\n");
  125. }
  126. printk(KERN_INFO "fb%d: %s frame buffer device\n",
  127. fbinfo->node, fbinfo->fix.id);
  128. return 0;
  129. free_video_memory:
  130. s3c2410fb_unmap_video_memory(fbinfo);
  131. release_clock:
  132. clk_disable(info->clk);
  133. clk_put(info->clk);
  134. release_irq:
  135. free_irq(irq, info);
  136. release_regs:
  137. iounmap(info->io);
  138. release_mem:
  139. release_resource(info->mem);
  140. kfree(info->mem);
  141. dealloc_fb:
  142. platform_set_drvdata(pdev, NULL);
  143. framebuffer_release(fbinfo);
  144. return ret;
  145. }

s3c2410fb_map_vedio_memory:

  1. static int __init s3c2410fb_map_video_memory(struct fb_info *info)
  2. {
  3. struct s3c2410fb_info *fbi = info->par;
  4. dma_addr_t map_dma;
  5. unsigned map_size = PAGE_ALIGN(info->fix.smem_len);
  6. dprintk("map_video_memory(fbi=%p) map_size %u\n", fbi, map_size);
  7. info->screen_base = dma_alloc_writecombine(fbi->dev, map_size,
  8. &map_dma, GFP_KERNEL);                                                      //为帧缓冲分配内存空间。同时使用了dma
  9. if (info->screen_base) {
  10. /* prevent initial garbage on screen */
  11. dprintk("map_video_memory: clear %p:%08x\n",
  12. info->screen_base, map_size);
  13. memset(info->screen_base, 0x00, map_size);
  14. info->fix.smem_start = map_dma;
  15. dprintk("map_video_memory: dma=%08lx cpu=%p size=%08x\n",
  16. info->fix.smem_start, info->screen_base, map_size);
  17. }
  18. return info->screen_base ? 0 : -ENOMEM;
  19. }

分析到这里发现并没有设置帧缓冲的地址:

于是可以通过搜索帧地址来辨别,在哪个函数中实现。

s3c2410fb_set_lcdaddr:

  1. static void s3c2410fb_set_lcdaddr(struct fb_info *info)
  2. {
  3. unsigned long saddr1, saddr2, saddr3;
  4. struct s3c2410fb_info *fbi = info->par;
  5. void __iomem *regs = fbi->io;
  6. saddr1 = info->fix.smem_start >> 1;
  7. saddr2 = info->fix.smem_start;
  8. saddr2 += info->fix.line_length * info->var.yres;
  9. saddr2 >>= 1;
  10. saddr3 = S3C2410_OFFSIZE(0) |
  11. S3C2410_PAGEWIDTH((info->fix.line_length / 2) & 0x3ff);
  12. dprintk("LCDSADDR1 = 0x%08lx\n", saddr1);
  13. dprintk("LCDSADDR2 = 0x%08lx\n", saddr2);
  14. dprintk("LCDSADDR3 = 0x%08lx\n", saddr3);
  15. writel(saddr1, regs + S3C2410_LCDSADDR1);                                  //这里设置了帧缓冲的地址
  16. writel(saddr2, regs + S3C2410_LCDSADDR2);
  17. writel(saddr3, regs + S3C2410_LCDSADDR3);
  18. }

但是如何知道调用顺序呢,可以在函数中调用dump_stack():

  1. Backtrace:
  2. [<c0049048>] (dump_backtrace+0x0/0x10c) from [<c0373fac>] (dump_stack+0x18/0x1c)
  3. r7:232f3302 r6:5bd42233 r5:00000000 r4:3a352944
  4. [<c0373f94>] (dump_stack+0x0/0x1c) from [<c01718c8>] (s3c2410fb_set_par+0x150/0x78c)
  5. [<c0171778>] (s3c2410fb_set_par+0x0/0x78c) from [<c016a578>] (fbcon_init+0x42c/0x4b8)
  6. [<c016a14c>] (fbcon_init+0x0/0x4b8) from [<c0185800>] (visual_init+0xb8/0x100)
  7. [<c0185748>] (visual_init+0x0/0x100) from [<c018a65c>] (take_over_console+0x1f4/0x3d8)
  8. r7:00000000 r6:c03a6c90 r5:c05a75a0 r4:00000019
  9. [<c018a468>] (take_over_console+0x0/0x3d8) from [<c0167050>] (fbcon_takeover+0x7c/0xd4)
  10. [<c0166fd4>] (fbcon_takeover+0x0/0xd4) from [<c016b1b0>] (fbcon_event_notify+0x768/0x7b0)
  11. r5:ffffffff r4:00000000
  12. [<c016aa48>] (fbcon_event_notify+0x0/0x7b0) from [<c0070784>] (notifier_call_chain+0x54/0x94)
  13. [<c0070730>] (notifier_call_chain+0x0/0x94) from [<c0070d08>] (__blocking_notifier_call_chain+0x54/0x6c)
  14. r9:c04b5008 r8:00000005 r7:ffffffff r6:c381dd98 r5:c04c5470
  15. r4:c04c547c
  16. [<c0070cb4>] (__blocking_notifier_call_chain+0x0/0x6c) from [<c0070d40>] (blocking_notifier_call_chain+0x20/0x28)
  17. r8:c3842a04 r7:00000000 r6:c0513120 r5:c3842800 r4:c381dd60
  18. [<c0070d20>] (blocking_notifier_call_chain+0x0/0x28) from [<c015fc48>] (fb_notifier_call_chain+0x1c/0x24)
  19. [<c015fc2c>] (fb_notifier_call_chain+0x0/0x24) from [<c0160cf0>] (register_framebuffer+0x154/0x1fc)
  20. [<c0160b9c>] (register_framebuffer+0x0/0x1fc) from [<c0014bbc>] (s3c24xxfb_probe+0x4c4/0x6fc)
  21. [<c00146f8>] (s3c24xxfb_probe+0x0/0x6fc) from [<c0014e20>] (s3c2410fb_probe+0x14/0x18)
  22. [<c0014e0c>] (s3c2410fb_probe+0x0/0x18) from [<c019369c>] (platform_drv_probe+0x20/0x24)
  23. [<c019367c>] (platform_drv_probe+0x0/0x24) from [<c0192694>] (driver_probe_device+0x8c/0x1a0)
  24. [<c0192608>] (driver_probe_device+0x0/0x1a0) from [<c019283c>] (__driver_attach+0x94/0x98)
  25. [<c01927a8>] (__driver_attach+0x0/0x98) from [<c0191f38>] (bus_for_each_dev+0x6c/0x98)
  26. r7:c01927a8 r6:c04c56b8 r5:c381de98 r4:00000000
  27. [<c0191ecc>] (bus_for_each_dev+0x0/0x98) from [<c0192514>] (driver_attach+0x20/0x28)
  28. r7:c04c56b8 r6:00000000 r5:c04c56b8 r4:c001fc68
  29. [<c01924f4>] (driver_attach+0x0/0x28) from [<c0191764>] (bus_add_driver+0xa4/0x244)
  30. [<c01916c0>] (bus_add_driver+0x0/0x244) from [<c0192b00>] (driver_register+0x74/0x15c)
  31. [<c0192a8c>] (driver_register+0x0/0x15c) from [<c0193a80>] (platform_driver_register+0x6c/0x88)
  32. r7:c381c000 r6:00000000 r5:c001fa50 r4:c001fc68
  33. [<c0193a14>] (platform_driver_register+0x0/0x88) from [<c0014e38>] (s3c2410fb_init+0x14/0x30)
  34. [<c0014e24>] (s3c2410fb_init+0x0/0x30) from [<c0044284>] (do_one_initcall+0x3c/0x1bc)
  35. [<c0044248>] (do_one_initcall+0x0/0x1bc) from [<c0008438>] (kernel_init+0x88/0xf4)
  36. [<c00083b0>] (kernel_init+0x0/0xf4) from [<c005a2e8>] (do_exit+0x0/0x620)

LCD驱动程序架构和分析的更多相关文章

  1. LCD驱动程序之层次分析

    1.回顾字符设备驱动程序: 字符设备驱动编写的一般步骤: 1)主设备号 2)构造file_operations结构体体 .open = xxxx .read = xxxxx 3)register_ch ...

  2. [国嵌攻略][142][LCD驱动程序架构]

    LCD裸机驱动回顾 1.LCD初始化 1.1.控制器初始化 1.2.端口初始化 1.3.指明了帧缓冲 2.LCD图形显示 2.1.将图形数据写入帧缓冲 Linux帧缓冲体验 把图片转换成开发板屏对应的 ...

  3. [国嵌攻略][143][LCD驱动程序分析]

    LCD驱动程序分析 LCD驱动程序代码在/drivers/video/s3c2410fb.c文件中,在该驱动的s3c2410fb_init中注册了平台驱动,该驱动的初始化代码在s3c24xxfc_pr ...

  4. 10. LCD驱动程序 ——框架分析

    引言: 由LCD的硬件原理及操作(可参看韦哥博客:第017课 LCD原理详解及裸机程序分析) 我们知道只要LCD控制器的相关寄存器正确配置好,就可以在LCD面板上显示framebuffer中的内容. ...

  5. Linux内核启动代码分析二之开发板相关驱动程序加载分析

    Linux内核启动代码分析二之开发板相关驱动程序加载分析 1 从linux开始启动的函数start_kernel开始分析,该函数位于linux-2.6.22/init/main.c  start_ke ...

  6. LCD驱动程序编写

    学习目标:编写LCD驱动程序,熟悉根据芯片手册分析时序图,配置寄存器,并测试LCD程序. 一.LCD驱动程序编写 步骤: 1)分配fb_info结构体 2)设置fb_info结构体 a. 固定参数 b ...

  7. LCD驱动程序

    学习目标:熟悉TFT LCD的概念,分层驱动工作原理和程序编写. 一.LCD 概念 1.  显示器数据组织格式 1)一幅图像成为一帧,每帧由多行组成,每行由多个像素组成.每个像素的颜色由若干位表示,对 ...

  8. linux驱动由浅入深系列:高通sensor架构实例分析之三(adsp上报数据详解、校准流程详解)【转】

    本文转载自:https://blog.csdn.net/radianceblau/article/details/76180915 本系列导航: linux驱动由浅入深系列:高通sensor架构实例分 ...

  9. LCD驱动程序(一)

    LCD显示原理: 在JZ2440上,想要让LCD显示,需要几个部分1.LCD硬件 2.开发板上的LCD控制器 3.SDRAM内存存放数据FramBuffer 4.可能还需要一个调色板(实际上是一块内存 ...

随机推荐

  1. shell脚本学习(6)awk 编排字段

    awk能取出文本字段重新编排 1 awk的用法 awk ‘program’ [file] 2 其中program 可以写成 ‘parrtern {action}’    pattern 或 actio ...

  2. EDA课设-交通灯-Verilog版----FPGA--004

    分得到析四个状态: S1: 主干道(绿灯亮) ,支干道(亮红灯):--40S S1: 主干道 (黄灯亮) ,支干道(亮红灯):--4S S1: 主干道 (亮红灯),支干道(绿灯亮):--20S S1: ...

  3. 黄金含量版本——KTV

    呀,进来的都是盆友,首先先给大家拜年了,祝大家新年快乐,万事如意,家和万事兴~! 大家看了标题进来就不能让大家白进来,一定会让大家带着满满的果实. 下面我们就来讨论讨论KTV这个项目: (1)KTV的 ...

  4. iOS 开发加密做法

    一般做法是这样的: 客户端 每一个请求的URL中加上时间的参数.对url中的参数是排序好的. 然后对这个URL进行MD5.将这个MD5作为最后一个参数(sign)拼接到url最后. 服务端 收到请求后 ...

  5. 头疼3-4次的问题,数据从DB导出到EXCEL,再从EXCEL导入到DB,数据格式发生错误 ,导致 程序出错。

    反思: 1 解决 问题的思路 绕远了: 在这个问题出现前,程序是运行正确 的 问题出现前,我误删了DB 的 testcase表的所有 case ,然后 再把邮件 中的excel数据导入到 DB 然后 ...

  6. How to show out three rows from the same databand On A4?

    How to show out three rows from the same databand On A4? Quote Post by DoraHuang » Tue Mar 13, 2018 ...

  7. oo_project_2java数据类型范围及测试

    数据类型范围测试 一.数字常数的编译问题 java中的常量数字默认以int型编译 如: long a = 1234567890; //十位 long b = 12345678900; //默认数据为i ...

  8. 如何保存android app日志

    android 手机日志保存方法如下: 前置条件:已安装adb 1,手机usb连接电脑,打开USB调试模式(注意仅连接一台手机设备) 2,win+R输入cmd打开命令窗口,输入指令:adb devic ...

  9. tfsenflow队列|tf.train.slice_input_producer|tf.train.Coordinator|tf.train.start_queue_runners

      #### ''' tf.train.slice_input_producer :定义样本放入文件名队列的方式[迭代次数,是否乱序],但此时文件名队列还没有真正写入数据 slice_input_pr ...

  10. pyppeteer模块的基本使用

    pyppeteer模块的基本使用 引言 Selenium 在被使用的时候有个麻烦事,就是环境的相关配置,得安装好相关浏览器,比如 Chrome.Firefox 等等,然后还要到官方网站去下载对应的驱动 ...