首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

高清嵌入式系统中的DVI驱2

高清嵌入式系统中的DVI驱2

  调用函数platform_device_register(&mxc_fb_device)和i2c_register_board_info(1, mxc_i2c1_board_info,ARRAY_SIZE(mxc_i2c1_board_info))向系统注册以上设备。

4.2 设备驱动

4.2.1 LCD控制器驱动

  LCD控制器驱动是一个标准的帧缓冲设备驱动。首先在drivers/video/mxc/mxc_ipuv3_fb.c中定义全局结构变量mxcfb_driver:
static struct platform_driver mxcfb_driver={
  .driver={
    .name=MXCFB_NAME,
  },
  .probe=mxcfb_probe,
  .remove=mxcfb_remove,
  .suspend=mxcfb_suspend,
  .resume=mxcfb_resume,
};

  然后,在驱动入口函数mxcfb_init(void)中调用platform_driver_register(&mxcfb_driver)注册驱动,当驱动加载成功后,会自动调用探测函数mxcfb_probe。

  mxcfb_probe是驱动设计中的重要函数。主要负责初始化硬件。申请中断、分配framebuffer所需的内存、注册帧缓冲设备等,以下是与framebuffer相关的操作。

① 调用mxcfb_init_fbinfo(&pdev﹥dev, &mxcfb_ops)函数,在其内通过framebuffer_alloc函数,为mx51帧缓冲信息结构体struct mxcfb_info分配所需空间。参数mxcfb_ops的定义如下:
static struct fb_ops mxcfb_ops={
  .owner=THIS_MODULE,
  .fb_set_par=mxcfb_set_par,
  .fb_check_var=mxcfb_check_var,
  .fb_setcolreg=mxcfb_setcolreg,
  .fb_pan_display=mxcfb_pan_display,
  ……
};

  mxcfb_ops 定义了指向底层操作的一系列函数,这些函数针对MX51帧缓冲操作,是framebuffer核心驱动操作的具体实现。

② 初始化帧缓冲信息结构体fb_info的固定和可变参数,填充fb_var_screeninfo var和fb_fix_screeninfo fix成员。

  定义fbi为struct fb_info 类型的指针,通过fbi﹥fbops = &mxcfb_ops语句,将已定义的文件操作接口mxcfb_ops赋予fb_info结构的fbops成员。

  调用mxcfb_check_var(&fbi﹥var, fbi)函数,检查和调整fb_info结构中变量var的值。var是一个struct fb_var_screeninfo类型的变量,表示显示控制器参数,其中与显示输出状态有关的信息,如屏幕分辨率等将在后面的DVI驱动中设置。

  调用mxcfb_set_fix(fbi)函数,用于填充一个struct fb_fix_screeninfo结构变量fbi﹥fix,它描述了显示输出设备自身的属性。

③ 调用register_framebuffer(fbi)函数,注册帧缓冲驱动程序,该函数只有一个参数,即前面已定义的、指向struct fb_info结构的指针fbi。

4.2.2DVI设备驱动

  LCD控制器将DVI芯片作为它所连接的显示外设,在完成LCD控制器驱动后还需编写DVI设备驱动。在文件drivers/video/mxc/mxcfb_dvi.c中定义驱动结构体:
static struct platform_driver dvi_driver={
  .driver={
  .name="dvi_tfp410"},
  .probe=dvi_probe,
  .remove=__devexit_p(dvi_remove),
  .suspend=dvi_suspend,
  .resume=dvi_resume,
};

  然后,在外设驱动入口函数dvi_init(void)中调用platform_driver_register(&dvi_driver)注册DVI驱动,驱动加载后,系统自动调用探测函数dvi_probe,该函数主要实现以下操作:一是指定framebuffer设备,由于MX51 IPU(图像处理单元)支持多个framebuffer设备,此处要确定DVI究竟使用MX51 IPU framebuffer的哪一个设备;二是填充fb_var_screeninfo结构变量var中有关显示输出状态的信息,如屏幕的显示分辨率、画面位置等,为此在程序中定义结构数组video_modes:

static struct fb_videomode video_modes[]={
  {
  /*1024×768 @ 60 Hz,像素时钟频率为33 MHz */
  "DVITFP410", 60, 1024, 768, 33260, 117, 18, 23, 28, 2, 3,
  0, FB_VMODE_NONINTERLACED,0,
  },
  ……
};

  结构struct fb_videomode用于描述显示输出状态,调用函数“fb_videomode_to_var(&var, &video_modes[0])”将屏幕显示参数转换为var结构变量的相关成员,由于var的部分成员值已在前面LCD控制器驱动中确定,此处完成了对var全部成员的设置。

  一个frambuffer设备由一个struct fb_info结构表示,本设计用fb_info结构的全局变量registered_fb表示系统注册的frambuffer设备,驱动程序的主要任务之一是填充这个结构变量。LCD控制器驱动与DVI外设驱动之间的信息传递,通过该全局变量实现。

5 DVI驱动测试

  首先,通过显示一幅图片测试DVI输出是否正常。通过转换工具(如Image2lcd)把一幅1024×768大小的jpg图片转换为RGB 888分辨率、1024×768的RGB格式的二进制图片。然后键入命令: cp pic.bin /dev/fb0,此时图片显示于屏幕上。接下来,再使用MX51的视频解码测试程序播放一个720P的视频H.264文件,可以看到视频播放清晰流畅,效果很好。

结语

  经测试,DVI驱动程序在MX51平台上成功实现。framebuffer是Linux提供给用户的一个直接面向显示缓冲区的接口,本设计是一个面向应用的framebuffer驱动,文中给出了DVI驱动的整体架构,对主要模块的设计思想和实现方法进行了详细的介绍。
返回列表