⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 关于frambuffer - ~ 悠悠风信子 ~ - csdnblog.htm

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 HTM
📖 第 1 页 / 共 5 页
字号:
            !supportLists]--&gt;二、&lt;!--[endif]--&gt;FrameBuffer在LINUX中实现和机制</P>
            <P>Framebuffer对应的源文件在linux/drivers/video/目录下。总的抽象设备文件为fbcon.c,在这个目录下还有与各种显卡驱动相关的源文件。</P>
            <P>(一)、分析Framebuffer设备驱动</P>
            <P>&nbsp;&nbsp;&nbsp; 需要特别提出的是在INTEL平台上,老式的VESA 1.2 
            卡,如CGA/EGA卡,是不能支持Framebuffer的,因为Framebuffer要求显卡支持线性帧缓冲,即CPU可以访问显缓冲中的每一位,但是VESA 
            1.2 卡只能允许CPU一次访问64K的地址空间。</P>
            <P>FrameBuffer设备驱动基于如下两个文件:</P>
            <P>1) linux/include/linux/fb.h<BR>2) linux/drivers/video/fbmem.c</P>
            <P>下面分析这两个文件。</P>
            <P>1、fb.h</P>
            <P>&nbsp;&nbsp; 几乎主要的结构都是在这个中文件定义的。这些结构包括:</P>
            <P>1)fb_var_screeninfo</P>
            <P>&nbsp;&nbsp; 这个结构描述了显示卡的特性:</P>
            <P>struct fb_var_screeninfo </P>
            <P>{<BR>__u32 xres; /* visible resolution */<BR>__u32 yres;<BR>__u32 
            xres_virtual; /* virtual resolution */<BR>__u32 
            yres_virtual;<BR>__u32 xoffset; /* offset from virtual to visible 
            resolution */<BR>__u32 yoffset; </P>
            <P>__u32 bits_per_pixel; /* guess what */<BR>__u32 grayscale; /* != 
            0 Gray levels instead of colors */</P>
            <P>struct fb_bitfield red; /* bitfield in fb mem if true color, 
            */<BR>struct fb_bitfield green; /* else only length is significant 
            */<BR>struct fb_bitfield blue;<BR>struct fb_bitfield transp; /* 
            transparency */</P>
            <P>__u32 nonstd; /* != 0 Non standard pixel format */</P>
            <P>__u32 activate; /* see FB_ACTIVATE_* */</P>
            <P>__u32 height; /* height of picture in mm */<BR>__u32 width; /* 
            width of picture in mm */</P>
            <P>__u32 accel_flags; /* acceleration flags (hints) */</P>
            <P>/* Timing: All values in pixclocks, except pixclock (of course) 
            */<BR>__u32 pixclock; /* pixel clock in ps (pico seconds) 
            */<BR>__u32 left_margin; /* time from sync to picture */<BR>__u32 
            right_margin; /* time from picture to sync */<BR>__u32 upper_margin; 
            /* time from sync to picture */<BR>__u32 lower_margin;<BR>__u32 
            hsync_len; /* length of horizontal sync */<BR>__u32 vsync_len; /* 
            length of vertical sync */<BR>__u32 sync; /* see FB_SYNC_* 
            */<BR>__u32 vmode; /* see FB_VMODE_* */<BR>__u32 reserved[6]; /* 
            Reserved for future compatibility */<BR>};</P>
            <P>2) 
            fb_fix_screeninfon<BR>这个结构在显卡被设定模式后创建,它描述显示卡的属性,并且系统运行时不能被修改;比如FrameBuffer内存的起始地址。它依赖于被设定的模式,当一个模式被设定后,内存信息由显示卡硬件给出,内存的位置等信息就不可以修改。</P>
            <P>struct fb_fix_screeninfo {<BR>char id[16]; /* identification 
            string eg "TT Builtin" */<BR>unsigned long smem_start; /* Start of 
            frame buffer mem */<BR>/* (physical address) */<BR>__u32 smem_len; 
            /* Length of frame buffer mem */<BR>__u32 type; /* see FB_TYPE_* 
            */<BR>__u32 type_aux; /* Interleave for interleaved Planes 
            */<BR>__u32 visual; /* see FB_VISUAL_* */<BR>__u16 xpanstep; /* zero 
            if no hardware panning */<BR>__u16 ypanstep; /* zero if no hardware 
            panning */<BR>__u16 ywrapstep; /* zero if no hardware ywrap 
            */<BR>__u32 line_length; /* length of a line in bytes */<BR>unsigned 
            long mmio_start; /* Start of Memory Mapped I/O */<BR>/* (physical 
            address) */<BR>__u32 mmio_len; /* Length of Memory Mapped I/O 
            */<BR>__u32 accel; /* Type of acceleration available */<BR>__u16 
            reserved[3]; /* Reserved for future compatibility */<BR>};</P>
            <P>3) fb_cmap<BR>描述设备无关的颜色映射信息。可以通过FBIOGETCMAP 和 FBIOPUTCMAP 
            对应的ioctl操作设定或获取颜色映射信息.</P>
            <P>struct fb_cmap {<BR>__u32 start; /* First entry */<BR>__u32 len; 
            /* Number of entries */<BR>__u16 *red; /* Red values */<BR>__u16 
            *green;<BR>__u16 *blue;<BR>__u16 *transp; /* transparency, can be 
            NULL */<BR>};</P>
            <P>4) fb_info<BR>定义当显卡的当前状态;fb_info结构仅在内核中可见,在这个结构中有一个fb_ops指针, 
            指向驱动设备工作所需的函数集。</P>
            <P>struct fb_info {<BR>char modename[40]; /* default video mode 
            */<BR>kdev_t node;<BR>int flags;<BR>int open; /* Has this been open 
            already ? */<BR>#define FBINFO_FLAG_MODULE 1 /* Low-level driver is 
            a module */<BR>struct fb_var_screeninfo var; /* Current var 
            */<BR>struct fb_fix_screeninfo fix; /* Current fix */<BR>struct 
            fb_monspecs monspecs; /* Current Monitor specs */<BR>struct fb_cmap 
            cmap; /* Current cmap */<BR>struct fb_ops *fbops;<BR>char 
            *screen_base; /* Virtual address */<BR>struct display *disp; /* 
            initial display variable */<BR>struct vc_data *display_fg; /* 
            Console visible on this display */<BR>char fontname[40]; /* default 
            font name */<BR>devfs_handle_t devfs_handle; /* Devfs handle for new 
            name */<BR>devfs_handle_t devfs_lhandle; /* Devfs handle for compat. 
            symlink */<BR>int (*changevar)(int); /* tell console var has changed 
            */<BR>int (*switch_con)(int, struct fb_info*);<BR>/* tell fb to 
            switch consoles */<BR>int (*updatevar)(int, struct fb_info*);<BR>/* 
            tell fb to update the vars */<BR>void (*blank)(int, struct 
            fb_info*); /* tell fb to (un)blank the screen */<BR>/* arg = 0: 
            unblank */<BR>/* arg &gt; 0: VESA level (arg-1) */<BR>void 
            *pseudo_palette; /* Fake palette of 16 colors and<BR>the cursor's 
            color for non<BR>palette mode */<BR>/* From here on everything is 
            device dependent */<BR>void *par;<BR>};</P>
            <P>5) struct 
            fb_ops<BR>用户应用可以使用ioctl()系统调用来操作设备,这个结构就是用一支持ioctl()的这些操作的。</P>
            <P>struct fb_ops {<BR>/* open/release and usage marking */<BR>struct 
            module *owner;<BR>int (*fb_open)(struct fb_info *info, int 
            user);<BR>int (*fb_release)(struct fb_info *info, int user);<BR>/* 
            get non settable parameters */<BR>int (*fb_get_fix)(struct 
            fb_fix_screeninfo *fix, int con,<BR>struct fb_info *info);<BR>/* get 
            settable parameters */<BR>int (*fb_get_var)(struct fb_var_screeninfo 
            *var, int con,<BR>struct fb_info *info);<BR>/* set settable 
            parameters */<BR>int (*fb_set_var)(struct fb_var_screeninfo *var, 
            int con,<BR>struct fb_info *info);<BR>/* get colormap */<BR>int 
            (*fb_get_cmap)(struct fb_cmap *cmap, int kspc, int con,<BR>struct 
            fb_info *info);<BR>/* set colormap */<BR>int (*fb_set_cmap)(struct 
            fb_cmap *cmap, int kspc, int con,<BR>struct fb_info *info);<BR>/* 
            pan display (optional) */<BR>int (*fb_pan_display)(struct 
            fb_var_screeninfo *var, int con,<BR>struct fb_info *info);<BR>/* 
            perform fb specific ioctl (optional) */<BR>int (*fb_ioctl)(struct 
            inode *inode, struct file *file, unsigned int cmd,<BR>unsigned long 
            arg, int con, struct fb_info *info);<BR>/* perform fb specific mmap 
            */<BR>int (*fb_mmap)(struct fb_info *info, struct file *file, struct 
            vm_area_struct *vma);<BR>/* switch to/from raster image mode 
            */<BR>int (*fb_rasterimg)(struct fb_info *info, int 
start);<BR>};</P>
            <P>6) structure map<BR>struct fb_info_gen | struct fb_info | 
            fb_var_screeninfo<BR>| | fb_fix_screeninfo<BR>| | fb_cmap<BR>| | 
            modename[40]<BR>| | fb_ops ---|---&gt;ops on var<BR>| | ... | 
            fb_open<BR>| | | fb_release<BR>| | | fb_ioctl<BR>| | | fb_mmap<BR>| 
            struct fbgen_hwswitch -|-&gt; detect<BR>| | encode_fix<BR>| | 
            encode_var<BR>| | decode_fix<BR>| | decode_var<BR>| | get_var<BR>| | 
            set_var<BR>| | getcolreg<BR>| | setcolreg<BR>| | pan_display<BR>| | 
            blank<BR>| | set_disp</P>
            <P>[编排有点困难,第一行的第一条竖线和下面的第一列竖线对齐,第一行的第二条竖线和下面的第二列竖线对齐就可以了]<BR>这个结构 
            fbgen_hwswitch抽象了硬件的操作.虽然它不是必需的,但有时候很有用.</P>
            <P>2、 fbmem.c<BR>fbmem.c 处于Framebuffer设备驱动技术的中心位置.它为上层应用程序提供系统调用 
            也为下一层的特定硬件驱动提供接口;那些底层硬件驱动需要用到这儿的接口来向系统内核注册它们自己. fbmem.c 
            为所有支持FrameBuffer的设备驱动提供了通用的接口,避免重复工作.</P>
            <P>1) 全局变量</P>
            <P>struct fb_info *registered_fb[FB_MAX];<BR>int 
            num_registered_fb;</P>
            <P><BR>这两变量记录了所有fb_info 结构的实例,fb_info 结构描述显卡的当前状态,所有设备对应的fb_info 
            结构都保存在这个数组中,当一个FrameBuffer设备驱动向系统注册自己时,其对应的fb_info 
            结构就会添加到这个结构中,同时num_registered_fb 为自动加1.</P>
            <P>static struct {<BR>const char *name;<BR>int (*init)(void);<BR>int 
            (*setup)(void);<BR>} fb_drivers[] __initdata= { ....};</P>
            <P>如果FrameBuffer设备被静态链接到内核,其对应的入口就会添加到这个表中;如果是动态加载的,即使用insmod/rmmod,就不需要关心这个表。</P>
            <P>static struct file_operations fb_ops ={<BR>owner: 
            THIS_MODULE,<BR>read: fb_read,<BR>write: fb_write,<BR>ioctl: 
            fb_ioctl,<BR>mmap: fb_mmap,<BR>open: fb_open,<BR>release: 
            fb_release<BR>};<BR>这是一个提供给应用程序的接口.</P>
            <P>2)fbmem.c 实现了如下函数.</P>
            <P>register_framebuffer(struct fb_info 
            *fb_info);<BR>unregister_framebuffer(struct fb_info *fb_info);</P>
            <P>这两个是提供给下层FrameBuffer设备驱动的接口,设备驱动通过这两函数向系统注册或注销自己。几乎底层设备驱动所要做的所有事情就是填充fb_info结构然后向系统注册或注销它。</P>
            <P>(二)一个LCD显示芯片的驱动实例</P>
            <P>以Skeleton LCD 
            控制器驱动为例,在LINUX中存有一个/fb/skeleton.c的skeleton的Framebuffer驱动程序,很简单,仅仅是填充了fb_info结构,并且注册/注销自己。设备驱动是向用户程序提供系统调用接口,所以我们需要实现底层硬件操作并且定义file_operations结构来向系统提供系统调用接口,从而实现更有效的LCD控制器驱动程序。</P>
            <P>1)在系统内存中分配显存<BR>在fbmem.c文件中可以看到, file_operations 
            结构中的open()和release()操作不需底层支持,但read()、write()和 
            mmap()操作需要函数fb_get_fix()的支持.因此需要重新实现函数fb_get_fix()。另外还需要在系统内存中分配显存空间,大多数的LCD控制器都没有自己的显存空间,被分配的地址空间的起始地址与长度将会被填充到fb_fix_screeninfo 
            结构的smem_start 和smem_len 的两个变量中.被分配的空间必须是物理连续的。</P>
            <P>2)实现 fb_ops 中的函数<BR>用户应用程序通过ioctl()系统调用操作硬件,fb_ops 
            中的函数就用于支持这些操作。(注: fb_ops结构与file_operations 
            结构不同,fb_ops是底层操作的抽象,而file_operations是提供给上层系统调用的接口,可以直接调用.<BR>&nbsp; 
            ioctl()系统调用在文件fbmem.c中实现,通过观察可以发现ioctl()命令与fb_ops’s 
            中函数的关系:<BR>FBIOGET_VSCREENINFO fb_get_var<BR>FBIOPUT_VSCREENINFO 
            fb_set_var<BR>FBIOGET_FSCREENINFO fb_get_fix<BR>FBIOPUTCMAP 
            fb_set_cmap<BR>FBIOGETCMAP fb_get_cmap<BR>FBIOPAN_DISPLAY 
            fb_pan_display</P>
            <P><BR>如果我们定义了fb_XXX_XXX 方法,用户程序就可以使用FBIOXXXX宏的ioctl()操作来操作硬件。</P>
            <P>文件linux/drivers/video/fbgen.c或者linux/drivers/video目录下的其它设备驱动是比较好的参考资料。在所有的这些函数中fb_set_var()是最重要的,它用于设定显示卡的模式和其它属性,下面是函数fb_set_var()的执行步骤: 
            </P>
            <P>1)检测是否必须设定模式<BR>2)设定模式</P>
            <P>3)设定颜色映射</P>
            <P>4) 根据以前的设定重新设置LCD控制器的各寄存器。</P>
            <P>第四步表明了底层操作到底放置在何处。在系统内存中分配显存后,显存的起始地址及长度将被设定到LCD控制器的各寄存器中(一般通过fb_set_var() 
            函数),显存中的内容将自动被LCD控制器输出到屏幕上。另一方面,用户程序通过函数mmap()将显存映射到用户进程地址空间中,然后用户进程向映射空间发送的所有数据都将会被显示到LCD显示器上。</P>
            <P>&lt;!--[if !supportEmptyParas]--&gt; &lt;!--[endif]--&gt;</P>
            <P>&lt;!--[if 
            !supportLists]--&gt;三、&lt;!--[endif]--&gt;FrameBuffer的应用</P>
            <P>(一)、一个使用FrameBuffer的例子</P>
            <P>1、FrameBuffer主要是根据VESA标准的实现的,所以只能实现最简单的功能。</P>
            <P>2、由于涉及内核的问题,FrameBuffer是不允许在系统起来后修改显示模式等一系列操作。(好象很多人都想要这样干,这是不被允许的,当然如果你自己写驱动的话,是可以实现的).</P>
            <P>3、对FrameBuffer的操作,会直接影响到本机的所有控制台的输出,包括XWIN的图形界面。</P>
            <P>好,现在可以让我们开始实现直接写屏:</P>
            <P>1、打开一个FrameBuffer设备</P>
            <P>2、通过mmap调用把显卡的物理内存空间映射到用户空间</P>
            <P>3、直接写内存。</P>
            <P>/********************************</P>
            <P>File name : fbtools.h</P>
            <P>*/</P>
            <P>#ifndef _FBTOOLS_H_</P>
            <P>#define _FBTOOLS_H_</P>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -