为EVB添加 Frame Buffer驱动(一):基本套路

 一个嵌入式系统如果有了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了,反而可以为客户节省成本。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值