注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

时间记录器

记录我的Linux、Android学习之路

 
 
 

日志

 
 

sep0718_fb 分析(二) sep0718fb_ops  

2010-08-04 15:05:49|  分类: Linux |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
struct fb_ops sep0718fb_ops = {
    .owner          = THIS_MODULE,
    .fb_check_var   = sep0718fb_check_var,
    .fb_set_par     = sep0718fb_set_par,
    .fb_blank       = sep0718fb_blank,
    .fb_pan_display = sep0718fb_pan_display,
    .fb_setcolreg   = sep0718fb_setcolreg,
    .fb_fillrect    = cfb_fillrect,
    .fb_copyarea    = cfb_copyarea,
    .fb_imageblit   = cfb_imageblit,
    .fb_cursor      = soft_cursor,
    .fb_ioctl       = sep0718fb_ioctl,
};
以下是个成员函数的调用和层次关系:
* sep0718fb_ops
 **static int sep0718fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 **static int sep0718fb_set_par(struct fb_info *info)
   ***static void sep0718fb_activate_var(sep0718fb_info_t *fbi, struct fb_var_screeninfo *var)
 **static int sep0718fb_blank(int blank_mode, struct fb_info *info)
 **static int sep0718fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
   ***void sep0718fb_set_fb_addr(sep0718fb_info_t *fbi)
 **static int sep0718fb_setcolreg(unsigned int regno, unsigned int red, unsigned int green, unsigned int blue, 
                                                    unsigned int transp, struct fb_info *info)
   ***static inline unsigned int sep0718fb_chan_to_field(unsigned int chan, struct fb_bitfield bf)
 **static int sep0718fb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
   ***static int sep0718fb_get_pos(struct fb_info *info, overlay_config_t * arg )
   ***static int sep0718fb_get_screen_info(struct fb_info *info, overlay_config_t * arg )
   ***static int sep0718fb_set_position(struct fb_info *info, overlay_config_t * arg )
   ***static int sep0718fb_queue_buffer(struct fb_info *info, unsigned long* arg )
   ***static int sep0718fb_overlay_on_off(struct fb_info *info, unsigned long arg )
   ***static int sep0718fb_overlay_set_alpha(struct fb_info *info, unsigned int alpha_level, unsigned int win_num)
   ***static int sep0718fb_overlay_set_colorkey(struct fb_info *info, unsigned int color_key, unsigned int win_num)

sep0718fb_ops是系统调用的操作接口,与常见的filesoperation结构体类似,用户通过调用结构体中的函数来对设备进行操作。
struct fb_ops中的成员众多,我们的0718只实现了里面的一笑部分:
.fb_check_var       = sep0718fb_check_var,
    .fb_set_par     = sep0718fb_set_par,
    .fb_blank           = sep0718fb_blank,
    .fb_pan_display = sep0718fb_pan_display,
    .fb_setcolreg       = sep0718fb_setcolreg,
    .fb_ioctl           = sep0718fb_ioctl,
以下部分摘抄自leeming师兄的《SEP0718 framebuffer驱动设计文档》
struct fb_ops sep0718fb_ops是整个驱动在初始化结束后会涉及的内容,由于在probe中会将sep0718fb_ops结构体注册到内核中。因此在驱动完成初始化后,其实就是这个结构体在起作用,因此下面讲一下这个结构体所做的工作。在这个结构体中具体是驱动设计到的函数有:
fb_check_var: 在上面的小节中提到对于一个LCD屏来说内核提供了两组数据结构来描述它,一组是可变属性(fb_var_screeninfo描述),另一组是不变属性(fb_fix_screeninfo描述)。对于可变属性,应该防止在操作的过程中出现超出法定范围的情况,因此内核应该可以调用相关函数来检测、并将这些属性固定在法定的范围内。我们在这里的实现主要是针对bits_per_pixel的。

fb_set_var:用户应用程序可通过ioctl对FIX参数进行重新配置,因此在进行这个之前首先会调用check_var保证参数在支持范围内。参数可改变的列表见var结构体,实际应用中主要是改变屏幕bpp和行的长度。这里需要注意的一个地方是在set_var函数的内部我们是通过active函数来使寄存器重新配置的,对寄存器参数进行重新配置时一定要对lcdc先关闭,然后配完了再使能。

fb_pan_display:FBIOPAN_DISPLAY在linux的注释里是“平移显示”的意思。怎么理解呢?就是按照y坐标平移显示缓存中的内容。调用FBIOPAN_DISPLAY时,会传一个y坐标偏移量yoffset给驱动,然后驱动会把当前显存的指针偏移 “yoffset X 屏幕宽度 X 位色字节数” 个字节,这样就好像实现了图像的y坐标平移,也就是“平移显示”。当这个yoffset等于屏幕高度的时候,就实现了显存的切换。由于android中的要求是对y方向平移显示,所以我们在这里的实现也是平移显示的。注意是y平移还是x平移是在sep0718fb_init_fbinfo初始化函数中的  finfo->fb.fix.ypanstep = 1;所决定的。

fb_ioctl:ioctl函数主要是为驱动实现一些framebuffer架构没有包含的一些特殊的特性,用户应用程序可以通过ioctl来操作这些特殊的操作。Sep0718的overlay,alpha blending, color key等功能就是通过此处实现的。
  
fb_blank:在0718驱动中没有去实现


以下主要分析_ioctl 在应用层和驱动层之间的代码实现。
在linux/drivers/video/fbmem.c文件中fb_ioctl函数最终实现I/O控制命令的执行,这些标准命令包括:
    FBIOGET_VSCREENINFO://获得可变的屏幕参数    **
    FBIOPUT_VSCREENINFO://设置可变的屏幕参数   fb_set_var
    FBIOGET_FSCREENINFO://获得固定的屏幕参数    **
    FBIOPUTCMAP:        //设置颜色表             fb_set_cmap
    FBIOGETCMAP:        //获得颜色表             **
    FBIOPAN_DISPLAY:    //pan显示                fb_pan_display
    FBIO_CURSOR:        //
    FBIOGET_CON2FBMAP:  //
    FBIOPUT_CON2FBMAP:  //
    FBIOBLANK://                                fb_blank
    default:
各个命令参数宏定义如下
* ioctls   0x46 is 'F'                              */
#define FBIOGET_VSCREENINFO 0x4600
#define FBIOPUT_VSCREENINFO 0x4601
#define FBIOGET_FSCREENINFO 0x4602
#define FBIOGETCMAP                 0x4604
#define FBIOPUTCMAP                  0x4605
#define FBIOPAN_DISPLAY            0x4606
#ifdef __KERNEL__
#define FBIO_CURSOR            _IOWR('F'0x08struct fb_cursor_user)
#else
#define FBIO_CURSOR            _IOWR('F'0x08struct fb_cursor)
#endif
#define FBIOGET_CON2FBMAP    0x460F
#define FBIOPUT_CON2FBMAP    0x4610
#define FBIOBLANK                       0x4611   /* arg: 0 or vesa level + 1 */
#define FBIOGET_VBLANK     _IOR('F'0x12struct fb_vblank)
#define FBIO_ALLOC                   0x4613
#define FBIO_FREE                     0x4614
#define FBIOGET_GLYPH            0x4615
#define FBIOGET_HWCINFO       0x4616
#define FBIOPUT_MODEINFO     0x4617
#define FBIOGET_DISPINFO       0x4618
这些命令在do_fb_ioctl中被散转,但是fbmem.c文件中还有大量的LCDC具体功能函数,这都是在default中实现的。
default:
        if (!lock_fb_info(info))
            return -ENODEV;
        fb = info->fbops;
        if (fb->fb_ioctl)
            ret = fb->fb_ioctl(info, cmd, arg);
        else
            ret = -ENOTTY;
        unlock_fb_info(info);
在ops中有
.fb_ioctl  =  sep0718fb_ioctl,
挂钩。
fb_ioctl会调用do_fb_ioctl(info, cmd, arg);可以看到,如果应用程序传入的不是标准命令参数,则直接通过
fb->fb_ioctl(info, cmd, arg);把参数传给static int sep0718fb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)了。

在sep0718fb_ioctl(info, cmd, arg)中有如下散转
switch(cmd) 
    {
        case OVERLAY_GET_POSITION:               sep0718fb_get_pos(info, (overlay_config_t*) arg );
        case OVERLAY_GET_SCREEN_INFO:       sep0718fb_get_screen_info(info, (overlay_config_t*) arg );
        case OVERLAY_SET_POSITION:               sep0718fb_set_position(info, (overlay_config_t*) arg);
        case OVERLAY_QUEUE_BUFFER:            sep0718fb_queue_buffer(info, (unsigned long*) arg);
        case OVERLAY_SET_CONFIGURE:         //sep0718fb_set_configure((overlay_config_t*)arg, win_num);
        case OVERLAY_ON_OFF:                         sep0718fb_overlay_on_off(info, arg );
        case OVERLAY_SET_ALPHA1:                 sep0718fb_overlay_set_alpha(info, alpha_level, 1);
        case OVERLAY_SET_ALPHA2:                 sep0718fb_overlay_set_alpha(info, alpha_level, 2);
        case OVERLAY_SET_COLORKEY1:         sep0718fb_overlay_set_colorkey(info, arg, 1);
        case OVERLAY_SET_COLORKEY2:         sep0718fb_overlay_set_colorkey(info, arg, 2);
        default:
    }
各个命令参数宏定义如下
#define OVERLAY_GET_POSITION             0
#define OVERLAY_SET_POSITION             1
#define OVERLAY_GET_SCREEN_INFO     2
#define OVERLAY_QUEUE_BUFFER          3
#define OVERLAY_SET_CONFIGURE        4
#define OVERLAY_ON_OFF                       5
#define OVERLAY_SET_ALPHA1               6
#define OVERLAY_SET_ALPHA2               7
#define OVERLAY_SET_COLORKEY1       8
#define OVERLAY_SET_COLORKEY2       9

可见这些0718使用的cmd参数并不与标准命令参数冲突。

用户使用例程:
例子一:
int fp;
overlay_config_t arg;

fp=open ("/dev/fb0", O_RDWR);;
ioctl(fp,OVERLAY_GET_POSITION,&arg);//获得图层位置相关信息放在arg变量中

例子二:
#include  
int main ()  
{  
    int framebuffer_handler;  
    struct fb_fix_screeninfo fixed_info;  
    struct fb_var_screeninfo variable_info;      
     
    open ("/dev/fb0", O_RDWR); /*in real life, check every ioctl if it returns -1 */  

    ioctl (framebuffer_handler,FBIOGET_VSCREENINFO, &variable_info); variable_info.bits_per_pixel = 32;  

    ioctl(framebuffer_handler, FBIOPUT_VSCREENINFO, &variable_info);  

    ioctl (framebuffer_handler,FBIOGET_FSCREENINFO, &fixed_info);  

    variable_info.yoffset = 513;  

    ioctl (framebuffer_handler,FBIOPAN_DISPLAY, &variable_info);  
}
  评论这张
 
阅读(1781)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017