网站导航: 首页 > 设计参考 > 正文 文章搜索
S3c2410 LCD驱动学习心得
 
文章编号:
091112205444
文章分类: 单片机 ARM
点 击:
...
关 键 词: S3c2410,LCD
文章来源:
网络 作者:dancerwen
摘 要:
实验目的:学会驱动程序的编写方法,配置S3C2410的LCD驱动,以及在LCD屏上显示包括bmp和jpeg两种格式的图片

2.2.2  S3C2410中LCD的数据结构
 在S3C2410的LCD设备驱动中,定义了s3c2410fb_info来标识一个LCD设备,结构体如下:
struct s3c2410fb_info {
 struct fb_info  *fb;
 struct device  *dev;
 struct s3c2410fb_mach_info *mach_info;
 struct s3c2410fb_hw regs;  /* LCD Hardware Regs */
 dma_addr_t  map_dma;  /* physical */
 u_char *   map_cpu;  /* virtual */
 u_int   map_size;
 /* addresses of pieces placed in raw buffer */
 u_char *   screen_cpu;  /* virtual address of buffer */
 dma_addr_t  screen_dma;  /* physical address of buffer */
 …………
};
成员变量fb指向我们上面所说明的fb_info结构体,代表了一个FrameBuffer。dev则表示了这个LCD设备。map_dma,map_cpu,map_size这三个域向了开辟给LCD DMA使用的内存地址。screen_cpu,screen_dma指向了LCD控制器映射的内存地址。另外regs标识了LCD控制器的寄存器。
struct s3c2410fb_hw {
 unsigned long lcdcon1;
 unsigned long lcdcon2;
 unsigned long lcdcon3;
 unsigned long lcdcon4;
 unsigned long lcdcon5;
};
这个寄存器和硬件的寄存器一一对应,主要作为实际寄存器的映像,以便程序使用。
 这个s3c2410fb_info中还有一个s3c2410fb_mach_info成员域。它存放了和体系结构相关的一些信息,如时钟、LCD设备的GPIO口等等。这个结构体定义为
struct s3c2410fb_mach_info {
 unsigned char fixed_syncs; /* do not update sync/border */
 int type;      /* LCD types */
 int width;      /* Screen size */
 int height;
 struct s3c2410fb_val xres;  /* Screen info */
 struct s3c2410fb_val yres;
 struct s3c2410fb_val bpp;
 struct s3c2410fb_hw  regs;  /* lcd configuration registers */
 /* GPIOs */
 unsigned long gpcup;
 unsigned long gpcup_mask;
 unsigned long gpccon;
 unsigned long gpccon_mask;
 ………… 
};
  
图2.3
上图表示了S3C2410驱动的整体结构,反映了结构体之间的相互关系

2.3  主要代码结构以及关键代码分析
2.3.1  FrameBuffer驱动的统一管理
 fbmem.c实现了Linux FrameBuffer的中间层,任何一个FrameBuffer驱动,在系统初始化时,必须向fbmem.c注册,即需要调用register_framebuffer()函数,在这个过程中,设备驱动的信息将会存放入名称为registered_fb数组中,这个数组定义为
struct fb_info *registered_fb[FB_MAX];
int num_registered_fb;
它是类型为fb_info的数组,另外num_register_fb则存放了注册过的设备数量。
 我们分析一下register_framebuffer的代码。
int register_framebuffer(struct fb_info *fb_info)
{
 int i;
 struct fb_event event;
 struct fb_videomode mode;

 if (num_registered_fb == FB_MAX) return -ENXIO; /* 超过最大数量 */
 num_registered_fb++;
 for (i = 0 ; i < FB_MAX; i++)
  if (!registered_fb[i]) break;     /* 找到空余的数组空间 */
 fb_info->node = i;

 fb_info->dev = device_create(fb_class, fb_info->device,
     MKDEV(FB_MAJOR, i), "fb%d", i);  /* 为设备建立设备节点 */
 if (IS_ERR(fb_info->dev)) {
  …………
 } else{
  fb_init_device(fb_info);      /* 初始化改设备 */
 }
 …………
 return 0;
}
从上面的代码可知,当FrameBuffer驱动进行注册的时候,它将驱动的fb_info结构体记录到全局数组registered_fb中,并动态建立设备节点,进行设备的初始化。注意,这里建立的设备节点的次设备号就是该驱动信息在registered_fb存放的位置,即数组下标i 。在完成注册之后,fbmem.c就记录了驱动的fb_info。这样我们就有可能实现fbmem.c对全部FrameBuffer驱动的统一处理。

2.3.2  实现消息的分派
fbmem.c实现了对系统全部FrameBuffer设备的统一管理。当用户尝试使用一个特定的FrameBuffer时,fbmem.c怎么知道该调用那个特定的设备驱动呢?
我们知道,Linux是通过主设备号和次设备号,对设备进行唯一标识。不同的FrameBuffer设备向fbmem.c注册时,程序分配给它们的主设备号是一样的,而次设备号是不一样的。于是我们就可以通过用户指明的次设备号,来觉得具体该调用哪一个FrameBuffer驱动。下面通过分析fbmem.c的fb_open()函数来说明。(注:一般我们写FrameBuffer驱动不需要实现open函数,这里只是说明函数流程。)
static int fb_open(struct inode *inode, struct file *file){
 int fbidx = iminor(inode);
 struct fb_info *info;
 int res;
    /* 得到真正驱动的函数指针 */
 if (!(info = registered_fb[fbidx])) return -ENODEV; 
 if (info->fbops->fb_open) {
  res = info->fbops->fb_open(info,1); //调用驱动的open()
  if (res)  module_put(info->fbops->owner);
 }
 return res;
}
当用户打开一个FrameBuffer设备的时,将调用这里的fb_open()函数。传进来的inode就是欲打开设备的设备号,包括主设备和次设备号。fb_open函数首先通过iminor()函数取得次设备号,然后查全局数组registered_fb得到设备的fb_info信息,而这里面存放了设备的操作函数集fb_ops。这样,我们就可以调用具体驱动的fb_open() 函数,实现open的操作。下面给出了一个LCD驱动的open() 函数的调用流程图,用以说明上面的步骤。
 
 图2.4

2.3.3  开发板S3C2410 LCD驱动的流程
(1)在mach-smdk2410.c中,定义了初始的LCD参数。注意这是个全局变量。
static struct s3c2410fb_mach_info smdk2410_lcd_cfg = {
 .regs= {
  .lcdcon1 = S3C2410_LCDCON1_TFT16BPP |
   S3C2410_LCDCON1_TFT|
   S3C2410_LCDCON1_CLKVAL(7),
  ......
 },
 .width  = 240,   .height = 320,
 .xres = {.min = 240,.max= 240,.defval = 240},
 .bpp   = {.min = 16,  .max= 16,  .defval = 16},
 ......
};
(2)内核初始化时候调用s3c2410fb_probe函数。下面分析这个函数的做的工作。首先先动态分配s3c2410fb_info空间。
   fbinfo = framebuffer_alloc(sizeof(struct s3c2410fb_info),&pdev->dev);
把域mach_info指向mach-smdk2410.c中的smdk2410_lcd_cfg 。
info->mach_info = pdev->dev.platform_data;
设置fb_info域的fix,var,fops字段。

fbinfo->fix.type  =  FB_TYPE_PACKED_PIXELS;
fbinfo->fix.type_aux     = 0;
fbinfo->fix.xpanstep     = 0;

fbinfo->var.nonstd     = 0;
fbinfo->var.activate   = FB_ACTIVATE_NOW;
fbinfo->var.height     = mach_info->height;
fbinfo->var.width     = mach_info->width;

fbinfo->fbops      = &s3c2410fb_ops;
……
该函数调用s3c2410fb_map_video_memory()申请DMA内存,即显存。

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;
…….
设置控制寄存器,设置硬件寄存器。

memcpy(&info->regs, &mach_info->regs,sizeof(info->regs));
info->regs.lcdcon1 &= ~S3C2410_LCDCON1_ENVID;
……….
调用函数s3c2410fb_init_registers(),把初始值写入寄存器。

writel(fbi->regs.lcdcon1, S3C2410_LCDCON1);
   writel(fbi->regs.lcdcon2, S3C2410_LCDCON2);

(3)当用户调用mmap()映射内存的时候,Fbmem.c把刚才设置好的显存区域映射给用户。
  start = info->fix.smem_start;
  len = PAGE_ALIGN( (start & ~PAGE_MASK) + info->fix.smem_len);
  io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
vma->vm_end - vma->vm_start,vma->vm_page_prot);
  ……
这样就完成了驱动初始化到用户调用的整个过程。
 

 
相关文章:
S3C2440A驱动RGB接口TFT LCD的研究[图]
s3c2410 Timer工作原理[图]
虚拟SPI时序在TC77与S3C2410通信中的应用[图]
s3c2410 MMU(存储器管理单元)讲解[图]
s3c2410 CACHES,WRITE BUFFER讲解[图]
S3C2410中的脉宽调制定时器(PWM)
S3C2410 中断程序的实现
s3c2410 watchdog详解
s3c2410 中断异常处理[图]
基于ARM9芯片S3C2410a的GPRS数据终端设计
ARM系统中DMA方式在数据采集中的应用[图]
AD7888与S3C2410的SPI接口及Linux下嵌入式驱动的实现[图]
基于s3c2410的ARMer9开发平台的使用
ARM S3C2410硬件手册重点
基于ARM S3C2410与TMS320C6416的接口设计[图]
S3C2410上Jffs2的移植
ARM S3C2410驱动TFT-LCD的研究[图]
MINIGUI在S3C2410开发板的移植
mplayer在S3C2410上的移植
在S3C2410上移植yaffs2文件系统
S3C2410 bootloader(vivi)阅读笔记
s3c2410 LCD图片显示
S3C2410 LCD 驱动程序移植及GUI程序编写[图]
S3C2410X开发总结及心得
U-Boot在S3C2410开发板上的移植
S3C2410初始化
S3C2410通过IIS总线与音频芯片UDA1380进行通信
在S3C2410上移植bluetooth(蓝牙)
S3c2410软件调试总结
S3C2410上触摸屏的应用实例
S3c2410的触摸屏及模数转换
S3C2410的快速启动技术
基于嵌入式linux和s3c2410平台的视频采集
s3c2410移植MPlayer到linux2.6

上一页 123 下一页
 
最新开源项目
 
 
  查看更多...  
 
本站相关产品   淘宝网店
 




 
  查看更多...  

 

本站程序由百合电子工作室开发和维护
Copyright @ baihe electric studio
渝ICP备09006681号-4