zoukankan      html  css  js  c++  java
  • lcd驱动解析(二)

    init部分主要完成的任务是:屏的初始化,显示的初始化,最后打开lcd,背光,等待图片数据输入,然后输出。(产生fbinfo结构体给fbmem.c使用)

    用户操作的流程包括:ioctl控制图片的显示属性(读取初始化时的配置或者使用bsp操作寄存器改变显示设置)和显示图片的数据源。(概括说就是控制和数据两条线)

    这一节主要分析init部分,就是属于***fb.c文件的函数。

        驱动程序绑定由内核自动执行,当内核发现一个驱动程序与一个设备匹配时,将调用驱动程序的probe函数,完成对设备的探测及初始化等工作。device与driver是用名字搭配的,其实注册并部分先后,device注册时会去找driver,driver注册的时候会去找device,当配对成功后,driver就从device中获取必要的数据(使用到资源或者一些参数),然后对设备进行初始化。搭建必要的设备运行环境,比如lcd需要在内存中申请一段空间,用于接收用户发送过来的数据。只有都准备完毕了,才可以打开设备,等待用户操作。(lcd driver还产生了一个结构体fbinfo,存放了用户可能用到的所有信息,放到fbmem.c中)这样probe函数的入口参数就可以解释了

    kzalloc

        用kzalloc申请内存的时候, 效果等同于先是用 kmalloc() 申请空间 , 然后用 memset() 来初始化 ,所有申请的元素都被初始化为 0.

    首先为什么要使用这个函数,目的是在堆空间分配一段内存给一个指针,然后初始化为0。其实完成同样的功能也可以这样,先定义一个结构体实例,并初始化为0,然后把这个对象赋值给那个指针。结果都是一个指针指向了一段大小一样空的内存,只不过一个在堆,一个在栈。不过在堆中更容易控制,可以自己free掉,而不需要等待系统去帮你free。有个不好就是把指针给别人用,别人却不去free它,那就糟了,这一点还是比不上结构体实例的。

    platform_get_resource

    struct resource *platform_get_resource(struct platform_device *dev,
                                       unsigned int type, unsigned int num)
    {
           int i; 
           for (i = 0; i < dev->num_resources; i++) {
    //不管你想找哪一类资源,都要从第一个资源看是比对,所以效率吗貌似有点低,不过一般总资源数也不多。
    struct resource *r = &dev->resource[i]; if (type == resource_type(r) && num-- == 0) return r;
    //找到匹配的之后把整个结构体返回。 }
    return NULL;
    //没找到就返回空。 }
    //这里取出的资源包括中断号,io端口的寄存器物理地址等。这些资源是设备需要用的,驱动取出后用于静态申请(就是已知物理地址,中断号的情况下去申请物理地址和中断号),可以理解为,
    //告诉系统这段物理地址和中断号被占用,不能再分配给其他设备了。如果没有lcd,这些资源就可以给别人用了。这些都是系统资源啊,大家共用的。
    info->mem = request_mem_region(res->start, resource_size(res), pdev->name);
    //这就是申请指定的io物理地址空间,告诉系统,这段物理地址被lcd占用。(后来使用寄存器的物理地址) info
    ->io = ioremap(res->start, resource_size(res));
    //把申请到的物理地址空间映射到虚拟地址空间中,后来操作寄存器都是使用的虚拟地址。

    framebuffer_alloc()

    framebuffer_alloc()功能是向内核申请一段大小为sizeof(struct fb_info) + size的空间,其中size的大小代表设备的私有数据空间,并用fb_info的par域指向该私有空间。为什要价size大小,因为这样才是整个fbinfo的大小,私有数据空间需要与fbinfo一起free,就是说这段数据是不可缺少的,那么为什么不用结构体来存放,这样与fbinfo就是一个整体了啊,一起free更有说服力。大家注意一下par是个void型的指针,为什么要是void型的呢,因为他自己都不知道他将要指向的私有数据类型,那你用什么结构体来存放这莫名的私有数据呢。fbinfo这个结构体里面的成员是定好的,他是与fbmem.c的接口,这个接口结构体中就只有这样一个私有数据指针是可变的,是给用户发挥的。这就解释了为什么par是void类型的指针。既然fbinfo是在***fb.c中申请的,作为数据接口给fbmem.c,那么在init结束后也是不能释放的,所以放在堆里面很安全,在注销驱动的时候在remove函数内会free掉,很方便是不是?

     关于android lcd doublebuffer问题

    DMA从SDRAM FIFO中取数据,送给显存buffer的时候,中间需要进行处理,比如mix alphableeding,colorkey等工作,这些时间并不长,但是在进行处理时,SDRAM FIFO中的数据无法更新,可以理解为是基于此FIFO进行合成等工作的,合成完了才会送到显存FIFO,送完后等待取出下一张要显示的图片,取图片又是需要时间的,两个时间加起来就无法忽略了,有明显的延迟。所以使用doublebuffer,就是行为原来的两倍,可以存两张图片,一个用来合成,一个用来绘制,两个交替使用,解决延迟的问题。(这也就是通常说的pan_display)

     

     

     

     

       

  • 相关阅读:
    android 开发 View _3_ View的属性动画ValueAnimator
    android 开发 View _2_ View的属性动画ObjectAnimator ,动画效果一览
    android 开发 View _1_ View的子类们 和 视图坐标系图
    android 开发 ScrollView 控件的一些api描述与自定义ScrollView接口回调方法
    android 开发 我的高德地图代码例子
    android 开发 singleTask启动模式下传值的坑
    android 开发 时间选择器TimePicker的使用
    android 开发 实现一个activity变成dialog对话框
    android 开发 实现一个ListView套嵌GirdView的滚动布局
    android 开发 使用自定义布局实现标题栏复用(标题栏内容自定义:使用代码实现和xml布局自定义属性2种办法实现)
  • 原文地址:https://www.cnblogs.com/autum/p/lcdc.html
Copyright © 2011-2022 走看看