微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > 5.Ricoboard开发板上HDMI模块简单分析和使用framebuffer显示bmp文件

5.Ricoboard开发板上HDMI模块简单分析和使用framebuffer显示bmp文件

时间:10-02 整理:3721RD 点击:
HDMI在目前的嵌入式中应用越来越广,关于其定义,相关的cec,edid,hdcp等不做过多介绍。
相对于其他几家芯片厂家的hdmi模块,ti的hdmi子系统又有很多的不同。
dss可以理解为Display Subsystem的简写,翻译过来就是显示子系统,这个硬件模块负责读从存储器取像素数据,发送到lcd或者hdmi显示器。
它分为两大部分:1)DISPC,获取像素数据,颜色转换,组成和其他像素操作;2)编码器,将原始像素数据转化成标准的显示信息,hdmi,或者mipi DPI。
对于一个芯片来说dss还应该包括其他一些有用的解码器,比如dpi dvi等等,还有显示面板。
DISPC又包括overlays和overlay managers,简单的理解,前者负责接收数据,后者负责数据处理。
overlays又分为GFX和VIDEO ,各自支持一些格式,值得注意的是后者支持yuv,而前者不支持。
dss也有一些不支持的属性,不支持HDCP。dss2是dss的升级版本支持hdcp。
下图是dss整体框架。


上面只是dss模块的整体框架,在实际编码中有很多微小的细节需要注意。
sii9022是开发板使用的hdmi芯片,是Silicon Image公司的产品,支持HDMI 1.2a(1.4应该是目前最新的版本)和DVI 1.0,以及下面一些特性。

  1. Integrated TMDS core
  2. ? DTV resolution support - 480i/576i/
  3. 480p/576p/720p/1080i/1080p
  4. ? PC resolution support - VGA/XGA/
  5. SXGA/WSXGA/UXGA
  6. ? Flexible interface to HD MPEG decoders:
  7. - 12/24-bit RGB YCbCr 4:4:4
  8. - 16/20/24-bit YCbCr 4:2:2
  9. - 8/10/12-bit YCbCr 4:2:2
  10. (ITU-R BT.601 & BT.656)
  11. ? Integrated YCbCr —> RGB conversion
  12. ? 4:2:2 —> 4:4:4 up-converter
  13. ? Programmable Data Enable (DE) generator

复制代码

sii9022电路图如下:


下面就简单分析一下hdmi的启动流程。

  1.        
  2.         DT_MACHINE_START(AM33XX_DT, "Generic AM33XX (Flattened Device Tree)")
  3.                 .reserve        = am33xx_reserve,
  4.                 .map_io                = am33xx_map_io,
  5.                 .init_early        = am33xx_init_early,
  6.                 .init_late        = am33xx_init_late,
  7.                 .init_irq        = omap_intc_of_init,
  8.                 .handle_irq        = omap3_intc_handle_irq,
  9.                 .init_machine        = omap_generic_init,
  10.                 .init_late        = am33xx_init_late,
  11.                 .init_time        = omap3_gptimer_timer_init,
  12.                 .dt_compat        = am33xx_boards_compat,
  13.                 .restart        = am33xx_restart,
  14.         MACHINE_END

复制代码

根据启动log我们可以找到一个入口函数,他的实现是在arch/arm/mach-omap2中的board-genreic.c文件中。当然kernel的最开始入口函数不是这个函数,但是对于我们关注的某个soc来说,把DT_MACHINE_START函数作为入口函数足够了。
omap_generic_init -->omapdss_init_of(display.c) -->omap_init_fb(fb.c另外两个函数为return 0;)初始化fb等等。
下面omap_dss_init函数通过module_init(omap_dss_init);加载到kernel中,其实现如下,调用探针函数 omap_dss_probe,初始化dss_init_platform_driver和dispc_init_platform_driver,前者初始化dss2,后者启动dispc,跟前面的介绍很吻合。

  1. static int __init omap_dss_init(void)
  2.         {
  3.                 int r;
  4.                 int i;
  5.                 r = platform_driver_probe(&omap_dss_driver, omap_dss_probe);
  6.                 if (r)
  7.                         return r;
  8.        
  9.                 r = dss_init_platform_driver();
  10.                 if (r) {
  11.                         DSSERR("Failed to initialize DSS platform driver\n");
  12.                         goto err_dss;
  13.                 }
  14.        
  15.                 r = dispc_init_platform_driver();
  16.                 if (r) {
  17.                         DSSERR("Failed to initialize dispc platform driver\n");
  18.                         goto err_dispc;
  19.                 }
  20.        
  21.                 /*
  22.                  * It's ok if the output-driver register fails. It happens, for example,
  23.                  * when there is no output-device (e.g. SDI for OMAP4).
  24.                  */
  25.                 for (i = 0; i ;
  26.         };

复制代码


module_i2c_driver(sil9022_driver); 函数将sil9022_driver模块加载到系统中,且与下面的内容呼应。注意其是module_i2c_driver函数,从这里才能找到一点其他soc中hdmi模块的影子。

  1. module_i2c_driver(sil9022_driver);
  2.                 sii9022: sii9022@3b {
  3.                 compatible = "sii,sii9022";
  4.                 reg = ;
  5.                 reset-gpio = ;
  6.                 video-source = ;
  7.                 data-lines = ;
  8.         };

复制代码


dts中的定义也与下面iic的设备节点对应起来。0x3b


module_platform_driver(panel_dpi_driver);函数将panel_dpi_driver加载到系统中,

  1. static struct platform_driver panel_dpi_driver = {
  2.         .probe = panel_dpi_probe,
  3.         .remove = __exit_p(panel_dpi_remove),
  4.         .driver = {
  5.                 .name = "panel-dpi",
  6.                 .owner = THIS_MODULE,
  7.                 .of_match_table = panel_dpi_of_match,
  8.         },
  9. };

复制代码


panel_dpi_driver与下面的内容呼应。

  1. lcd0: display@0 {
  2.                 compatible = "osddisplays,osd057T0559-34ts", "panel-dpi";
  3.                 video-source = ;
  4.                 data-lines = ;
  5.                 panel-timing {
  6.                         clock-frequency = ;
  7.                         hactive = ;
  8.                         vactive = ;
  9.                         hfront-porch = ;
  10.                         hback-porch = ;
  11.                         hsync-len = ;
  12.                         vback-porch = ;
  13.                         vfront-porch = ;
  14.                         vsync-len = ;
  15.                         hsync-active = ;
  16.                         vsync-active = ;
  17.                         de-active = ;
  18.                         pixelclk-active = ;
  19.                 };
  20.         };

复制代码


根据下面的log,我们可以清晰的看到fb,sii9022,panel-pdi,dss是如何串联起来。

  1. =6=omapfb_probe
  2. =1=omapfb_init_connections
  3. =1=hdmic_connect
  4. =1=hdmic_connect in->ops.hdmi->connect
  5. =1=sil9022_connect
  6. sii9022 1-003b: CONNECT
  7. =2=omapfb_init_connections fbdev->num_displays=2
  8. =2=omapfb_init_connections fbdev->num_displays=2 i=0
  9. =1=panel_dpi_connect
  10. =2=panel_dpi_connect
  11. omapdss APPLY error: manager lcd is already connected to an output
  12. fbcvt: 1024x768@60: CVT Name - .786M3-R
  13. =7=omapfb_probe
  14. create 3 framebuffers
  15. fb_infos allocated
  16. =1=omapdss_default_get_resolution
  17. fbmems allocated
  18. =1=omapdss_default_get_resolution
  19. fb_infos initialized
  20. =1=omapfb_set_par
  21. =2=omapfb_set_par
  22. =3=omapfb_set_par
  23. =1=omapfb_apply_changes
  24. =4=omapfb_set_par
  25. pan_display(0)
  26. Console: switching to colour frame buffer device 128x48
  27. pan_display(0)
  28. framebuffers registered
  29. =1=omapfb_apply_changes
  30. =1=omapfb_apply_changes
  31. =1=omapfb_apply_changes
  32. Enable fb0
  33. create_framebuffers done
  34. =8=omapfb_probe
  35. =1=omapfb_init_display
  36. =1=sil9022_enable
  37. sii9022 1-003b: ENABLE
  38. =2=sil9022_enable
  39. =3=sil9022_enable
  40. =1=sil9022_hw_enable
  41. sii9022 1-003b: HW_ENABLE -> Timings
  42. pixel_clk                       = 56000
  43. horizontal res          = 1024
  44. vertical res                    = 768
  45. sii9022 1-003b: hdmi enabled
  46. =4=sil9022_enable
  47. =2=omapfb_init_display
  48. =3=omapfb_init_display
  49. =6=omapfb_init_display
  50. =9=omapfb_probe

复制代码


omapdss的节点有哪些?


sysfs接口测试
cat /sys/devices/platform/omapdss/overlay0/name
gfx
与介绍中的概念对应起来。
echo "0" > /sys/devices/platform/omapdss/overlay0/enabled
echo "1" > /sys/devices/platform/omapdss/overlay0/enabled
上面两个语句可以控制屏幕的亮灭。
echo 2 > /sys/class/graphics/fb0/rotate可以控制屏幕的旋转180度,只是我们这里运行出错。


另外还有一个问题,不知道大家注意到没有dts和相应的probe函数一一对应,他们会调用几次?
一般情况是一次,但是如果我们想多次调用探针函数可以吗?答案是肯定可以的。
掌握上面的信息,我感觉对于开发板hdmi模块已经有了一个简单的入门,当然更加细节的问题则需要时间继续研究,比如edid如何处理,HDCP如何实现。
帧缓冲(framebuffer)是 Linux 为显示设备提供的一个接口,出现在kernel2.2.x以后,它把显存抽象后的一种设备,他允许上层应用程序在图形模式下直接对显示缓冲区进行读写操作,写操作可以立即反应到显示屏幕上。这种操作是抽象的,统一的。用户不必关心物理显存的位置、换页机制等等具体细节。这些都是由Framebuffer 设备驱动来完成的,所以可知其具有良好的移植性。
       帧缓冲设备对应的设备文件为/dev/fb*,如果系统有多个显示卡,Linux 下还可支持多个帧缓冲设备,最多可达32 个,分别为/dev/fb0 到/dev/fb31,当前缺省的帧缓冲设备通常指向/dev/fb0。当然在嵌入式系统中支持一个显示设备就够了。帧缓冲设备为标准字符设备,主设备号为29,次设备号则从0到31。分别对应/dev/fb0-/dev/fb31。在MID上,设备信息是/dev/graphics/fb0。   
对于我们来说omapfb_driver驱动实现了对framebuffer的支持。

  1. fh = openFB(NULL);
  2.         getVarScreenInfo(fh, &var);
  3.         getFixScreenInfo(fh, &fix);
  4.        
  5. //        fb_mem_offset = (unsigned long)(fix.smem_start) & (~PAGE_MASK);
  6.         fb_mem = (unsigned long int)mmap(NULL, fix.smem_len ,
  7.                 PROT_READ | PROT_WRITE, MAP_SHARED, fh, 0);
  8.                             memcpy((void*)(fb_mem + offset), color, 4);
  9.         closeFB(fh);

复制代码


上面是帧缓冲的简单步骤,附件是我显示bmp的源代码。

下面是运行的结果,一图是没有运行的抓图,二图是显示第一个bmp,三图是显示第二个bmp。




知识点总结:
1.dss;
2.sii9022;
3.probe函数多次调用;
4.framebuffer。

2.49 MB, 下载次数: 10

知识点总结棒棒哒  赞一个

小编的显示是用的什么方法,HDMI还是HDMI转VGA呢?

使用HDMI转dvi线。

HDMI的输出分辨率可以改不

在另外的开发板上改过,米尔的开发板没有试过,板子已经还给厂家。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top