Chinaunix首页 | 论坛 | 博客
  • 博客访问: 130556
  • 博文数量: 22
  • 博客积分: 949
  • 博客等级: 准尉
  • 技术积分: 266
  • 用 户 组: 普通用户
  • 注册时间: 2010-09-10 22:31
文章分类

全部博文(22)

文章存档

2012年(1)

2011年(2)

2010年(19)

分类: 嵌入式

2010-09-11 09:01:52

    一个嵌入式系统如果有了LCD显示,那肯定会添彩不少,正好俺们的EVB上是标配LCD的,所以可以给它添个Frame Buffer驱动。以前改过S3C2410的Frame Buffer驱动,代码过于冗长,而且S3C2410是是大户人家的东东,自己带LCD控制器,可以直接支持“玻璃“也可以支持模组(通过总线)的,关于玻璃和模组请看文章后面的备注。俺们设计芯片的原则不是Low Cost, 而是Ultra Low Cost,还美名其曰ULC。不过好歹也是个外企,虽然在51Job上叫外企(其它),我们还是有一个专门的硬件模块LCD Bridge来接LCD模组的,包括了经典51单片机书上讲的通过74xx芯片生成RS, WR,RD,CS信号的电路,主要在于没有哪个做手机的用户会在一堆BGA中间加两个突兀的SOC封装74xx,明显不专业嘛,所以我们只能依了客户。此外这个LCD Bridge里面还有一点FIFO和颜色转换的东东。FIFO还有点用,那个颜色转换到目前为止还没用过。
    写Linux程序如果说还要Start From Scratch,明显Out了,没看大家张嘴闭嘴都是”移植......移植“还是”移植“吗?最经典的模板当然非skeletonfb.c莫数了,不过这个文件注释居多,有效内容太少。我还是选一个实际一点的,对driver/video按照大小排序,最后在矮子里面找高个,发现q40fb.c资质不错,就是它了。
    第一步当然是要把q40fb.c该个名字cbp-fb.c,放到driver/video下面,然后添加Kconfig和Makefile选项使它能被编译了,照葫芦画瓢:
1.  driver/video/Kconfig:
config FB_CBP
 tristate "VIA(VTC) CBP LCD framebuffer support"
 depends on FB && ARCH_CBP
 select FB_CFB_FILLRECT
 select FB_CFB_COPYAREA
 select FB_CFB_IMAGEBLIT
    ---help---
      Frame Buffer Driver for VIA Telecom(VTC) CBP chipset.
其中的FB_CFB_XX是为了将CFB相关的函数编译进去,相当于软件对画框等操作进行加速

2. driver/video/Makefile
obj-$(CONFIG_FB_CBP)               +=cbp-fb.o
    第二步当然是把这个文件改改,一方面把那些名字都替换成俺喜欢的名字,其次只好还要能够编译过,无非就是修修补补,这个比较容易。
3.修改跟EVB相关的参数
    主要是修改分辨率,修改RGB565的bit定义等等,就是修改传说中的fix和var参数
static struct fb_fix_screeninfo cbp_fb_fix __initdata = {
 .id  = "cbp",
 .smem_len = 240*320*2,
 .type  = FB_TYPE_PACKED_PIXELS,
 .visual  = FB_VISUAL_TRUECOLOR,
 .line_length = 240*2,
 .accel  = FB_ACCEL_NONE,
};
static struct fb_var_screeninfo cbp_fb_var __initdata = {
 .xres  = 240,
 .yres  = 320,
 .xres_virtual = 240,
 .yres_virtual = 320,
 .bits_per_pixel = 16,
    .red  = {11, 5, 0},
 .green  = {5, 6, 0},
 .blue  = {0, 5, 0},
 .activate = FB_ACTIVATE_NOW,
 .height  = -1,
 .width  = -1,
 .vmode  = FB_VMODE_NONINTERLACED,
};
4.为驱动分配内存 
     现在这个世道,没有Money甚吗都干不了,就像Frame Buffer驱动没有内存一样。当系统调用cbp_fb_init中的platform_xxx函数的时候已经注定后面要调用的第一个函数就是probe函数了。先调用以下函数:
 info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev);
   紧接着申请显示缓存,没错,就是显存了,俺们这个系统不是独立显存,还得和CPU共享。分配的时候当然要分配一段没有Cache的区域了,不然当使用CPU刷新屏幕的时候很可能会是这里一个小黑条,那里一片花条,这个是俺多年与CPU,GFX,DMA,CACHE打交道的经验了。
     cbp_fb_fix.smem_start = dma_alloc_writecombine(&(dev->dev),
                                                    map_size,
                                                    &map_dma,
                                                    GFP_KERNEL);
这个函数的返回值就是申请到的地址,虚拟的。物理的存在那个map_dma里面。
既然已经有了info这个筐,又有了显存地址、fix info、var info这一堆东东,赶紧往里面装吧。
 info->var = cbp_fb_var;
 info->fix = cbp_fb_fix;
 info->fbops = &cbp_fb_ops;
 info->flags = FBINFO_DEFAULT;  /* not as module for now */
 info->pseudo_palette = info->par;
 info->par = NULL;
 info->screen_base = (char *) cbp_fb_fix.smem_start;
4.注册
    现在万事具备,陆毅也给周瑜借来了东风,调用Color Map和Register函数即可:
 if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
  framebuffer_release(info);
  return -ENOMEM;
 }
 //master_outb(3, DISPLAY_CONTROL_REG);
 if (register_framebuffer(info) < 0) {
  printk(KERN_ERR "Unable to register cbp frame buffer\n");
  fb_dealloc_cmap(&info->cmap);
  framebuffer_release(info);
  return -EINVAL;
 }
 return 0;
    现在我可以打保票说,这个Frame Buffer驱动已经呱呱坠地OK了,其实Frame Buffer驱动一点都不复杂,是那些写书的人把它写复杂了,不过我的启蒙教材ldd2和它的后续好像根本不写Frame Buffer。或许就是觉得它太简单。。。。。。。。?!
不过要让这个驱动产生点实际的效果,比如显示俺们那熟悉的可爱的小企鹅哦,还得明天继续分解。
备注:
    我的前任台湾老板,一个卖液晶的朋友(注:两个人,男的)告诉我,那种不带LCD控制器的液晶面板叫玻璃,也就是LCD,就是只有带液晶控制器的MCU才能和它们对接,比如大家猛汉S3C2410,这些玻璃的扫描时序有MCU产生,因此MCU要不停的刷,会占用很多的Memory带宽。 而自己带LCD控制器的叫LCM,也就是LCD Module,俗称模组了,中发电子市场那种黑白的后面有绿色电路板12864模块就是典型,不过现在很多也没有后面背的绿色电路板了,芯片直接坐在玻璃上,俗称COG,就是Chip On Glass了,是不是很土?而且很多模组都是彩色的,比如俺用的,深圳无名氏所产的以ILI932x作为控制器的240x320彩色模组。模组的好处就是像51单片机这种带宽吃紧的MCU,或者说跟S3C2410相比带宽可以忽略的处理器可以接这种液晶,显示点控制信息啥的。而像Samsung这种豪门,反正卖芯片就是卖沙子,帮客户把LCD控制器做里面了,客户只用买玻璃就OK了,反而可以为客户节省成本。

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/dfysy/archive/2010/09/06/5866941.aspx
阅读(1458) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~