调试一台自研HDMI采集盒时,客户反馈接上4K显示器后采集端永远只有1920x1080@30,xrandr列出的模式也无法开到2160p。我当时没有急着查驱动,第一件事就是抓EDID。原因很简单:HDMI链路上源端和接收端第一次握手,靠的就是那颗挂在DDC通道上的EEPROM——EDID读不到、读不全、读出来校验不过,后面所有分辨率、音频、色彩协商都是空谈。EDID全称Extended Display Identification Data,E-EDID是它的扩展形态,基本块加扩展块一起,撑起了一条HDMI链路从“能否点亮”到“能跑多高规格”的全部信息。这篇文章就把EDID/E-EDID从协议原理、数据结构、硬件设计到Linux下的实际验证完整过一遍。
1. 从一次“识别不到显示器”说起:EDID在HDMI链路里的真实地位
1.1 没有EDID,源端就是“盲人摸象”
先想一个问题:HDMI把显卡和显示器连在一起,显卡怎么知道对面的显示器最高支持多少分辨率、刷新率是多少、支不支持HDR、音频采样率能做到多高?
答案是它不知道,全靠显示器主动“自报家门”。这个自报家门的数据结构就是EDID。EDID存放在显示设备(sink)端的EEPROM里,通常是一颗24C02或者更大容量的存储芯片,然后显卡(source)通过DDC(Display Data Channel)通道把数据读走。DDC底子上就是I2C总线,在HDMI连接器上对应15脚SCL和16脚SDA,EDID设备的7位I2C地址固定是0x50,写地址0xA0、读地址0xA1。
为什么说没有EDID源端就是盲人摸象?因为HDMI不像传统的VGA模拟接口可以通过行场同步信号来推断一个大概的时序范围,数字链路上必须明确告诉源端“我支持哪些时序、用哪种色彩格式、默认分辨率是什么”。有一次我把一个EDID读出来是空的显示器接到PC上,系统只能按640x480@60的最低安全模式输出,画面错位、颜色发灰,完全不可用。这就是没有EDID信息的典型表现。
提示:EDID不只是给显卡用的。HDMI采集卡、扩展坞、视频处理器、矩阵切换器,凡是作为HDMI source去读取对面设备的角色,都要依赖EDID来决定输出什么时序。设计和调试HDMI产品,EDID读取链路的重要性仅次于物理层信号完整性。
1.2 DDC通道与HDMI 19脚热插拔的来龙去脉
DDC协议是从VGA时代就有的。当初CRT显示器需要被系统识别出型号和时序参数,VESA定义了一套通过I2C读取显示器信息的机制,那时候叫DDC1/DDC2B。到了DVI和HDMI时代,这个机制被原封不动继承下来。HDMI的DDC通道就是I2C总线,电气特性和时序要求基本一致,但有一个关键角色是整个读取动作的“触发器”——热插拔检测引脚(Hot Plug Detect,HPD)。
HPD在HDMI连接器上是19脚。它的工作逻辑很直观:sink端检测到5V电源过来后,把HPD引脚拉高,source端检测到这个上升沿就知道“对面来了个HDMI设备,可以开始读EDID了”。如果HPD一直处于低电平,源端根本不会去枚举这个HDMI输出口,连/sys/class/drm下的HDMI节点都可能不出现。
这个机制在设计上容易踩坑的点在于时序配合。HDMI规范要求:sink端上电后,等到可以稳定提供EDID读取能力时再拉高HPD。实际做产品时,如果HPD由MCU固件控制,你要确保MCU上电初始化I2C外设、EEPROM准备好之后,才允许HPD输出高电平。否则就会出现“HPD已经拉高了,但源端去读0x50地址时读不到数据”这种经典问题。
1.3 为什么会有E-EDID:128字节的边界与扩展机制
最早的EDID只有128字节,也就是一个基本块。128字节能装什么?一个显示器的基础身份、物理尺寸、色彩特性、若干标准时序和一个详细时序描述符,基本就到顶了。可HDMI面对的场景远比CRT时代复杂:声道数、音频编码格式、YCbCr 4:4:4支持、Deep Color、3D、4K60、动态HDR,哪一个都得有对应的信息位。
于是VESA在EDID 1.3之后引入了扩展块机制。一个EDID整体由基本块(Base Block)加若干扩展块(Extension Block)组成,每个扩展块仍是128字节。基本块的第126个字节专门记录“后面还有多少个扩展块”。这种结构就是E-EDID(Enhanced EDID)。
这里有个容易忽略的点:扩展块本身不规定内容,它只是容器。具体装什么由扩展块的Tag决定,HDMI设备最常见的就是Tag 0x02的CEA-861扩展块。也就是说,E-EDID这个词不是指某一个特定版本,而是指“基本块+扩展块”这个整体体系。你在Linux下用edid-decode解析一份真实显示器的EDID,看到的第一部分是Basic Display Parameters,后面跟着CEA Extension Block,那就是一份标准的E-EDID。
2. 128字节基本块逐字节拆解:设备身份与基本能力
2.1 Header、厂商ID与产品信息
EDID基本块的前128字节是根,所有信息都从这里延伸出去。第一个字段是8字节的Header,固定为00 FF FF FF FF FF FF 00。这不是巧合,而是一个同步标志:读EDID时先检查这8个字节,如果对不上,说明总线上的设备可能不对,或者数据线时序有问题。我调试时最常干的一件事就是hexdump看开头,一旦开头不是这个值,基本就能判断是地址错误或者读到了错误的I2C设备。
厂商ID和产品信息分布在后面几个字节。厂商ID是PNP ID,不是ASCII字符串,而是16位压缩编码:每5位表示一个字母,A对应0,B对应1,依此类推。比如某大厂“DEL”解出来会是一个16位数值,edid-decode会直接展示成“DEL”。接下来的产品代码和序列号都是厂商自定义的,没有固定格式含义,但调试时可以通过它们交叉确认“我拿到的是不是这台设备的EDID”。
生产周和生产年份在第16和17字节,其中年份是相对1990年的偏移值,比如0x20表示2022年(0x20=32,1990+32=2022)。当然,这个值是EEPROM烧录时写的,有的厂商干脆固定写一个不变的生产周期。这是正常的,不用较真。
2.2 显示特性与色彩参数
基本块第20字节是显示参数特性,最关键的bit7表示输入类型:置1为数字输入(HDMI/DVI),置0为模拟输入(VGA)。做HDMI产品时,这个位必须是1,否则某些严格的驱动会把设备当作VGA显示器处理,行为会变得很奇怪。
第21和22字节分别表示最大水平图像尺寸和最大垂直图像尺寸,单位是厘米。这个数值很多实际产品写得并不准确,但对系统来说,它会影响PPI计算和字体缩放,不是功能关键项。
第23字节是Gamma值,表达式是(byte + 100) / 100,比如0x78(120)表示gamma 2.20。第24字节是特性支持位图,里面最值得关注的是bit7(Preferred Timing Mode):如果置1,表示第一个Detailed Timing Descriptor(详细时序描述符)里的那个时序是显示器推荐使用的原生时序。这个位决定了Linux framebuffer初始分辨率,很多4K显示器开机默认就能到4K,靠的就是它。
色度信息占据第25到34字节,一共10个字节,分别存放红、绿、蓝、白四色的x/y色度坐标,每个坐标由“2位低精度+8位高精度”组成。实际解析出来的是一串小数,比如红色x=0.640、红色y=0.330。这个数据对普通用户没多大用,但做色彩校准或者HDR相关的产品时,是判断“这台显示器色域覆盖到哪”的重要依据。
2.3 Established/Standard/Detailed Timings三层时序表
基本块里描述时序的方式有三层,这是EDID的精髓设计。
第一层是Established Timings,共3个字节的位置,用位图来表示一批“远古协议时代就定死”的时序,比如640x480@60、800x600@60、1024x768@60这些。置1表示支持。这层信息量不大,但胜在固定,所有设备都必须兼容。
第二层是Standard Timings,在偏移38到53的位置,一共8组,每组2字节。第一字节表示水平像素数(单位是8像素的倍数,再减31),第二字节的高2位表示宽高比(00=16:10、01=4:3、10=5:4、11=16:9),低6位表示刷新率(60Hz起算的偏移值)。注意:如果某个标准时序项的值是01 01,表示该项未使用。读取时需要留意,不要把它当成真实分辨率。
第三层是Detailed Timing Descriptors(DTD),从偏移54开始,共4组,每组18字节。这是EDID里信息密度最高、也最复杂的部分。一个完整DTD包含像素时钟、水平活动像素/消隐、垂直活动像素/消隐、同步极性等信息。像素时钟以10kHz为单位存储,比如1920x1080@60需要148.5MHz,存的值就是14850。另外,如果DTD最前面的像素时钟字段为0,那这18字节不是时序描述,而是显示器描述字符串,比如:
- Tag
0xFC:显示器名称,ASCII字符串 - Tag
0xFF:显示器序列号 - Tag
0xFD:显示器频率范围限制(最小/最大垂直刷新率、水平频率、最大像素时钟) - Tag
0xFE:未指定ASCII文字
第1组DTD通常就是Preferred Timing Mode。剩下的3组可以存备选时序,也可以存显示器描述字符串。很多工具直接读出来显示器型号“DELL U2720Q”,靠的就是0xFC描述符。
3. CEA扩展块与HDMI VSDB:4K、深色、多声道藏在这里
3.1 CEA扩展块的数据块体系
基本块只保证基本可用,但HDMI真正的高规格信息全部落在扩展块里。最核心的是Tag 0x02的CEA-861扩展块,它是消费电子协会定义的格式。
CEA扩展块的头部结构是:第0字节Tag=0x02,第1字节是CEA版本号,第2字节的高位表示是否存在详细时序描述符(DTD),低5位表示DTD数据在扩展块内的偏移。从第3字节开始是一系列Data Block。每个Data Block的头部1字节,高3位是Tag编码,低5位是数据长度,后面跟着实际数据。
常见的数据块Tag包括:
| Tag | 含义 |
|---|---|
| 0x02 | Video Data Block(视频数据块) |
| 0x03 | Audio Data Block(音频数据块) |
| 0x04 | Speaker Allocation Data Block(扬声器分配) |
| 0x60 | Vendor Specific Data Block(HDMI VSDB就是这类格式) |
视频数据块里是一串VIC(Video Identification Code)编号。VIC 1是640x480@60,VIC 4是1280x720@60,VIC 16是1920x1080@60,VIC 31是3840x2160@30,VIC 32是3840x2160@60。这个编号标准由CEA-861定义,HDMI源端看到VIC 32,才知道对面支持2160p60。
这里有个坑要特别注意:VIC只是“支持列表”,不保证可用。比如HDMI 1.4时代的电视虽然可以报VIC 32,但VSDB里的最大TMDS时钟如果没达到600MHz,源端同样不会输出4K60。我之前调试一块显卡输出4K显示器时,信号总是锁定在4K30,查下来就是VSDB的TMDS时钟字段只支持到300MHz。
VIC列表里的数据还可能带标志位:bit7置1表示该时序是显示器的native时序,适合作为默认输出。这是除了基本块Preferred Timing之外的另一个偏好信号,同样要留意。
3.2 HDMI Vendor Specific Data Block解析
HDMI VSDB是HDMI规格特有的配置块,格式上几乎等同于CEA的Vendor Specific Data Block,但层次上被HDMI规范强制要求。它前三个字节是IEEE注册的OUI(Organizationally Unique Identifier),取值为00 0C 03,这是HDMI Licensing Administrator注册的标识。做HDMI协议分析时看到这个OUI,就直接锁定它是HDMI相关的VSDB。
VSDB里包含的信息对设计格外重要:
- 最高TMDS时钟:以5MHz为单位。例如600(0x4B0)对应3GHz?注意这里数值单位是5MHz,所以如果字段值是0x78(120),最高TMDS时钟就是600MHz,这是HDMI 2.0的能力。
- 物理地址(Physical Address):用于CEC路由寻址,是HDMI网络中每个节点位置的唯一标识。
- Deep Color支持位:判断sink是否支持30/36/48位色深。
- 3D支持标志:3D格式声明。
- HDMI 2.1相关扩展:包含FRL模式的最大速率等字段。
对于做HDMI接口设计的工程师来说,VSDB不只是给系统用的,它还是HDMI一致性测试中的必测项。如果EEPROM里的VSDB写错了,比如OUI写反、物理地址冲突、TMDS时钟字段超范围,HDMI合规测试基本过不了。我的习惯是每拿到一个显示器或电视的EDID,先edid-decode看VSDB里OUI和物理地址,确认无误再继续分析其他字段。
3.3 音频数据块与扬声器分配
音频数据块(Audio Data Block)由若干短音频描述符(Short Audio Descriptor,SAD)构成,每个SAD占3字节。第一个SAD的第一个字节高4位表示音频格式:1是LPCM,2是AC-3,7是Dolby Digital Plus,9是DTS等。低3位表示声道数量减1,比如LPCM 8声道就是7。
第二个字节是采样率位图,bit3是48kHz,bit2是44.1kHz,bit1是32kHz,更高位对应96kHz/176.4kHz/192kHz。第三个字节对LPCM表示最大位深:001表示16bit,010表示20bit,011表示24bit。对压缩格式则可能表示最大码率。
对于HDMI源端设计,这个数据块决定了两件事:一是EMI/HDMI音频能力协商的结果,二是音频驱动是否允许用户选择96kHz或192kHz输出。我曾遇过一次号称支持192kHz的功放,实际SAD里只claim了24bit/96kHz,结果Windows下音频属性无论如何都选不到192kHz。查EDID后才发现厂家固件标称和实际EEPROM内容不一致。所以遇到版本不符,先怀疑EDID内容和说明书不符,再怀疑其他链路。
扬声器分配数据块(Speaker Allocation Data Block)描述了设备内置扬声器的物理布局:FL/FR(前置左右)、FC、LFE、RL/RR等。HDMI音频驱动根据它决定多声道输出时是否进行下混或上混。大多数外接显示器这项都写“无内置扬声器”,但电视通常都会声明2声道或更多。
4. 硬件设计层面的EDID:电平转换、上拉、HPD与防护
4.1 5V域、1.8V域的DDC电平转换选型
这是HDMI硬件设计里最常被新手忽略的一块。HDMI连接器上的DDC引脚规范上工作电压是5V,需要从source端的18脚+5V取电,而绝大多数SoC或FPGA的I2C控制器电平是1.8V或3.3V。直接用io直接接上去,轻则读不到数据,重则烧毁GPIO。
正确的做法是在中间加电平转换器。常见的选择有TXS0102(双向电平转换)、PCA9517(I2C缓冲器)、PCA9617(带动态偏移的低电压缓冲器)等。如果你的系统里DDC总线还需要隔离长距离走线或应对多路HDMI输入切换,可以考虑加I2C Mux,比如PCA9546。
关于电平转换有个容易踩的坑:TXS0102这类自动方向判断的电平转换芯片,在低速I2C场景下工作得不错,但它的上拉电阻是内部集成的,大约在10kΩ级别。如果你的EDID EEPROM离连接器很远,或者总线上挂的设备多,等效电容变大,就可能出现边沿变慢、400kHz下读取不稳定。遇到这种情况,我一般会换用更强驱动的缓冲器,或者在走线上尽量缩短DDC到连接器之间的距离。
注意:DDC规范的最大I2C时钟是400kHz。但实际板上为了稳定性,很多方案会配置成100kHz。除非你的HDMI合规测试对DDC时序有严格要求,否则优先保证能稳定读取。
4.2 HPD设计中的常见错误与正确接法
HPD引脚看起来简单,就是个电平信号,但很多板的HPD设计都栽过跟头。
第一个错误是把HPD当普通GPIO输出直接接连接器。HDMI规范里HPD是从sink端拉高来“通知”source端,而实际调试中发现很多sink设备MCU内部GPIO驱动能力弱,被source端的内部上拉电阻直接拉高了,导致HPD永远为高。结果是源端认为始终有设备接入,但读EDID时又因为EEPROM还没初始化而失败。正确做法是HPD线上加一个上拉电阻到5V或3.3V,让默认状态明确,然后用MCU的GPIO作为开漏或推挽输出去控制它。必要时加一级三极管或MOS管做缓冲,别指望MCU的GPIO直接驱动长距离连接器线缆。
第二个错误是HPD上并联了滤波电容。很多工程师想当然地认为“加个小电容滤下干扰”,结果电容一加上,HPD上升沿变缓,源端中断触发不了或边沿检测失败。HPD线允许一定的高电平时间,但边沿不能太缓,我一般建议不加重电容,最多加一个低容值ESD保护管。滤波放在MCU内部配置输入滤波即可。
第三个错误是HPD和EDID EEPROM供电时序没配合。HPD拉高前,DDC侧的EEPROM和电平转换器必须已经完成上电。如果HPD先高、EEPROM后上电,源端会在HPD触发后立即尝试读EDID,读到的只能是全FF,而且很多源端软件对首次读取失败的重试机制并不积极,结果就是“接上没反应”。
4.3 I2C速率与容性负载对EDID回读的影响
HDMI源端读EDID时,走的是一条从主控到连接器再到对端设备的完整I2C链路。总线上的每颗芯片、每个过孔、每寸走线都会贡献电容。I2C标准里规定总线容性负载上限是400pF,但HDMI连接器和线缆本身就会占掉不少,主板上再加电容保护,很容易超标。
超标的表现是什么?不是立刻读不到,而是偶发失败。系统开机时读一次EDID成功,过一会儿热插拔一次就读不到了;或者10次里面有2次读出来校验失败。这类问题在实验室里最难复现,但一旦到产线上批量测试就会爆发。
我的建议是:在DDC总线靠近连接器端的走线上做阻抗和长度控制,尽量减少过孔;滤波和ESD防护器件的结电容要选择在几pF以内的型号;布线时绕开高频开关电源的干扰区。如果多用几个通道的HDMI输入切换,I2C总线上还要考虑Mux芯片的导通电容。实测情况下,把总线上所有器件的容性负载加起来,不要让DDC有效容性负载超过200pF,这边留的余量才够。
还有一种情况是接地问题。DDC总线参考的是连接器外壳地和数字地,如果HDMI连接器外壳没有良好接地,或者与主板地之间存在大的电势差,读EDID时会出现奇怪的数据bit错误。检查地连接比检查信号线本身更优先。
5. Linux下提取、解析和校验EDID的完整实操
5.1 用/sys/class/drm直接导出EDID
在Linux系统上,如果显卡驱动已经把HDMI接口枚举出来,那获取EDID是最简单的。DRM子系统中每个连接器都有一个sysfs路径,以HDMI为例通常是/sys/class/drm/card0-HDMI-A-1/,也可能是card1-HDMI-A-2,取决于你的显卡和接线。直接读取该目录下的edid文件就能拿到二进制的完整EDID:
cat /sys/class/drm/card0-HDMI-A-1/edid > edid.bin注意:如果显示器没接好或者驱动没完成探测,这个文件根本不存在,或者大小为0。所以在工程脚本里先判断文件大小再继续处理,比直接读取更可靠。
拿到edid.bin后可以用hexdump快速看下头部确认基本块的Header:
hexdump -C edid.bin | head正常开头应该是00 ff ff ff ff ff ff 00。如果看到的不是这8个字节,说明要么读错设备,要么总线有问题。
5.2 用edid-decode解析全字段
拿到二进制文件后,最重要的事情是解析。edid-decode是一款VESA官方工具,Debian/Ubuntu下直接apt install edid-decode装,Fedora用dnf install edid-decode。解析指令:
edid-decode edid.bin输出内容会非常完整,从基本块到每个DTD到CEA扩展块里的VIC、SAD、VSDB都会展开。举个例子,你能看到:
Vendor-Specific Data Block (HDMI), OUI 00-0C-03 Source physical address: 1.0.0.0 Maximum TMDS clock: 300 MHz如果解析过程中报“Block 0 checksum failed”或者“Block 1 checksum failed”,说明读取到的EDID已经损坏。出现这种情况,优先重新读取,确认是不是没插牢固或者线缆问题。
使用edid-decode的意义不只是给人看,它对硬件调试的价值在于:可以帮助你核对EEPROM烧录内容是否符合预期。比如定制线缆或者做HDMI分配器/切换器时,很多人需要修改或伪造EDID,edid-decode就可以验证修改后内容的正确性。
5.3 烧录验证与内核级EDID覆盖
调试HDMI设备时还有一种常见操作:内核级覆盖EDID。比如某块ARM主板的HDMI输出对某型号电视读到的EDID存在故障,导致无法输出正确分辨率,实质是驱动没有做足够的容错。Linux内核提供了强制指定EDID的机制,可以在启动参数里加drm.edid_firmware=HDMI-A-1:edid/1920x1080.bin,指定的二进制文件放在/lib/firmware/edid/目录下。这样即使物理设备上的EDID有问题,内核也会按你给的EDID来处理。
这个功能在调试时非常有用。比如手里有一台显示器EDID芯片已经损坏,但你需要验证主板HDMI输出本身没问题,就可以用这个方法把一个正常显示器导出的EDID强制给该接口。当然,这只适合调试和测试环境,量产产品还是要保证EDID读取链路本身的健壮性。
提示:
drm.edid_firmware的格式是<connector>:<file>,connector名字要和sysfs里的节点一致。多个接口用逗号分隔。如果模块编译进内核而不是按模块加载,用drm.edid_firmware要确保DRM的EDID固件支持已开启。
除了导出和解析,Linux下还可以通过i2c-tools直接从底层总线上读。先用i2cdetect -l找到DDC所在的总线,然后用i2cdump -y <bus> 0x50查看内容。这个方法在DRM驱动尚未枚举HDMI接口时特别有用,可以绕过驱动层独立验证硬件通路。但要注意:直接访问I2C设备时,可能和HDMI驱动产生总线竞争,建议先停掉相关驱动或用独立的总线控制器访问。
6. EDID读取失败的排查链路与实际案例
6.1 五类典型故障现象对照
做HDMI设备调试这么久,我归纳下来,EDID相关故障基本逃不出下面五类。每类对应的排查方向差异很大:
| 故障现象 | 直接原因 | 排查方向 |
|---|---|---|
| 系统完全没有HDMI节点 | HPD没有拉高或源端没检测到 | 量HPD电压、检查GPIO配置 |
| 节点存在但edid文件不存在或读空 | DDC读取超时 | 检查SCL/SDA上拉、电平转换器供电 |
| 读到的EDID内容全FF | 地址错误或EEPROM未上电 | 用i2cdetect确认0x50地址;检查sink端供电 |
| 读到的EDID校验失败 | 时序不稳定或长度不够 | 降低I2C速率、查走线电容 |
| EDID正常但高分输出不了 | VSDB里TMDS时钟或VIC列表不足 | 用edid-decode核对CEA扩展块内容 |
6.2 案例一:HPD上升沿正常却始终无法枚举
有一次调试一块基于FPGA的HDMI发送板,接到一台显示器上,Windows设备管理器里始终看不到这个显示设备。示波器抓HPD引脚,上升沿很清楚,电平也到了3.3V,完全符合预期。但是用i2cdetect扫描DDC总线时,0x50地址永远不会在列表里出现,i2cdump返回全是FF。
排查过程是先测了DDC总线上的SCL/SDA走线,确认没有短路和断路,再量了连接器18脚+5V,发现电压为0。这就有意思了:HPD能拉高,但DDC侧没有+5V,那HPD是谁供的电?最后追踪发现板的sink端电路里HPD被外部上拉到3.3V,而+5V是经过一个MOS管开关控制的,该MOS管默认不导通,而控制信号来自另一颗尚未初始化的电源管理芯片。系统上电时序里,电源管理芯片晚于HDMI连接器电源要求,导致EDID EEPROM根本没有工作电源。
修复方案是把+5V的控制信号改为由FPGA直接控制,并在HPD拉高之前确保+5V稳定输出。这个问题如果只盯信号波形,永远发现不了;必须把HPD、5V、DDC三者的时序放在一起考虑。
6.3 案例二:读取结果偶发性全FF/校验失败
另一个典型案例是HDMI输入采集卡。现象是系统能开机识别到HDMI源,但一段时间后或者切换到另一个输入源再切回来,采集画面蓝屏,dmesg里提示EDID读取失败。用示波器挂上DDC看,400kHz时钟下SCL/SDA波形还凑合,但SDA的下降沿明显有台阶,说明存在过冲和振铃。
后来定位到问题出在两处:一是DDC线上为了防止ESD加了TVS管,型号选得结电容过大(接近20pF),加上连接器和走线电容,总容性负载已经接近400pF上限;二是SCL和SDA两条线在PCB上并行走了将近8厘米,间距没有拉开,发生了串扰。整改方案是换用低结电容的ESD保护器件,同时对SCL/SDA做包地处理、拉开两条线间距。改版后连续3000次热插拔测试,EDID读取失败次数降到0。
这个案例的关键经验是:EDID读取偶发失败,不要一上来就怀疑软件,先看物理层。I2C总线是很古老的接口,也是很容易被信号完整性欺负的接口。
调试EDID还有一个值得推广的做法:把EDID读取作为HDMI板卡的产测必测项。不是简单读一次就算过,而是连续读10次,每次都要校验Header和Checksum全部通过才放行。这个测试对捕捉上电时序问题、焊接问题、电平转换芯片不良问题非常有效。我经手的HDMI板卡项目,产测阶段靠这一项就能拦截掉相当比例的隐性不良品。
另外,在设计阶段用软件模拟HDMI source去读sink的EDID,也是所有HDMI设备开发的标准动作。Linux下用i2c-tools完成底层的读写,用edid-decode完成解析,这两个工具组合起来基本覆盖了从硬件到协议的整个验证路径。