关于linux的fbframebuffer 设备驱动.docx

上传人:b****1 文档编号:13211602 上传时间:2023-06-12 格式:DOCX 页数:56 大小:39.80KB
下载 相关 举报
关于linux的fbframebuffer 设备驱动.docx_第1页
第1页 / 共56页
关于linux的fbframebuffer 设备驱动.docx_第2页
第2页 / 共56页
关于linux的fbframebuffer 设备驱动.docx_第3页
第3页 / 共56页
关于linux的fbframebuffer 设备驱动.docx_第4页
第4页 / 共56页
关于linux的fbframebuffer 设备驱动.docx_第5页
第5页 / 共56页
关于linux的fbframebuffer 设备驱动.docx_第6页
第6页 / 共56页
关于linux的fbframebuffer 设备驱动.docx_第7页
第7页 / 共56页
关于linux的fbframebuffer 设备驱动.docx_第8页
第8页 / 共56页
关于linux的fbframebuffer 设备驱动.docx_第9页
第9页 / 共56页
关于linux的fbframebuffer 设备驱动.docx_第10页
第10页 / 共56页
关于linux的fbframebuffer 设备驱动.docx_第11页
第11页 / 共56页
关于linux的fbframebuffer 设备驱动.docx_第12页
第12页 / 共56页
关于linux的fbframebuffer 设备驱动.docx_第13页
第13页 / 共56页
关于linux的fbframebuffer 设备驱动.docx_第14页
第14页 / 共56页
关于linux的fbframebuffer 设备驱动.docx_第15页
第15页 / 共56页
关于linux的fbframebuffer 设备驱动.docx_第16页
第16页 / 共56页
关于linux的fbframebuffer 设备驱动.docx_第17页
第17页 / 共56页
关于linux的fbframebuffer 设备驱动.docx_第18页
第18页 / 共56页
关于linux的fbframebuffer 设备驱动.docx_第19页
第19页 / 共56页
关于linux的fbframebuffer 设备驱动.docx_第20页
第20页 / 共56页
亲,该文档总共56页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

关于linux的fbframebuffer 设备驱动.docx

《关于linux的fbframebuffer 设备驱动.docx》由会员分享,可在线阅读,更多相关《关于linux的fbframebuffer 设备驱动.docx(56页珍藏版)》请在冰点文库上搜索。

关于linux的fbframebuffer 设备驱动.docx

关于linux的fbframebuffer设备驱动

草稿V2.4.0

1framebuffer设备即帧缓冲设备(简写fb)提供了显示接口的抽象描述。

同时代表着显示接口的存储区,应用程序通过定义好的函数访问,不需要知道底

层的任何操作。

Framebuffer驱动使用的设备节点,通常位于/dev目录,如/dev/fb*.从用

户角度看,fb设备和其他/dev下面的设备类似:

普通的字符设备,主设备号29,

次设备号定义fb的索引。

通常,使用如下方式(前面的数字表示次设备号)

0=/dev/fb0第一个fb设备

1=/dev/fb1第二个fb设备

考虑到向下兼容,可以创建符号链接:

/dev/fb0current->fb0

/dev/fb1current->fb1

fb也是一种普通的内存设备,可以读写其内容。

例如,屏幕抓屏:

cp/dev/fb0myfile

fb虽然可以像内存设备(/dev/mem)一样,对其read,write,seek以及mmap。

但区别在于fb使用的不是整个内存区,而是显存部分。

通过ioctl可以读取或设定fb设备参数,很重要的一点,颜色表(cmap)也

要通过Ioctl设定。

查看就知道有多少ioctl应用以及相关数据结

构。

这里给出摘要:

-你可以获取设备一些不变的信息,如设备名,屏幕的组织(平面,象素,...)

对应内存区的长度和起始地址。

-也可以获取能够改变的信息,例如位深,颜色格式,时序等。

如果你改变这

些值,驱动程序将对值进行优化,以满足设备特性(如果你的设定,设备不支持,

返回EINVAL)。

-你也可以获取或设定部分颜色表。

所有这些特性让应用程序十分容易的使用framebuffer设备。

Xserver可

以使用/dev/fb*而不需知道硬件的寄存器是如何组织的。

XF68_FBDev是一个用

于位映射(单色)Xserver,唯一要做的就是在应用程序在相应的位置设定是否

显示。

在新内核中,帧缓冲设备可以工作于模块中,允许动态加载。

这类驱动必须

调用register_framebuffer()在系统中注册。

之所以对视频模式进行介绍,因为在后面的一些数据结构中,会出现对视频

模式的参数描述。

CRT显示器用3个电子枪轰击磷粉完成颜色的显示。

电子枪必须完成从左到草稿V2.4.0

2右的水平扫描和从上至下的垂直扫描。

改变枪的电压,对应显示的颜色可以不同。

当电子枪完成一行扫描重新回到下一行的开始,被称为“水平折回”。

当一屏幕

全部扫描完毕,电子枪从底部回到左上角,被称为“垂直折回”。

在折回的途中

电子枪是关闭的。

电子枪打点的移动速度取决于点时钟。

如果点时钟是28.37516MHz,打一

个点需要35242ps。

1/(28.37516E6Hz)=35.242E-9s

如果屏幕分辨率是640x480,那么一行的时间是:

640*35.242E-9s=22.555E-6s

然而水平折回也是需要时间的,通常272个点时钟单位,因此扫描一行需要

的时间就是:

(640+272)*35.242E-9s=32.141E-6s

由此得到水平扫描的频率是31KHz:

1/(32.141E-6s)=31.113E3Hz

若屏幕有480行,加上垂直折回时间49个行时钟单位,刷新一屏所需时间:

(480+49)*32.141E-6s=17.002E-3s

由此得到垂直扫描的频率是59Hz:

1/(17.002E-3s)=58.815Hz

这意味着屏幕数据每秒钟刷新59次。

为了得到稳定的图像显示效果,VESA

标准规定垂直扫描频率不低于72Hz。

但也因人而异,有些人在50Hz时就感觉不

到闪烁,而另一些则要在80Hz以上才可。

由于显示器不知道何时开始新的一行扫描,因此需要为行扫描提供水平同步

信号。

类似的,也为每一帧显示提供垂直同步信号。

图像在屏幕上点的位置取决

于这些同步信号的发生时刻。

下图给出了所有时序的概要。

水平折回的时间就是左边空白+右边空白+水

平同步长度。

垂直折回的时间就是上空白+下空白+垂直同步长。

+----------+--------------------------------------------+----------+-------+

||^|||

|||upper_margin|||

||?

|||

+----------###############################################----------+-------+

|#^#||

|left#|#right|hsync|

|margin#|xres#margin|len|

|<-------->#<---------------+--------------------------->#<-------->|<----->|

|#|#||

|#|#||

|#|yres#||

|#|#||

|#|#||

|#|#||

|#?

#||草稿V2.4.0

3+----------###############################################----------+-------+

||^|||

|||lower_margin|||

||?

|||

+----------+---------------------------------------------+----------+-------+

||^|||

|||vsync_len|||

||?

|||

+----------+---------------------------------------------+----------+-------+把XFree86时序变成fb时序

典型的显示模式:

"800x600"508008569761040600637643666

DCFHRSH1SH2HFLVRSV1SV2VFL

而帧缓冲设备使用下面的参数:

-pixclock:

点时钟inps(picoseconds)

-left_margin:

timefromsynctopicture

-right_margin:

timefrompicturetosync

-upper_margin:

timefromsynctopicture

-lower_margin:

timefrompicturetosync

-hsync_len:

lengthofhorizontalsync

-vsync_len:

lengthofverticalsync

1)Pixelclock:

xfree:

inMHz

fb:

inpicoseconds(ps)

pixclock=1000000/DCF

2)horizontaltimings:

left_margin=HFL-SH2

right_margin=SH1-HR

hsync_len=SH2-SH1

3)verticaltimings:

upper_margin=VFL-SV2

lower_margin=SV1-VR

vsync_len=SV2-SV1

1.2

下面给出了一个framebuffer驱动例子,并添加详细注释。

通过阅读该例,

希望大家对framebuffer驱动初步了解。

后面我们将分析用到的数据结构,以及草稿V2.4.0

4其中成员变量和成员函数的功能和意义。

/*linux/drivers/video/anakinfb.c

*Copyright(C)2001AlephOneLtd.forAcuniaN.V.

*

*Thisprogramisfreesoftware;youcanredistributeitand/ormodify

*itunderthetermsoftheGNUGeneralPublicLicenseversion2as

*publishedbytheFreeSoftwareFoundation.

*Changelog:

23-Apr-2001TTCCreated

*/

#include

#include

#include

#include

#include

#include

#include

#include

#include

staticu16colreg[16];//颜色描述表,cmap的简化描述

staticintcurrcon=0;//当前的console索引

staticstructfb_infofb_info;

staticstructdisplaydisplay;

staticintanakinfb_getcolreg(u_intregno,u_int*red,u_int*green,

u_int*blue,u_int*transp,structfb_info*info)

{

if(regno>15)//共有16色,故索引不大于15

return1;

//颜色描述的位深16位,分别是R:

G:

B=5:

6:

5;后面的补齐操作采用了左移

低位补齐方式,只要和setcloreg运算相反即可,也可以使用高位补齐方式。

*red=colreg[regno]&0xf800;

*green=colreg[regno]&0x7e0<<5;//移到高字节,凑足16位

*blue=colreg[regno]&0x1f<<11;//移到高字节,凑足16位

*transp=0;//不支持透明度

return0;//成功返回0,参考fb_get_cmap实现,就知道这里为什么是0。

}

staticintanakinfb_setcolreg(u_intregno,u_intred,u_intgreen,u_int草稿V2.4.0

5blue,u_inttransp,structfb_info*info)

{

if(regno>15)

return1;

//根据索引,设置颜色表的颜色值

colreg[regno]=(red&0xf800)|(green&0xfc00>>5)|

(blue&0xf800>>11);

return0;

}

//从fb_info结构获取fb_fix_screeninfo信息。

由于我们在anakinfb_init

中并没有设置fb_info.fix的值,所以只有在此函数内通过常值赋予。

staticintanakinfb_get_fix(structfb_fix_screeninfo*fix,intcon,

structfb_info*info)

{

//fix全部为0

memset(fix,0,sizeof(structfb_fix_screeninfo));

//id作为字符串标识用

strcpy(fix->id,"AnakinFB");

//显存的起始物理地址

fix->smem_start=VGA_START;

//显存所占的字节数

fix->smem_len=VGA_SIZE;

//象素显示

fix->type=FB_TYPE_PACKED_PIXELS;

//下面的略,参考后面fb_fix_srceeninfo结构

fix->type_aux=0;

fix->visual=FB_VISUAL_TRUECOLOR;

fix->xpanstep=0;

fix->ypanstep=0;

fix->ywrapstep=0;

//每行所占字节数,xres=400

fix->line_length=400*2;

//显卡无硬件加速

fix->accel=FB_ACCEL_NONE;

return0;

}

staticintanakinfb_get_var(structfb_var_screeninfo*var,intcon,

structfb_info*info)

{

//var初始化为0

memset(var,0,sizeof(structfb_var_screeninfo));

//x方向分辨率草稿V2.4.0

6var->xres=400;

//y方向分辨率

var->yres=234;

//虚拟分辨率,不支持pan,故和实际分辨率一致

var->xres_virtual=400;

var->yres_virtual=234;

var->xoffset=0;

var->yoffset=0;

//色深16位,5:

6:

5结构

var->bits_per_pixel=16;

//彩色,非灰度,bpp<8,grayscale=1

var->grayscale=0;

//根据R:

G:

B=5:

6:

5得下面数据

var->red.offset=11;

var->red.length=5;

var->green.offset=5;

var->green.length=6;

var->blue.offset=0;

var->blue.length=5;

//不支持透明度

var->transp.offset=0;

var->transp.length=0;

var->nonstd=0;

var->activate=FB_ACTIVATE_NOW;

//下面解释略

var->height=-1;

var->width=-1;

var->pixclock=0;

var->left_margin=0;

var->right_margin=0;

var->upper_margin=0;

var->lower_margin=0;

var->hsync_len=0;

var->vsync_len=0;

var->sync=0;

var->vmode=FB_VMODE_NONINTERLACED;

return0;

}

//此函数直接返回,表明fb_var_screeninfo是不希望被修改的,这和显示器有

关。

若显示模式只有400*234*16一种,则set_var没有意义。

staticintanakinfb_set_var(structfb_var_screeninfo*var,intcon,

structfb_info*info)

{草稿V2.4.0

7return-EINVAL;

}

//获取颜色表

staticintanakinfb_get_cmap(structfb_cmap*cmap,intkspc,intcon,

structfb_info*info)

{

if(con==currcon)//通常会成立

returnfb_get_cmap(cmap,kspc,anakinfb_getcolreg,info);

elseif(fb_display[con].cmap.len)

fb_copy_cmap(&fb_display[con].cmap,cmap,kspc?

0:

2);

else

fb_copy_cmap(fb_default_cmap(16),cmap,kspc?

0:

2);

return0;

}

//设置颜色表

staticintanakinfb_set_cmap(structfb_cmap*cmap,intkspc,intcon,

structfb_info*info)

{

interr;

if(!

fb_display[con].cmap.len){

if((err=fb_alloc_cmap(&fb_display[con].cmap,16,0)))

returnerr;

}

if(con==currcon)//通常会成立

returnfb_set_cmap(cmap,kspc,anakinfb_setcolreg,info);

else

fb_copy_cmap(cmap,&fb_display[con].cmap,kspc?

0:

1);

return0;

}

//console切换

staticintanakinfb_switch_con(intcon,structfb_info*info)

{

currcon=con;

return0;

}

//通知console更新var

staticintanakinfb_updatevar(intcon,structfb_info*info)

{

return0;草稿V2.4.0

8}

//开关显示用

staticvoidanakinfb_blank(intblank,structfb_info*info)

{

/*

*TODO:

useI2Ctoblank/unblankthescreen

*/

}

//定义structfb_ops结构

staticstructfb_opsanakinfb_ops={

owner:

THIS_MODULE,

fb_get_fix:

anakinfb_get_fix,

fb_get_var:

anakinfb_get_var,

fb_set_var:

anakinfb_set_var,

fb_get_cmap:

anakinfb_get_cmap,

fb_set_cmap:

anakinfb_set_cmap,

};

//fb驱动初始化函数

int__initanakinfb_init(void)

{

//fb_info变量全部置0

memset(&fb_info,0,sizeof(structfb_info));

//对fb_info.modename赋值为”AnakinFB”

strcpy(fb_info.modename,"AnakinFB");

//fb_info.node=-1,后面调用register_framebuffer,会重新设该值为

/dev/fbx节点

fb_info.node=-1;

//fb_info.flags指明fb驱动的内核加载方式

fb_info.flags=FBINFO_FLAG_DEFAULT;

//定义fb_info的fops

fb_info.fbops=&anakinfb_ops;

//fb_info.disp是提供fbcon的基础

fb_info.disp=&display;

//fb_info.fontname表示fbcon采用的字体为VGA8X16

strcpy(fb_info.fontname,"VGA8x16");

fb_info.changevar=NULL;

//console切换时调用函数anakinfb_switch_con

fb_info.switch_con=&anakinfb_switch_con;

//下面2个函数没有操作,直接返回

fb_info.updatevar=&anakinfb_updatevar;

fb_info.blank=&anakinfb_blank;

//display初始化为0草稿V2.4.0

9memset(&display,0,sizeof(structdisplay));

//对display.var赋值,参考anakinfb_get_var函数

anakinfb_get_var(&display.var,0,&fb_info);

//显存的起始地址

display.screen_base=ioremap(VGA_START,VGA_SIZE);

//显示的颜色模式

display.visual=FB_VISUAL_TRUECOLOR;

//象素

display.type=FB_TYPE_PACKED_PIXELS;

display.type_aux=0;

display.ypanstep=0;

display.ywrapstep=0;

//每行字节数,每行400象素,16位色深,故400*2

display.line_length=400*2;

display.can_soft_blank=1;

//颜色反转显示标志

display.inverse=0;

#ifdefFBCON_HAS_CFB16//内核配置参数

//fbcon的底层操作函数

display.dispsw=&fbcon_cfb16;

//辅助数据,意义不大

display.dispsw_data=colreg;

#else//此情况基本不会发生

display.dispsw=&fbcon_dummy;

#endif

//注册framebuffer

if(register_framebuffer(&fb_info)<0)

return-EINVAL;

MOD_INC_USE_COUNT;

return0;

}

MODULE_AUTHOR("Tak-ShingChan");

MODULE_DESCRIPTION("Anakinframebufferdriver");

MODULE_SUPPORTED_DEVICE("fb");

Thefb_opsStructureThe

structureishowaframebufferdriversetsupthisconnection.Thestructure,defined

in,isacollectionoffunctionpointers.Eachopenfile(representedinternallybyafilestructure,whichwewillexamineshortly)isassociatedwithitsownsetoffunctions(by

includingafieldcalledfb_opthatpointstoafile_operationsstructure).Theoperationsare草稿V2.4.0

10

mostlyinchargeofimplementingthesystemcallsandaretherefore,namedopen,read,andsoon.

Wecanconsiderthefiletobean“object”andthefunctionsoperatingonittobeits“methods,”

usingobject-orientedprogrammingterminologytodenoteactionsdeclaredbyanobjecttoacton

itself.Thisisthefirstsignofobject-orientedprogrammingweseeintheLinuxkernel,and

we’llseemoreinlaterchapters.

Conventionally,afile_operationsstructureorapointertooneiscalledfbops(orsomevariation

thereof).Eachfieldinthestructuremustpointtothefunctioninthedriverthatimplements

aspecificoperation,orbeleftNULLforunsupportedoperations.

Theexactbehavioro

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 自然科学 > 物理

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2