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,以及下面一些特性。
下面就简单分析一下hdmi的启动流程。
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,跟前面的介绍很吻合。
module_i2c_driver(sil9022_driver); 函数将sil9022_driver模块加载到系统中,且与下面的内容呼应。注意其是module_i2c_driver函数,从这里才能找到一点其他soc中hdmi模块的影子。
dts中的定义也与下面iic的设备节点对应起来。0x3b
module_platform_driver(panel_dpi_driver);函数将panel_dpi_driver加载到系统中,
panel_dpi_driver与下面的内容呼应。
根据下面的log,我们可以清晰的看到fb,sii9022,panel-pdi,dss是如何串联起来。
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的支持。
上面是帧缓冲的简单步骤,附件是我显示bmp的源代码。
下面是运行的结果,一图是没有运行的抓图,二图是显示第一个bmp,三图是显示第二个bmp。
知识点总结:
1.dss;
2.sii9022;
3.probe函数多次调用;
4.framebuffer。
相对于其他几家芯片厂家的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,以及下面一些特性。
- Integrated TMDS core
- ? DTV resolution support - 480i/576i/
- 480p/576p/720p/1080i/1080p
- ? PC resolution support - VGA/XGA/
- SXGA/WSXGA/UXGA
- ? Flexible interface to HD MPEG decoders:
- - 12/24-bit RGB YCbCr 4:4:4
- - 16/20/24-bit YCbCr 4:2:2
- - 8/10/12-bit YCbCr 4:2:2
- (ITU-R BT.601 & BT.656)
- ? Integrated YCbCr —> RGB conversion
- ? 4:2:2 —> 4:4:4 up-converter
- ? Programmable Data Enable (DE) generator
下面就简单分析一下hdmi的启动流程。
-
- DT_MACHINE_START(AM33XX_DT, "Generic AM33XX (Flattened Device Tree)")
- .reserve = am33xx_reserve,
- .map_io = am33xx_map_io,
- .init_early = am33xx_init_early,
- .init_late = am33xx_init_late,
- .init_irq = omap_intc_of_init,
- .handle_irq = omap3_intc_handle_irq,
- .init_machine = omap_generic_init,
- .init_late = am33xx_init_late,
- .init_time = omap3_gptimer_timer_init,
- .dt_compat = am33xx_boards_compat,
- .restart = am33xx_restart,
- MACHINE_END
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,跟前面的介绍很吻合。
- static int __init omap_dss_init(void)
- {
- int r;
- int i;
- r = platform_driver_probe(&omap_dss_driver, omap_dss_probe);
- if (r)
- return r;
-
- r = dss_init_platform_driver();
- if (r) {
- DSSERR("Failed to initialize DSS platform driver\n");
- goto err_dss;
- }
-
- r = dispc_init_platform_driver();
- if (r) {
- DSSERR("Failed to initialize dispc platform driver\n");
- goto err_dispc;
- }
-
- /*
- * It's ok if the output-driver register fails. It happens, for example,
- * when there is no output-device (e.g. SDI for OMAP4).
- */
- for (i = 0; i ;
- };
module_i2c_driver(sil9022_driver); 函数将sil9022_driver模块加载到系统中,且与下面的内容呼应。注意其是module_i2c_driver函数,从这里才能找到一点其他soc中hdmi模块的影子。
- module_i2c_driver(sil9022_driver);
- sii9022: sii9022@3b {
- compatible = "sii,sii9022";
- reg = ;
- reset-gpio = ;
- video-source = ;
- data-lines = ;
- };
dts中的定义也与下面iic的设备节点对应起来。0x3b
module_platform_driver(panel_dpi_driver);函数将panel_dpi_driver加载到系统中,
- static struct platform_driver panel_dpi_driver = {
- .probe = panel_dpi_probe,
- .remove = __exit_p(panel_dpi_remove),
- .driver = {
- .name = "panel-dpi",
- .owner = THIS_MODULE,
- .of_match_table = panel_dpi_of_match,
- },
- };
panel_dpi_driver与下面的内容呼应。
- lcd0: display@0 {
- compatible = "osddisplays,osd057T0559-34ts", "panel-dpi";
- video-source = ;
- data-lines = ;
- panel-timing {
- clock-frequency = ;
- hactive = ;
- vactive = ;
- hfront-porch = ;
- hback-porch = ;
- hsync-len = ;
- vback-porch = ;
- vfront-porch = ;
- vsync-len = ;
- hsync-active = ;
- vsync-active = ;
- de-active = ;
- pixelclk-active = ;
- };
- };
根据下面的log,我们可以清晰的看到fb,sii9022,panel-pdi,dss是如何串联起来。
- =6=omapfb_probe
- =1=omapfb_init_connections
- =1=hdmic_connect
- =1=hdmic_connect in->ops.hdmi->connect
- =1=sil9022_connect
- sii9022 1-003b: CONNECT
- =2=omapfb_init_connections fbdev->num_displays=2
- =2=omapfb_init_connections fbdev->num_displays=2 i=0
- =1=panel_dpi_connect
- =2=panel_dpi_connect
- omapdss APPLY error: manager lcd is already connected to an output
- fbcvt: 1024x768@60: CVT Name - .786M3-R
- =7=omapfb_probe
- create 3 framebuffers
- fb_infos allocated
- =1=omapdss_default_get_resolution
- fbmems allocated
- =1=omapdss_default_get_resolution
- fb_infos initialized
- =1=omapfb_set_par
- =2=omapfb_set_par
- =3=omapfb_set_par
- =1=omapfb_apply_changes
- =4=omapfb_set_par
- pan_display(0)
- Console: switching to colour frame buffer device 128x48
- pan_display(0)
- framebuffers registered
- =1=omapfb_apply_changes
- =1=omapfb_apply_changes
- =1=omapfb_apply_changes
- Enable fb0
- create_framebuffers done
- =8=omapfb_probe
- =1=omapfb_init_display
- =1=sil9022_enable
- sii9022 1-003b: ENABLE
- =2=sil9022_enable
- =3=sil9022_enable
- =1=sil9022_hw_enable
- sii9022 1-003b: HW_ENABLE -> Timings
- pixel_clk = 56000
- horizontal res = 1024
- vertical res = 768
- sii9022 1-003b: hdmi enabled
- =4=sil9022_enable
- =2=omapfb_init_display
- =3=omapfb_init_display
- =6=omapfb_init_display
- =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的支持。
- fh = openFB(NULL);
- getVarScreenInfo(fh, &var);
- getFixScreenInfo(fh, &fix);
-
- // fb_mem_offset = (unsigned long)(fix.smem_start) & (~PAGE_MASK);
- fb_mem = (unsigned long int)mmap(NULL, fix.smem_len ,
- PROT_READ | PROT_WRITE, MAP_SHARED, fh, 0);
- memcpy((void*)(fb_mem + offset), color, 4);
- closeFB(fh);
上面是帧缓冲的简单步骤,附件是我显示bmp的源代码。
下面是运行的结果,一图是没有运行的抓图,二图是显示第一个bmp,三图是显示第二个bmp。
知识点总结:
1.dss;
2.sii9022;
3.probe函数多次调用;
4.framebuffer。
2.49 MB, 下载次数: 10
知识点总结棒棒哒 赞一个
小编的显示是用的什么方法,HDMI还是HDMI转VGA呢?
使用HDMI转dvi线。
HDMI的输出分辨率可以改不
在另外的开发板上改过,米尔的开发板没有试过,板子已经还给厂家。