设为首页 加入收藏

TOP

16.Linux-LCD驱动(详解)(一)
2017-10-11 13:59:41 】 浏览:2050
Tags:16.Linux-LCD 驱动 详解

在上一节LCD层次分析中,得出写个LCD驱动入口函数,需要以下4步:

1) 分配一个fb_info结构体: framebuffer_alloc();

2) 设置fb_info

3) 设置硬件相关的操作

4) 使能LCD,并注册fb_info: register_framebuffer()

 

本节需要用到的函数:

void *dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp);  //分配DMA缓存区给显存
//参数如下:

//*dev:指针,这里填0,表示这个申请的缓冲区里没有内容

//size:分配的地址大小(字节单位)

//*handle:申请到的物理起始地址

//gfp:分配出来的内存参数,标志定义在<linux/gfp.h>,常用标志如下:
    //GFP_ATOMIC    用来从中断处理和进程上下文之外的其他代码中分配内存. 从不睡眠.
    //GFP_KERNEL    内核内存的正常分配. 可能睡眠.
    //GFP_USER      用来为用户空间页来分配内存; 它可能睡眠.    

分配一段DMA缓存区,分配出来的内存不使用cache缓存(因为DMA传输不需要CPU)

它和 dma_alloc_coherent ()函数相似,不过 dma_alloc_coherent ()函数是分配出来的内存会禁止cache缓存以及禁止写入缓冲区


 

dma_free_writecombine(dev,size,cpu_addr,handle);   //释放缓存
//cpu_addr:虚拟地址, 
//handle:物理地址

释放DMA缓冲区, dev和size参数和上面的一样


 

struct fb_info *framebuffer_alloc(size_t size, struct device *dev);      //申请一个fb_info结构体,
//size:额外的内存,
//*dev:指针, 这里填0,表示这个申请的结构体里没有内容

int register_framebuffer(struct fb_info *fb_info);  

                      //向内核中注册fb_info结构体,若内存不够,注册失败会返回负数

int unregister_framebuffer(struct fb_info *fb_info) ;

                      //注销内核中fb_info结构体

 


 

本节需要用到的结构体:

fb_info结构体如下:

struct fb_info {
        ... ...
       struct fb_var_screeninfo var;       //可变的参数
       struct fb_fix_screeninfo fix;        //固定的参数
       ... ...
       struct fb_ops *fbops;              //操作函数
       ... ...
       char __iomem *screen_base;        //显存虚拟起始地址
       unsigned long screen_size;          //显存虚拟地址长度
  
void *pseudo_palette; //假的16色调色板,里面存放了16色的数据,可以通过8bpp数据来找到调色板里面的16色颜色索引值,模拟出16色颜色来,节省内存,不需要的话就指向一个不用的数组即可 ... ... };

其中操作函数fb_info-> fbops 结构体写法如下:

static struct fb_ops s3c_lcdfb_ops = {
         .owner                = THIS_MODULE,
.fb_setcolreg
= my_lcdfb_setcolreg,//设置调色板fb_info-> pseudo_palette,自己构造该函数 .fb_fillrect = cfb_fillrect, //填充矩形,用/drivers/video/ cfbfillrect.c里的函数即可 .fb_copyarea = cfb_copyarea, //复制数据, 用/drivers/video/cfbcopyarea.c里的函数即可 .fb_imageblit = cfb_imageblit, //绘画图形, 用/drivers/video/imageblit.c里的函数即可 };

固定的参数fb_info-> fix 结构体如下:

struct fb_fix_screeninfo {
       char id[16];                   //id名字
       unsigned long smem_start;  //framebuffer物理起始地址                          
       __u32 smem_len;           //framebuffer长度,字节为单位
       __u32 type;                 //lcd类型,默认值0即可
       __u32 type_aux;               //附加类型,为0
       __u32 visual;                     //画面设置,常用参数如下
// FB_VISUAL_MONO01             0   单色,0:白色,1:黑色
// FB_VISUAL_MONO10             1    单色,1:白色,0:黑色
// FB_VISUAL_TRUECOLOR          2     真彩(TFT:真彩)
// FB_VISUAL_PSEUDOCOLOR     3     伪彩
// FB_VISUAL_DIRECTCOLOR        4     直彩

    __u16 xpanstep;                /*如果没有硬件panning就赋值为0 */
    __u16 ypanstep;                /*如果没有硬件panning就赋值为0 */
    __u16 ywrapstep;                 /*如果没有硬件ywrap就赋值为0 */

    __u32 line_length;                 /*一行的字节数 ,例:(RGB565)240*320,那么这里就等于240*16/8 */

    /*以下成员都可以不需要*/     unsigned
long mmio_start; /*内存映射IO的起始地址,用于应用层直接访问寄存器,可以不需要*/ __u32 mmio_len; /* 内存映射IO的长度,可以不需要*/ __u32 accel; __u16 reserved[3]; };

可变的参数fb_info-> var 结构体如下:

structfb_var_screeninfo{                                    
   __u32xres;                    /*可见屏幕一行有多少个像素点*/
    __u32 yres;                      /*可见屏幕一列有多少个像素点*/
    __u32 xres_virtual;         /*虚拟屏幕一行有多少个像素点 */       
    __u32  yres_virtual;       /*虚拟屏幕一列有多少个像素点*/
    __u32 xoffset;                 /*虚拟到可见屏幕之间的行偏移,若可见和虚拟的分辨率一样,就直接设为0*/
    __u32 yoffset;                 /*虚拟到可见屏幕之间的列偏移*/
    __u32  bits_per_pixel;    /*每个像素的位数即BPP,比如:RGB565则填入16*/
    __u32 grayscale;           /*非0时,指的是灰度,真彩直接填0即可*/

    struct fb_bitfield red;          //fb缓存的R位域, fb_bitfield结构体成员如下:
//__u32 offset;          区域偏移值,比如RGB565中的R,就在
首页 上一页 1 2 3 4 下一页 尾页 1/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇14.linux-platform机制实现驱动层.. 下一篇wr720n v4 折腾笔记(一):安装Open..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目