一、 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:没来一个时钟,电子枪向后移动一个像素
硬件操作:
- 配置引脚用于LCD
- 根据LCD手册设置LCD控制器
- 分配显存,并把分配的地址告诉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;">