我是靠谱客的博主 幽默小猫咪,最近开发中收集的这篇文章主要介绍LCD 驱动调试,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

为一块新的LCD屏编写了驱动,然后编译进内核,下载到开发板上,这时候,屏幕也许除了背光,没有其它任何的显示,这个时候,我们应该怎么进行调试呢?下面是几个最基本的问题:

  • 如何确定LCD驱动加载了呢?
  • LCD驱动的基本信息是否正确呢,如何检查?
  • 能否通过应用程序来对LCD屏幕进行控制呢?这里的FrameBuffer的应用程序如何编写呢?

下面是一些我现在用到的办法:

命令行查看FrameBuffer的信息

# cat /proc/fb
//在/proc目录,查看当前系统中的帧缓冲设备
0 jz-lcd
1 jz-slcd
# ls /dev/fb*
//查看/dev目录下的不同的帧缓冲设备
/dev/fb0
/dev/fb1

可以看到,现在系统中有两个帧缓冲设备。其中第0个帧缓存设备/dev/fb0,对应的是LCD控制器(jz-lcd)的驱动,而第1个帧缓存设备/dev/fb1,就是智能LCD控制器(jz-slcd)的驱动。可以在./drivers/video/目录下面的驱动文件(这里是jzlcd.c文件和jz4740_slcd.c文件)中看到/proc/fb中命名和注册。

static struct lcd_cfb_info * jzfb_alloc_fb_info(void)
{
……
strcpy(cfb->fb.fix.id, "jz-lcd");	//这里的字符串"jz-lcd"就是在/proc/fb中看到的打印信息,修改这里可以在/proc/fb中看到相应的改动
……
}
static int __init jzfb_init(void)
{
……
err = register_framebuffer(&cfb->fb);
if (err < 0) {
dprintk("jzfb_init(): register framebuffer err.n");
goto failed;
}
……
}

register_framebuffer()函数就是将LCD控制器(jz-lcd)的驱动注册到frame buffer中,这样才有我们看到的/proc/fb中的帧缓存设备0 jz-lcd以及/dev/fb0设备描述符。同理,我们还可以同时将智能LCD控制器(jz-slcd)的驱动注册到frame buffer中。

可以看到,frame buffer作为驱动程序,是各种不同的显示设备对OS,应用层的一个统一的接口,一个驱动接口。

在刚开始的时候,由于没有在.config文件中将jz-lcd驱动选项去掉,所以加载了两个帧缓冲设备,如上面所示。

命令行查看FrameBuffer的中断信息

查看到帧设备之后,那么帧设备有没有工作呢?我们可以通过产看中断的办法,大概的看到帧设备是否工作。

# cat /proc/interrupts
CPU0
3:
2
INTC
ohci_hcd:usb1
9:
5758
INTC
serial
14:
0
INTC
MMC/SD
15:
0
INTC
rtc
17:
0
INTC
cim
23:
73137
INTC
jz-timerirq
30:
0
INTC
lcd
32:
0
DMA
auto
33:
0
DMA
MMC Rx
34:
0
DMA
MMC Tx
35:
0
DMA
audio adc
36:
0
DMA
audio dac
150:
0
GPIO
udc_pnp
158:
0
GPIO
MMC card detect
173:
0
GPIO
poweroff
ERR:
0

通过打印/proc/interrupts的信息,可以看到30号中断,对应上面的jz-lcd驱动,而32号中断,是DMA中断,名字为auto,这其实对应jz-slcd的中断,jz4740_slcd.c文件中有下面的代码为证:

static int slcd_dma_init(void)
{
/* Request DMA channel and setup irq handler */
dma_chan = jz_request_dma(DMA_ID_AUTO, "auto", slcd_dma_irq, 0, NULL);
if (dma_chan < 0) {
printk("Request DMA Failedn");
return -1;
}
printk("DMA channel %d is requested by SLCD!n", dma_chan);
……
}

可以看到,这驱动中,通过jz_request_dma()函数请求可一个DMA通道,名字为auto,并且注册了DMA中断函数slcd_dma_irq()。通过查看内核启动信息,也可以验证这一点。

# cat /proc/
……
DMA channel 0 is requested by SLCD!
……

其中,cat /proc/interrupts的输出第二列表示进入这个中断的次数。可以看到,进入jz-lcd和auto的中断次数为0次,也就是从没有进入过中断。没有进入过中断,就没有DMA将图像从内存写入显存(GRAM)的过程,LCD上没有图像显示,也就不足为奇了。

查看内核启动信息

查看内核启动时的输出信息是最直接,有效的调试方式。可以在命令行下使用klog命令,也可以直接接串口获得内核启动信息。下面就下面的输出做出分析:

fb_alloc_cmap,fb.cmap.len:256....
dbg::drivers/video/jz4740_slcd.c,LINE(221): regno:0,RGBt:(0,0,0,65535)
dbg::drivers/video/jz4740_slcd.c,LINE(221): regno:1,RGBt:(0,0,43690,65535)
……
//省略了regno:2~regno:253
dbg::drivers/video/jz4740_slcd.c,LINE(221): regno:254,RGBt:(44767,65503,65519,65535)
dbg::drivers/video/jz4740_slcd.c,LINE(221): regno:255,RGBt:(65535,65535,65535,65535)
jzfb_set_var: after fb_set_cmap...
slcd_hw_init---------jzfb.w:240jzfb.h:320,jzfb.bpp:16
in order to init slcd SLCD_CFG=0x4400
SLCDC: PixClock:16000000 LcdClock:28000000
SLCD_CFG=0x4400
jzfb_set_pardbg::drivers/video/jz4740_slcd.c,LINE(460): var.yoffset: 0
dbg::drivers/video/jz4740_slcd.c,LINE(221): regno:0,RGBt:(0,0,0,65535)
dbg::drivers/video/jz4740_slcd.c,LINE(221): regno:1,RGBt:(0,0,43690,65535)
……
//省略了regno:2~regno:13
dbg::drivers/video/jz4740_slcd.c,LINE(221): regno:14,RGBt:(65535,65535,21845,65535)
dbg::drivers/video/jz4740_slcd.c,LINE(221): regno:15,RGBt:(65535,65535,65535,65535)
Console: switching to colour frame buffer device 30x40
dbg::drivers/video/jz4740_slcd.c,LINE(460): var.yoffset: 0
dbg::drivers/video/jz4740_slcd.c,LINE(221): regno:0,RGBt:(0,0,0,65535)
dbg::drivers/video/jz4740_slcd.c,LINE(221): regno:1,RGBt:(0,0,43690,65535)
……
//省略了regno:2~regno:13
dbg::drivers/video/jz4740_slcd.c,LINE(221): regno:14,RGBt:(65535,65535,21845,65535)
dbg::drivers/video/jz4740_slcd.c,LINE(221): regno:15,RGBt:(65535,65535,65535,65535)
dbg::drivers/video/jz4740_slcd.c,LINE(221): regno:0,RGBt:(0,0,0,65535)
dbg::drivers/video/jz4740_slcd.c,LINE(221): regno:1,RGBt:(0,0,43690,65535)
……
//省略了regno:2~regno:13
dbg::drivers/video/jz4740_slcd.c,LINE(221): regno:14,RGBt:(65535,65535,21845,65535)
dbg::drivers/video/jz4740_slcd.c,LINE(221): regno:15,RGBt:(65535,65535,65535,65535)
fb0: jz-ny-slcd frame buffer device, using 256K of video memory
DMA channel 0 is requested by SLCD!

之所以有上面这么多的输出信息,是因为驱动文件中原来定义的调试宏被打开了,并且,你也可以在你自己觉得有疑问,需要打印的地方加入输出信息。 打开调试宏的办法: 例如在文件jz4740_slcd.c中,

//#undef DEBUG
//如果不想打印调试信息,那么就使用这一句
#define DEBUG
//如果想打印调试信息,使用这一句
#ifdef DEBUG
#define dprintk(x...)	printk(x)
#else
#define dprintk(x...)
#endif

原来#define DEBUG是被注释掉的,现在去掉注释,然后将#undef DEBUG注释掉。这样,下面文件中使用到的dprintk()函数就会使用printk()函数做内核的输出答应。

至于添加答应操作,那么就使用dprintk()函数就可以了,用法和printf()类似。

最后

以上就是幽默小猫咪为你收集整理的LCD 驱动调试的全部内容,希望文章能够帮你解决LCD 驱动调试所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(53)

评论列表共有 0 条评论

立即
投稿
返回
顶部