Windows显示驱动中读取EDID
2015-07-04 11:45
155 查看
去年刚进实验室的时候,实验室有有人在从事Windows双屏显示驱动的开发。项目难度很大,因为相关Windows的东西基本都是闭源的,资料少之又少,因此项目进展也很慢。我也被配安排帮助开发驱动程序,当时给我的任务是写一个Windows驱动下读取显示器的EDID的程序。
EDID(Extended Display Identification Data :扩展显示标识数据,一种VESA标准数据格式(显卡有四种总线类型:IAS、VESA、PCI、APG,我们现有程序就是VESA总线)):包含有关显示器及其性能的参数,包括供应商信息、最大图像大小、厂商预设值、分辨率、频率范围的限制、显示器名和序列号的字符串等信息。基本EDID有128个字节,保存在display节中,这些信息可通过DDC与系统进行通信,是在显示器和GPU之间进行的。EDID数据读取到之后,可将相关参数传递给PC的显卡驱动,从而做出调整,使显示内容(数据)与显示屏相匹配。
基本的EDID拥有128个字节信息,其信息如下:
0-7: 头信息,由00 FF FF FF FF FF FF 00 这8个字节组成
8-9: 厂商ID
10-11: 产品ID
12-15: 32-bit序列号
16-17 : 制造日期
18-19 : EDID 版本
20-24 : 显示器的基本信息(视频输入定义,最大横向图像尺寸,最大纵向图像尺寸,显示传输特性,特征支持)
25-34 : 显示器的颜色特征
35-37 : Established Timings
38-53 : Standard Timings Identification
54-125:Detailed Timing Description
126: 扩展标志位
127: 求和验证值
EDID目前已经存在五种版本(数据格式),EDID1.0、EDID1.1、EDID1.2、EDID1.3、EDID2.0。另外还一种Enhanced EDID,它时基于EDID 1.3的结构,可以存储更多的数据,数据长度是128+N*128。
EDID能够为显示器的初始化配置提供环境参数,是显示驱动不可缺少的输入数据,因此读取EDID是我本次任务的最终目标。
强大的版权保护机制:HDCP
支持24bit色深处理,(RGB,YCbCr4-4-4,TCbCr4-2-2)
完全兼容DVI接口标准
支持热拔插
采用TMDS(最小传输差分传输技术),利用两个引脚间电压差来传送信号的技术
每个标准的HDMI连接,都包含3个用于传输数据的TMDS传输通道,1个独立的TMDS时钟通道(保证传输时所需的统一时序)。每个TMDS通道都能传输10bits的数据流(有多种编码格式)
HDMI把视频信号分为:R、G、B、H、V五种信号,用TMDS技术编码
DDC:显示数据通道,用来向视频接收装置发送配置信息和数据格式信息;接收装置读取这些E-EDID(增强扩展显示识别数据)
CEC:消费电子控制通道,通过这条通道可以控制视听设备的工作
控制数据(2位)
数据包(4位):包含:音频数据、辅助信息数据
视频信号经过编码,生成3路(3个TMDS数据传输通道,每路8位),共24位视频数据流,输入HDMI发射器中
TMDS通道传输24位视频像素信号,将每通道的8位编码成10位,在每个10位像素时钟周期传送一个最小化的信号序列,视频信号被调制为TMDS数据信号传输出去,被***接收
数据包也被调制成10位一组的TMDS信号,然后发出
视频数据传输期和岛屿数据传输期均开始于一个Guard Band保护频带,Guard Band由2个特殊的字符组成,为了明确限定控制数据传输期之后的跳转是视频数据传输期
3通道一共6位控制数据,分别为:HSYNC(行同步)、VSYNC(列同步)、CTL0、CTL1、CTL2、CTL3
每个TMDS通道包含2位控制数据,采用从2位到10位的编码方法,在每个控制周期的最后阶段
CTL0、CTL1、CTL2、CTL3组成的头文件,说明下一个周期是:视频数据传输周期or岛屿数据传输周期?
岛屿数据和控制数据是在视频数据传输的隐消期,不会占据带宽。因此一根HDMI数据线就能同时传输视频、音频信号。
上述是HDMI的工作原理,然而显卡驱动代码中并没有类似HDMI数据传输过程的具体实现,只是通过命令直接获取数据,因此可以推测HDMI是通过一个控制器来获取数据的。果然,在HD40的主板原理图上发现了HDMI控制器anx7150。
关于anx7150,我也简要的阅读了其数据手册,主要了解了该控制器的读取EDID的流程图、状态转移图等,并与显卡驱动中进行了核对。
VGA(Video Graphics Array)视频图形阵列是IBM于1987年提出的一个使用模拟信号的电脑显示标准。VGA接口即电脑采用VGA标准输出数据的专用接口。如下图所示,VGA接口的接口一共有15个通道,主要的数据通道时: 1、2、3通道,分别传输R、G、B三原色信号,以及13、14通道传输行、场同步信号。
在数据传输类型方面,VGA和HDMI有一定的区别:HDMI完全是数字信号的传输,而VGA则是由数字信号转换为模拟信号,进行传输,因此VGA的接口芯片CS7123或GM7123其实就是一个DAC的转换器。
由上面这两点就产生了一个疑问:
显卡驱动接上显示屏,要想正常工作。首先就必须读取EDID,然后解析EDID,从而完成对不同的显示屏的不同配置。但是根据数据传输通道和信号传输类型,EDID不太可能是通过这五个数据通道传输过来的,也不太可能是将数据转换为模拟信号传输过来的。并且EDID是存储在EEPROM中的一段序列,通常读取时通过I2C来读取的。所以,思考后觉得应该VGA接口上有通道可以构成一个读取EDID的DDC通道。经深入调研,发现VGA上的11、12、15、4引脚是有着其他功能的。根据资料显示:
Pin11:ID0/RES formerly Monitor ID bit 0, reserved since E-DDC
Pin12:ID1/SDA formerly Monitor ID bit 1, I2C data since DDC2
Pin15:ID3/SCL formerly Monitor ID bit 3, I2C clock since DDC2
Pin4 :ID2/RES formerly Monitor ID bit 2, reserved since E-DDC
从中推测实际中Pin12、Pin15很有可能被用来读取EDID,果然在HD40的板子上,有两个GPIO直接连接到了VGA的这两个管脚。另外,从管脚的作用来开,可以通过I2C协议来进行数据读取。在HD40中集成了I2C模块,看看是否能够直接使用处理器中的这个模块。但是处理器的I2C模块的对外管脚却没有连接到VGA管脚上,那么只能通过GPIO来模拟I2C进行VGA的读取。
方案确定后,直接编写代码。尽管代码中I2C的实现很容易,但是关于程序的初始化设置很复杂,涉及到虚拟内存到物理内存的映射,相关配置,这涉及到一系列的参数设置等等。
在读取EDID过程中,遇到了一个花了两天才解决的问题,即使用的显示器的EEPROM无法进行读取(之前据说该显示器就有些问题)。当时显示器能使用,但是却无法读取EDID,这让我不断的尝试修改代码,最后通过换了一个显示器,成功读取了EDID。
EDID
首先有必要了解一下EDID是什么?EDID(Extended Display Identification Data :扩展显示标识数据,一种VESA标准数据格式(显卡有四种总线类型:IAS、VESA、PCI、APG,我们现有程序就是VESA总线)):包含有关显示器及其性能的参数,包括供应商信息、最大图像大小、厂商预设值、分辨率、频率范围的限制、显示器名和序列号的字符串等信息。基本EDID有128个字节,保存在display节中,这些信息可通过DDC与系统进行通信,是在显示器和GPU之间进行的。EDID数据读取到之后,可将相关参数传递给PC的显卡驱动,从而做出调整,使显示内容(数据)与显示屏相匹配。
基本的EDID拥有128个字节信息,其信息如下:
0-7: 头信息,由00 FF FF FF FF FF FF 00 这8个字节组成
8-9: 厂商ID
10-11: 产品ID
12-15: 32-bit序列号
16-17 : 制造日期
18-19 : EDID 版本
20-24 : 显示器的基本信息(视频输入定义,最大横向图像尺寸,最大纵向图像尺寸,显示传输特性,特征支持)
25-34 : 显示器的颜色特征
35-37 : Established Timings
38-53 : Standard Timings Identification
54-125:Detailed Timing Description
126: 扩展标志位
127: 求和验证值
EDID目前已经存在五种版本(数据格式),EDID1.0、EDID1.1、EDID1.2、EDID1.3、EDID2.0。另外还一种Enhanced EDID,它时基于EDID 1.3的结构,可以存储更多的数据,数据长度是128+N*128。
EDID能够为显示器的初始化配置提供环境参数,是显示驱动不可缺少的输入数据,因此读取EDID是我本次任务的最终目标。
HDMI:高清晰度多媒体接口
在我手里有参考价值的资料是Windows显卡驱动的中通过HDMI读取EDID的程序。虽然我的目标是通过VGA读取EDID,但是在没有任何驱动开发经验的情况下,有必要先了解一下显卡驱动中HDMI部分的代码,以作为VGA程序开发的借鉴和参考。在看代码的同时,我也调研了HDMI数据传输的机制。下面对此做简要介绍。HDMI特点
支持EDID和DDC2B标准,设备之间可智能选择最佳匹配连接方式强大的版权保护机制:HDCP
支持24bit色深处理,(RGB,YCbCr4-4-4,TCbCr4-2-2)
完全兼容DVI接口标准
支持热拔插
采用TMDS(最小传输差分传输技术),利用两个引脚间电压差来传送信号的技术
每个标准的HDMI连接,都包含3个用于传输数据的TMDS传输通道,1个独立的TMDS时钟通道(保证传输时所需的统一时序)。每个TMDS通道都能传输10bits的数据流(有多种编码格式)
HDMI把视频信号分为:R、G、B、H、V五种信号,用TMDS技术编码
数据通道
TMDS:三个通道传输R、G、B三原色,HV编码在B信号通道里传输,R、G的多余位置用来传输音频信号。DDC:显示数据通道,用来向视频接收装置发送配置信息和数据格式信息;接收装置读取这些E-EDID(增强扩展显示识别数据)
CEC:消费电子控制通道,通过这条通道可以控制视听设备的工作
HDMI输入的源编码格式
视频像素数据(8位)控制数据(2位)
数据包(4位):包含:音频数据、辅助信息数据
数据传输过程
视频数据传输期
HDMI数据线上传送视频像素信号(数据)视频信号经过编码,生成3路(3个TMDS数据传输通道,每路8位),共24位视频数据流,输入HDMI发射器中
TMDS通道传输24位视频像素信号,将每通道的8位编码成10位,在每个10位像素时钟周期传送一个最小化的信号序列,视频信号被调制为TMDS数据信号传输出去,被***接收
岛屿数据传输期
TMDS通道上将出现音频数据、辅助信息数据,这些数据每4位一组(即上述的4位数据包)数据包也被调制成10位一组的TMDS信号,然后发出
视频数据传输期和岛屿数据传输期均开始于一个Guard Band保护频带,Guard Band由2个特殊的字符组成,为了明确限定控制数据传输期之后的跳转是视频数据传输期
控制数据传输期
在前面任意两个数据传输周期之间,每个TMDS包含2位的控制数据3通道一共6位控制数据,分别为:HSYNC(行同步)、VSYNC(列同步)、CTL0、CTL1、CTL2、CTL3
每个TMDS通道包含2位控制数据,采用从2位到10位的编码方法,在每个控制周期的最后阶段
CTL0、CTL1、CTL2、CTL3组成的头文件,说明下一个周期是:视频数据传输周期or岛屿数据传输周期?
岛屿数据和控制数据是在视频数据传输的隐消期,不会占据带宽。因此一根HDMI数据线就能同时传输视频、音频信号。
上述是HDMI的工作原理,然而显卡驱动代码中并没有类似HDMI数据传输过程的具体实现,只是通过命令直接获取数据,因此可以推测HDMI是通过一个控制器来获取数据的。果然,在HD40的主板原理图上发现了HDMI控制器anx7150。
关于anx7150,我也简要的阅读了其数据手册,主要了解了该控制器的读取EDID的流程图、状态转移图等,并与显卡驱动中进行了核对。
VGA
本次的任务是通过VGA读取EDID,那么有必要了解一下VGA。VGA(Video Graphics Array)视频图形阵列是IBM于1987年提出的一个使用模拟信号的电脑显示标准。VGA接口即电脑采用VGA标准输出数据的专用接口。如下图所示,VGA接口的接口一共有15个通道,主要的数据通道时: 1、2、3通道,分别传输R、G、B三原色信号,以及13、14通道传输行、场同步信号。
在数据传输类型方面,VGA和HDMI有一定的区别:HDMI完全是数字信号的传输,而VGA则是由数字信号转换为模拟信号,进行传输,因此VGA的接口芯片CS7123或GM7123其实就是一个DAC的转换器。
由上面这两点就产生了一个疑问:
显卡驱动接上显示屏,要想正常工作。首先就必须读取EDID,然后解析EDID,从而完成对不同的显示屏的不同配置。但是根据数据传输通道和信号传输类型,EDID不太可能是通过这五个数据通道传输过来的,也不太可能是将数据转换为模拟信号传输过来的。并且EDID是存储在EEPROM中的一段序列,通常读取时通过I2C来读取的。所以,思考后觉得应该VGA接口上有通道可以构成一个读取EDID的DDC通道。经深入调研,发现VGA上的11、12、15、4引脚是有着其他功能的。根据资料显示:
Pin11:ID0/RES formerly Monitor ID bit 0, reserved since E-DDC
Pin12:ID1/SDA formerly Monitor ID bit 1, I2C data since DDC2
Pin15:ID3/SCL formerly Monitor ID bit 3, I2C clock since DDC2
Pin4 :ID2/RES formerly Monitor ID bit 2, reserved since E-DDC
从中推测实际中Pin12、Pin15很有可能被用来读取EDID,果然在HD40的板子上,有两个GPIO直接连接到了VGA的这两个管脚。另外,从管脚的作用来开,可以通过I2C协议来进行数据读取。在HD40中集成了I2C模块,看看是否能够直接使用处理器中的这个模块。但是处理器的I2C模块的对外管脚却没有连接到VGA管脚上,那么只能通过GPIO来模拟I2C进行VGA的读取。
GPIO
由于要进行软件模拟GPIO,就需要知道如何对GPIO进行操作。根据文档显示:GPIO中共有9个寄存器,其中一个为只读寄存器,2个为只写寄存器,另外6个为可读写寄存器。GPIO的基地址为0xee500000,下表为涉及到GPIO操作所需的寄存器的基本信息。方案确定后,直接编写代码。尽管代码中I2C的实现很容易,但是关于程序的初始化设置很复杂,涉及到虚拟内存到物理内存的映射,相关配置,这涉及到一系列的参数设置等等。
在读取EDID过程中,遇到了一个花了两天才解决的问题,即使用的显示器的EEPROM无法进行读取(之前据说该显示器就有些问题)。当时显示器能使用,但是却无法读取EDID,这让我不断的尝试修改代码,最后通过换了一个显示器,成功读取了EDID。
相关文章推荐
- eclipse中maven插件上传项目jar包到私服
- C#中获取、生成随机数的三种方法
- 背景音乐
- mongodb 基本操作
- 详细解说STL string
- 最优秀的创意来自留白
- 可记住用户名和密码的登录界面
- 用wireshark解析应用层存储包
- JS 之表单特殊控制
- 暑假计划
- CFStringTransform的使用 :汉字转拼音、全角转半角等
- leetcode 226 :Invert Binary Tree
- subversion和客户端的应用
- BZOJ2565 最长双回文串
- Git教程学习(四)
- 用URL浏览图片
- 解决angular 与django的冲突
- java基础之java的基本了解
- Android中数据库的创建和使用
- UVA - 1347 Tour