linux的lcd驱动详细讲解.docx
- 文档编号:7613472
- 上传时间:2023-01-25
- 格式:DOCX
- 页数:29
- 大小:69.73KB
linux的lcd驱动详细讲解.docx
《linux的lcd驱动详细讲解.docx》由会员分享,可在线阅读,更多相关《linux的lcd驱动详细讲解.docx(29页珍藏版)》请在冰豆网上搜索。
linux的lcd驱动详细讲解
嵌入式驱动程序Day12
Top
1.LCD驱动设计开发
1LCD驱动设计开发
1.1问题
通过lcd驱动开发掌握linux内核framebuffer驱动开发通用方法。
1.2方案
一、帧缓冲(Framebuffer)。
帧缓冲(Framebuffer)是Linux为显示设备提供的一个接口,Linux抽象出FrameBuffer这个设备来供用户态进程实现直接写屏。
Framebuffer机制模仿显卡的功能,将显卡硬件结构抽象掉,可以通过Framebuffer的读写直接对显存进行操作。
用户可以将Framebuffer看成是显示内存的一个映像,将其映射到进程地址空间之后,就可以直接进行读写操作,而写操作可以立即反应在屏幕上。
这种操作是抽象的,统一的。
用户不必关心物理显存的位置、换页机制等等具体细节。
这些都是由Framebuffer设备驱动来完成的。
Framebuffer本身不具备任何运算数据的能力,就只好比是一个暂时存放水的水池。
CPU将运算后的结果放到这个水池,水池再将结果流到显示器,中间不会对数据做处理。
应用程序也可以直接读写这个水池的内容。
在应用程序中,一般通过将FrameBuffer设备映射到进程地址空间的方式使用,比如下面的程序就打开/dev/fb0设备,并通过mmap系统调用进行地址映射。
FrameBuffer设备还提供了若干ioctl命令,通过这些命令,可以获得显示设备的一些固定信息(比如显示内存大小)、与显示模式相关的可变信息(比如分辨率、象素结构、每扫描线的字节宽度),以及伪彩色模式下的调色板信息等等。
二、FrameBuffer在Linux中的实现和机制。
Framebuffer对应的源文件在linux/drivers/video/目录下。
总的抽象设备文件为fbcon.c,在这个目录下还有与各种显卡驱动相关的源文件。
1.分析Framebuffer设备驱动。
FrameBuffer设备驱动基于如下两个文件:
(1)linux/include/linux/fb.h
(2)linux/drivers/video/fbmem.c
2.分析这两个文件。
(1)fb.h。
几乎主要的结构都是在这个中文件定义的。
这些结构包括:
1)fb_var_screeninfo结构体。
这个结构描述了显示卡的特性:
__u32是表示unsigned不带符号的32bits的数据类型,其余类推。
这是Linux内核中所用到的数据类型,如果是开发用户空间(user-space)的程序,可以根据具体计算机平台的情况,用unsignedlong等等来代替。
structfb_var_screeninfo
{
__u32xres;//可视区域
__u32yres;
__u32xres_virtual;//可视区域
__u32yres_virtual;
__u32xoffset;//可视区域的偏移
__u32yoffset;
__u32bits_per_pixel;//每一象素的bit数
__u32grayscale;//等于零就成黑白
structfb_bitfieldred;
structfb_bitfieldgreen;/*elseonlylengthissignificant*/
structfb_bitfieldblue;
structfb_bitfieldtransp;//透明
__u32nonstd;//不是标准格式
__u32activate;/*seeFB_ACTIVATE_**/
__u32height;//内存中的图像高度
__u32width;//内存中的图像宽度
__u32accel_flags;//加速标志
//时序-_-这些部分就是显示器的显示方法
__u32pixclock;/*pixelclockinps(picoseconds)*/
__u32left_margin;/*timefromsynctopicture*/
__u32right_margin;/*timefrompicturetosync*/
__u32upper_margin;/*timefromsynctopicture*/
__u32lower_margin;
__u32hsync_len;/*lengthofhorizontalsync*/水平可视区域
__u32vsync_len;/*lengthofverticalsync*/垂直可视区域
__u32sync;/*seeFB_SYNC_**/
__u32vmode;/*seeFB_VMODE_**/
__u32reserved[6];//备用-以后开发
};
2)fb_fix_screeninfon结构体。
这个结构在显卡被设定模式后创建,它描述显示卡的属性,并且系统运行时不能被修改;比如FrameBuffer内存的起始地址。
它依赖于被设定的模式,当一个模式被设定后,内存信息由显示卡硬件给出,内存的位置等信息就不可以修改。
structfb_fix_screeninfo{
charid[16];/*identificationstringeg"TTBuiltin"*/ID
unsignedlongsmem_start;/*Startofframebuffermem*/内存起始
/*(physicaladdress)*/物理地址
__u32smem_len;/*Lengthofframebuffermem*/内存大小
__u32type;/*seeFB_TYPE_**/
__u32type_aux;/*InterleaveforinterleavedPlanes*/插入区域?
__u32visual;/*seeFB_VISUAL_**/
__u16xpanstep;//没有硬件设备就为零
__u16ypanstep;/*zeroifnohardwarepanning*/
__u16ywrapstep;/*zeroifnohardwareywrap*/
__u32line_length;//一行的字节表示
unsignedlongmmio_start;//内存映射的I/O起始
/*(physicaladdress)*/
__u32mmio_len;//I/O的大小
__u32accel;/*Typeofaccelerationavailable*/可用的加速类型
__u16reserved[3];/*Reservedforfuturecompatibility*/
};
3)fb_cmap结构体。
描述设备无关的颜色映射信息。
可以通过FBIOGETCMAP和FBIOPUTCMAP对应的ioctl操作设定或获取颜色映射信息。
structfb_cmap{
__u32start;/*Firstentry*/第一个入口
__u32len;/*Numberofentries*/入口的数字
__u16*red;/*Redvalues*/红
__u16*green;
__u16*blue;
__u16*transp;/*transparency,canbeNULL*/透明,可以为零
};
4)fb_info结构体。
定义当显卡的当前状态;fb_info结构仅在内核中可见,在这个结构中有一个fb_ops指针,指向驱动设备工作所需的函数集。
structfb_info{
charmodename[40];//默认的视频卡类型
kdev_tnode;
intflags;
intopen;//被打开过么?
#defineFBINFO_FLAG_MODULE1/*Low-leveldriverisamodule*/
structfb_var_screeninfovar;//现在的视频信息
structfb_fix_screeninfofix;//修正的信息
structfb_monspecsmonspecs;//现在的显示器模式
structfb_cmapcmap;//当前优先级
structfb_ops*fbops;
char*screen_base;//物理基址
structdisplay*disp;//初始化
structvc_data*display_fg;/*Consolevisibleonthisdisplay*/
charfontname[40];//默认的字体
devfs_handle_tdevfs_handle;/*Devfshandlefornewname*/
devfs_handle_tdevfs_lhandle;//兼容
int(*changevar)(int);//告诉console变量修改了
int(*switch_con)(int,structfb_info*);
//告诉fb选择consoles
int(*updatevar)(int,structfb_info*);
/*tellfbtoupdatethevars*/告诉fb更新变量
void(*blank)(int,structfb_info*);/*tellfbto(un)blankthescreen*/告诉fb使用黑白模式(或者不黑)
/*arg=0:
unblank*/arg=0的时候黑白模式
/*arg>0:
VESAlevel(arg-1)*/arg>0时候选择VESA模式
void*pseudo_palette;/*Fakepaletteof16colorsand
thecursor'scolorfornon
palettemode*/修正调色板
/*Fromhereoneverythingisdevicedependent*/现在就可以使用了
void*par;
};
5)structfb_ops结构体。
用户应用可以使用ioctl()系统调用来操作设备,这个结构就是用一支持ioctl()的这些操作的。
structfb_ops{
/*open/releaseandusagemarking*/
structmodule*owner;
int(*fb_open)(structfb_info*info,intuser);
int(*fb_release)(structfb_info*info,intuser);
/*getnonsettableparameters*/
int(*fb_get_fix)(structfb_fix_screeninfo*fix,intcon,
structfb_info*info);
/*getsettableparameters*/
int(*fb_get_var)(structfb_var_screeninfo*var,intcon,
structfb_info*info);
/*setsettableparameters*/
int(*fb_set_var)(structfb_var_screeninfo*var,intcon,
structfb_info*info);
/*getcolormap*/
int(*fb_get_cmap)(structfb_cmap*cmap,intkspc,intcon,
structfb_info*info);
/*setcolormap*/
int(*fb_set_cmap)(structfb_cmap*cmap,intkspc,intcon,
structfb_info*info);
/*pandisplay(optional)*/
int(*fb_pan_display)(structfb_var_screeninfo*var,intcon,
structfb_info*info);
/*performfbspecificioctl(optional)*/
int(*fb_ioctl)(structinode*inode,structfile*file,unsignedintcmd,
unsignedlongarg,intcon,structfb_info*info);
/*performfbspecificmmap*/
int(*fb_mmap)(structfb_info*info,structfile*file,structvm_area_struct*vma);
/*switchto/fromrasterimagemode*/
int(*fb_rasterimg)(structfb_info*info,intstart);
};
(2)fbmem.c。
fbmem.c处于Framebuffer设备驱动技术的中心位置。
它为上层应用程序提供系统调用也为下一层的特定硬件驱动提供接口;那些底层硬件驱动需要用到这儿的接口来向系统内核注册它们自己。
fbmem.c为所有支持FrameBuffer的设备驱动提供了通用的接口,避免重复工作。
1)全局变量。
structfb_info*registered_fb[FB_MAX];
intnum_registered_fb;
这两变量记录了所有fb_info结构的实例,fb_info结构描述显卡的当前状态,所有设备对应的fb_info结构都保存在这个数组中,当一个FrameBuffer设备驱动向系统注册自己时,其对应的fb_info结构就会添加到这个结构中,同时num_registered_fb为自动加1。
staticstruct{
constchar*name;
int(*init)(void);
int(*setup)(void);
}fb_drivers[]__initdata={....};
如果FrameBuffer设备被静态链接到内核,其对应的入口就会添加到这个表中;如果是动态加载的,即使用insmod/rmmod,就不需要关心这个表。
staticstructfile_operationsfb_ops={
owner:
THIS_MODULE,
read:
fb_read,
write:
fb_write,
ioctl:
fb_ioctl,
mmap:
fb_mmap,
open:
fb_open,
release:
fb_release
};
这是一个提供给应用程序的接口。
2)fbmem.c实现了如下函数。
Register_framebuffer(structfb_info*fb_info);
unregister_framebuffer(structfb_info*fb_info);
这两个是提供给下层FrameBuffer设备驱动的接口,设备驱动通过这两函数向系统注册或注销自己。
几乎底层设备驱动所要做的所有事情就是填充fb_info结构然后向系统注册或注销它。
三、本案例的操作步骤如下。
1.修改mach-cw210.c源文件,实现LCD设备的初始化。
2.重新编译内核zImage,并将zImage拷贝到/tftpboot下。
3.编写应用测试程序lcd_test.c。
(1)定义宏和变量;
copytextpop-up
1.#defineCOLOR_RED 0x000000FF
2.#defineCOLOR_GREEN 0x0000FF00
3.#defineCOLOR_BLUE 0x00FF0000
4.
5.intfdfb=-1;
6.
7.structfb_fix_screeninfofbfix={0};
8.structfb_var_screeninfofbvar={0};
9.longscreensize=0;
10.
11.int*fb32=NULL;
12.
13.intx=0;
14.inty=0;
15.longlocation=0;
#defineCOLOR_RED0x000000FF
#defineCOLOR_GREEN0x0000FF00
#defineCOLOR_BLUE0x00FF0000
intfdfb=-1;
structfb_fix_screeninfofbfix={0};
structfb_var_screeninfofbvar={0};
longscreensize=0;
int*fb32=NULL;
intx=0;
inty=0;
longlocation=0;
(2)编写main()函数;
1)打开Framebuffer设备文件;
2)使用ioctl()系统调用获取帧缓冲设备中设备无关的固定参数信息;
3)使用ioctl()系统调用获取帧缓冲设备中设备无关的可变参数信息和特定的显示模式;
4)计算显示屏幕上所有点需要的字节数,字节数等于分辨率*每个点占据的字节数;
5)使用函数mmap()将Framebuffer的显存映射到用户空间,使得用户空间可以直接进行读写操作;
6)根据色深,操作显存,在LCD屏上绘制红色、绿色、蓝色三个区域;
7)使用函数munmap()解除对显存的映射;
8)关闭Framebuffer设备。
4.编写Makefile文件。
5.编译LCD驱动模块,并将生成的lcd_test文件拷贝到指定目录下。
6.在TPAD的运行终端上运行应用测试程序,测试驱动程序。
1.3实现
1.修改mach-cw210.c源文件,实现LCD设备的初始化。
修改/home/tarena/workdir/tools/cw210_kernel_2.6.35.7/arch/arm/mach-s5pv210/目录下的mach-cw210.c源文件。
copytextpop-up
1.$cd/home/tarena/workdir/tools/cw210_kernel_2.6.35.7/arch/arm/mach-s5pv210/
2.$vimach-cw210.c
$cd/home/tarena/workdir/tools/cw210_kernel_2.6.35.7/arch/arm/mach-s5pv210/
$vimach-cw210.c
添加源代码如下:
copytextpop-up
1.#elifdefined(CONFIG_FB_AT070TN92)
2.staticstructs3cfb_lcdlte480wv={
3. .width =800,
4. .height =480,
5. .bpp =24,
6. .freq =28,
7. .clkval_f =6,//3
8.// 27,//HBPD
9.// 14,//HFPD
10.// 20,//10,//HSPW
11. .timing={
12. .h_fp =14,//210,
13. .h_bp =27,//16,
14. .h_sw =20,//30,
15. .v_fp =22,
16. .v_fpe =1,
17. .v_bp =10,
18. .v_bpe =1,
19. .v_sw =13,
20. },
21.
22. .polarity={
23. .rise_vclk =0,
24. .inv_hsync =1,
25. .inv_vsync =1,
26. .inv_vden =0,
27. },
28.};
29.
30.staticvoidlte480wv_cfg_gpio(structplatform_device*pdev)
31.{
32.inti;
33.
34.for(i=0;i<8;i++){
35.s3c_gpio_cfgpin(S5PV210_GPF0(i),S3C_GPIO_SFN
(2));
36.s3c_gpio_setpull(S5PV210_GPF0(i),S3C_GPIO_PULL_NONE);
37.}
38.
39.for(i=0;i<8;i++){
40.s3c_gpio_cfgpin(S5PV210_GPF1(i),S3C_GPIO_SFN
(2));
41.s3c_gpio_setpull(S5PV210_GPF1(i),S3C_GPIO_PULL_NONE);
42.}
43.
44.for(i=0;i<8;i++){
45.s3c_gpio_cfgpin(S5PV210_GPF2(i),S3C_GPIO_SFN
(2));
46.s3c_gpio_setpull(S5PV210_GPF2(i),S3C_GPIO_PULL_NONE);
47.}
48.
49.for(i=0;i<4;i++){
50.s3c_gpio_cfgpin(S5PV210_GPF3(i),S3C_GPIO_SFN
(2));
51.s3c_gpio_setpull(S5PV210_GPF3(i),S3C_GPIO_PULL_NONE);
52.}
53.
54./*mDNIeSEL:
whyweshallwrite0x2?
*/
55.writel(0x2,S5P_MDNIE_SEL);
56.
57./*drivestrengthtomax*/
58.writel(0xffffffff,S5PV210_GPF0_BASE+0xc
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- linux lcd 驱动 详细 讲解