004LCD驱动

一、 LCD驱动程序之层次分析(第十五课/第一节)

字符设备驱动程序

分析(fbmem.c),这是内核里面自带的LCD驱动程序
先从入口函数开始

注册的结构体内容

这里的fbmem.c没有创建设备结点,只有真正的硬件设备才会到这个类下面创建设备结点。在(register_framebuffer)中可以看到创建设备结点
----------------------------------------------------
假设app:open("/dev/fb0",...) 主设备号29,次设备号0
内核就会找到file_operation fb_fops结构体的".open = fb_open"函数,所以最后打开的是硬件设备


假设app:read(),内核就会找到file_operation fb_fops结构体中的".read = fb_read"函数


-----------------------------------------------------
这个(fbmem.c)是被抽象的出来的,最终都得依赖于数组里面的(fb_info)结构体,这个数组(registered_fb[])是从哪儿来的?
fb_info结构体数组的定义

谁来设置它呢?



有哪些硬件来调用这个(register_framebuffer)注册函数呢?

以(s3c2410fb.c)为例,先找到入口函数


probe函数:分配info结构体,设置,注册,硬件相关的操作



框架:

只有硬件相关的驱动设置好了并向上注册,(fbmem.c)才能进行一系列的操作
要想得到LCD的分辨率等信息:看fbmem.c的ioctl函数


看看这fb_info结构体都有哪些内容

二、 LCD驱动程序之硬件操作(第十五课/第二节)

硬件框图

引脚含义:

    VM(VDEN):vedio data enable,当被使能时,电子枪才会喷出颜色,否则就是光移动不喷颜色就成了黑框(有上下左右黑框)
    VLINE:行同步信号(HSYNC),当电子枪打到最右边时,此时接收到HSYNC行同步信号就会从最右边跳到下一行的最左边。
    RGB(565):颜色数据的来源,本来VD0~VD23,有些没使用,只用到16根线。
    VFRAME:帧同步信号(VSYNC),当电子枪打到最后一行的最右边时,此时就会跳转到第一行的最左边。
    VCLK:没来一个时钟,电子枪向后移动一个像素

硬件操作:

  1. 配置引脚用于LCD
  2. 根据LCD手册设置LCD控制器
  3. 分配显存,并把分配的地址告诉LCD控制器

三、 LCD驱动程序之编写代码之1初步编写(第十五课/第三节)

程序框架:

从入口函数开始填充
1. 分配一个fb_inof结构体


4. 注册,先把简单的写完

2. 设置参数
2.1 设置可变参数

2.2 设置固定参数

2.3 设置操作函数


2.4 其它设置

四、 LCD驱动程序之编写代码之2硬件设置(第十五课/第三节)

硬件图:





3. 硬件相关操作
3.1 映射LCD所用到的寄存器,并配置


3.2 映射LCD控制器寄存器


设置LCDCON1寄存器


根据命令 "dmesg" 可以从内核中得到时钟信息

同时查看LCD手册与芯片手册


再结合LCD手册时序表

    tvp(垂直同步信号宽度):电子枪接收到该信号后从最后一个像素跳到第一行的第一个像素点
    tvb(移动时间):电子枪接收到垂直同步信号后还有多长时间开始喷颜色,上边黑框
    tvd(行数):一列的像素个数
    tvf(等待垂直同步信号时间):显示完最后一个像素后等多长时间垂直同步信号才来,下边黑框

设置LCDCON2寄存器

    thp(行同步信号宽度):电子枪接收到该信号后从最后一个像素跳到下一行第一个像素点
    thb(移动时间):电子枪接收到行同步信号后还有多长时间开始喷颜色,左边黑框
    thd(行像素个数):一行的像素个数
    thf(等待行同步信号时间):显示完最右像素后等多长时间行同步信号才来,右边黑框

设置LCDCON3、4寄存器

设置LCDCON5寄存器



五、 LCD驱动程序之编写代码之3显存和调色板设置(第十五课/第三节)

3.3 分配显存,并把地址告诉LCD控制器
这个显存地址要让它的物理地址连续(LCD控制器没有那么智能),所以要用专门的函数来分配这个内存。查看内核中(s3c2410fb.c)中分配显存的方式。

我们自己模仿分配

设置LCDSADDR1寄存器

设置LCDSADDR2寄存器

设置LCDSADDR3寄存器

使能LCD控制器等等,以前为了省电所以关闭

调色板(调色板是一块内存):

    1. 若每个像素16位,可以让LCD控制器直接把显存数据取过来然后发给LCD屏。
    2. 若想要节省内存,在显存里每个像素只占8位,这时LCD控制器就会去显存上取8位数据,然后以这8位数据为索引去调色板获取真正的显示数据

为了兼容以前的程序,我们代码需要提供一个"假的调色板"
这个调色板可能在别的文件中会被调用


出口函数

六、 LCD驱动程序之编译测试(第十五课/第四节)

测试:
第一步:make menuconfig去掉原来的驱动程序,不然两个驱动程序会起冲突



第二步:编译没有LCD的内核;编译模块,因为会用到那三个函数,得把它们编译成(.ko)文件,等会儿加载进去


第三步:使用新的没有LCD的uImage启动

第四步:加载驱动

解决办法:到该模块的文件夹下,把这三个模块也加载上去




依次装载三个函数模块

在装载LCD驱动前先查看一下(/dev)目录下有没有fb设备


装载LCD驱动后进行测试
(echo hello > /dev/tty1)表示LCD上显示hello

(cat lcd.ko /dev/fb0)把lcd.ko的内容直接扔到显存上去,就会花屏

用按键来测试LCD
第一步:修改(/etc/inittab),再启动一个shell程序

以前我们的tty1会使用(tty_io.c)来调用(key_board.c),把按键作为输入;现在我们的tty1会使用(fbcon.c)来把LCD作为输出,这个程序最终也会用到(registered_fb)这个数组里的fb_info结构,fb_info结构里有显存。它会帮我们得到文字的字模,然后在LCD的显存描出这个文字
第二步:重启内核,挂接,并装载驱动




<wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">

posted on 2019-09-02 16:15  wawzzll  阅读(378)  评论(0编辑  收藏  举报

导航