个人总结日记:ltv350三星LCD并行接口接2440处理器的linux驱动程序移植

ltv350三星LCD并行接口接2440处理器的linux驱动程序移植


总体上分三步:
1> framebuffer_alloc函数分配一个fb_info类型的结构体
该结构体用于填充描述使用的液晶参数,比如像 像素类型,是否有硬件加速,
长宽,每个像素的位数,调色板等。
其中主要填充fix与var这两个成员结构体变量,这两个结构体在应用程序中
可以通过ioctl函数的命令字 FBIOGET_VSCREENINFO与 FBIOGET_FSCREENINFO
获取这两个结构体。
填充一个结构体fb_ops类型的变量,并让fb_info结构体成员指针fbops指向该
变量。fb_ops需要完成如下设置:
.owner = THIS_MODULE,
.fb_setcolreg = live2440_setcolreg,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
fb_setcolreg用于根据红绿蓝三基色的分量合成颜色到调色板数组中
fb_fillrect fb_copyarea fb_imageblit三个函数用于无显存硬件加器的系统
完成显示数据的填充和复制,使用这三个函数时需要配置相应.c文件编译成模块
或编译进内核。
通过dma_alloc_writecombine函数调协dma方式内存数据到LCD显示总线的数据
传输开始地址及传输长度,并返回传输的内存地址的物理地址及虚拟地址
2>设置lcd控制器及其相关的引脚
  主要是设置lcdcon1--lcdcon5 lcdaddr1--lcdaddr3及LCD控制所使用的GPIO引脚
  的复用功能:GPC,GPD,GPG。其中数据总线与地址总线使用GPC GPD,GPG的引脚4
  作为LCD屏的电源控制引脚。
3>注册frame buffer结构体到内核
  调用内核函数register_framebuffer把分配的fb_info结构体注册到内核中。
  内核中分配了一个长度为32的fb_info类型的数组指针,每注册一个fb_info就把
  其放入到数组中,并把数组的下标做为fb设置的序号给设备使用。然后创建设备
  文件/dev/fbx,由于fbmem.c的初始化函数中已经完成了fb主设备的注册,其已经
  提供了fb设备的 read write ioctl函数,这部分不需要为其进行其实设置
至此整个lcd驱动程序的基本结构就完成了,需要需要写成platform平台驱动的结
构,只需要按其结构修改,并把以上三部分的代码写到其probe函数中。


本来比较简单的程序,调试了几个周才算是完成也是比较纠结,期间也是相当的烦躁
曾经有过放弃的念头(之前移植uboot时也有过类似经历:
默认的nfcont的12位Soft lock是打开的,禁止写nand,但可以读nand,初始化时需要
清0该位,同时清0ECC相关位)。
遇到问题如下:
a> 
  编译后能直接insmod,但是使用echo nihao > /dev/tty1 或 
  cat xx.file > /dev/fb0 屏幕无反应。
  发现/dev/下有fb0与fb1两个设备文件,将上面命令中的tty1换成tty2,fb0换成fb1
  依然没有反应。
<a解决方法:发现源代码中已经存在文件s3c2410fb.c,make menuconfig修改源码
  配置项,把S3C2410FB配置成M,编译内核make uImage,编译模块make modules。
b>然后insmod cfb(三个cfb模块)*.ko和insmod lcd.ko出现段错误,而这时插入
  源码中的s3c2410fb.ko一切正常。
<b这地方卡了好久,曾经一路查看和打印内核源代码,发现程序在console_lock()
  中调用down_console_sem()请求信号量前能打印出信息,之后的信息没有打印出
  来就段错误了,曾经怀疑是busybox的insmod命令代码错误(用的busybox比较新)
  后来看了源码感觉不是它的问题。后来又挂成最新的3.18.0的内核还是同样死在
  请求console的信息量时段错误。于是最后又回归到检查自己的源码的路子上。
  最后发现是在设置 fix.line_length 的参数填写成240*2,填成了列的长度,修改之。
  遇到这样的错误其实首先应该去自己的代码中去仔细检查,找出错误,而不是先
  怀疑别人的代码,kernel,busybox这都是很多编写使用的代码一般发行的版本不会
  有大错误;浪费了大量的时间,当然其间也阅读也一些相关的代码也算是一点收获吧。
c>insmod lcd.ko后,注册成功但是屏幕还是没有反应
<c打印出lcdcon1-lcdaddr1寄存器值查看是否正确,发现打印出的值全是0,怀疑是
  lcd控制器的时钟没有打开,阅读源码中s3c2410fb.c的probe函数中有clk_get相关
  函数调用,于是在初始化LCD控制器前加入
  clk_get(NULL, "lcd")与clk_prepare_enable(lcd_clk)

  使能控制器时钟.默认地内核会关闭不使用的外设的时钟,以降低功率.

  之间还有过一次,设置lcdaddr2时与0x1fffff进行位与运算时少写了一个f,造成屏幕
  不停地在闪烁,像时小时候的黑白电视机在没有台时显示的波纹一样。

d>操作fb0和tty1设备文件,屏幕有反应能显示。在使用16位显示时,通过
  echo nihao > /dev/tty1 能看到屏幕上显示出了nihao但是很不清楚,
  在使用24位色显示时就只能看到屏幕上显示出一个黑块,该问题没能解决。
  应用程序可以通过ioctl获取屏幕的参数,通过mmap系统调用将屏幕的显存映射到
  内存空间中,通过向映射的内存空间写入颜色的值使屏幕点亮。
<d通过在屏幕的四周画线,观察能否在屏幕上看到来校正驱动程序参数。
  通过阅读屏幕的手册参数来设置lcdcon1-lcdcon5就能校正使显示正常。
e>在全屏显示纯色时,屏幕左上角大约有一个7*7像素的黑格在闪
  使用echo nihao > /dev/tty1命令后,发现黑格向下移动
<e这可能是内核默认的支持lcd console功能导致,make menuconfig修改内核配置
  去除该功能 
至此LCD驱动程序移植完毕


驱动程序编码调试成功后静态编译进内核
考虑到编写的驱动程序只是自己使用,就不再为其分类放到内核相应的目录树下,而是
在drivers目录下新建立文件夹live2440_platform,然后把.c文件放到该文件夹下,并
新建Kconfig与Makefile文件,Kconfig与Makefile的写法比较简单可参靠内核源码目录
下的其他文件填充编写。完成后修改drivers目录下的Kconfig,在endmenu前加入
source "drivers/live2440_platform/Kconfig"
修改drivers/Makefile文件 
在最后一行加入
或 写死obj-y += live2440_platform/
obj-$(CONFIG_LIVE2440_PLATFORM) += live2440_platform/
只有修改了drivers/Makefile后编译时make才会进入live2440_platform去执行它下面
的Makefile,否则及时通过make menuconfig配置上选项也不会将其编译进内核
  
最后附上LCD控制器的参数设置:
S3C2440,400MHz--Fclk 100MHz--Hclk 50MHz--Pclk
live2440_lcd_ctrl->lcdcon1 = (5<<8)|(3<<5)|(0xD<<1);
live2440_lcd_ctrl->lcdcon2 = (11<<24)|(239<<14)|(4<<6)|(7<<0);
live2440_lcd_ctrl->lcdcon3 = (8<<19)|(319<<8)|(4<<0);
live2440_lcd_ctrl->lcdcon4 = 7;
live2440_lcd_ctrl->lcdcon5 = (1<<11)|(1<<9)|(1<<8);
live2440_lcd_ctrl->lcdsaddr1 = (live2440_fbinfo->fix.smem_start>>1)&(0x3fffffff);
live2440_lcd_ctrl->lcdsaddr2 = ((live2440_fbinfo->fix.smem_start+live2440_fbinfo->fix.smem_len)>>1)&0x1fffff;
live2440_lcd_ctrl->lcdsaddr3 = 320*32/16;
live2440_lcd_ctrl->lcdcon5 |= (1<<3);
live2440_lcd_ctrl->lcdcon1 |= (1<<0);
  
  
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值