赞
踩
一:什么是EDID?
显示器中用来存储显示器信息的数据格式,包括尺寸、厂家、序列号等等。
EDID数据有128个字节,0x15、0x16两个字节对应显示器的宽高。
二:如何获取显示器EDID?
EDID存储在显示器中,本身是一个用来存储信息的I2C设备(设备地规定0x50),其通过DDC通道(i2c总线)进行读取。在服务器上,DDC信号和VGA其它信号从BMC芯片的DAC接出。
系统下,在加载i2c-dev驱动过后(modprobe i2c-dev),系统下会创建i2c设备节点,通过文件操作去进行i2c的读取。
- #include <fcntl.h>
- #include <unistd.h>
- #include <linux/i2c.h>
- #include <linux/i2c-dev.h>
- #include <stdio.h>
- #include <sys/ioctl.h>
-
- #define DDC_ADDR 0x50
- // #define BASE_ADDR 0x00
- #define BASE_ADDR 0x15 //0x15-width, 0x16-height
- #define DATA_LEN 2 // edid_lenght is 128
-
- int main(int argc, char** argv)
- {
- if(argc <= 1){
- fprintf(stderr, "param error, please input device\n");
- return -1;
- }
-
- char * i2c_dev = argv[1];
- int fd =open(i2c_dev, O_RDWR);
- if (fd < 0){
- fprintf(stderr, "open dev:%s failed/n", i2c_dev);
- close(fd);
- return -1;
- }
-
- ioctl(fd, I2C_TIMEOUT, 2);
- ioctl(fd, I2C_RETRIES, 1);
-
- unsigned char buf[DATA_LEN]={0};
- unsigned start = BASE_ADDR;
- struct i2c_msg msgs[2] = {
- {
- .addr = DDC_ADDR,
- .flags = 0,
- .len = 1,
- .buf = (void *)&start,
- },{
- .addr = DDC_ADDR,
- .flags = I2C_M_RD,
- .len = DATA_LEN,
- .buf = buf,
- }
- };
- struct i2c_rdwr_ioctl_data rdwr;
- rdwr.msgs = msgs;
- rdwr.nmsgs = 2;
- if(ioctl(fd, I2C_RDWR, &rdwr)<0){
- fprintf(stderr, "ioctl:i2c_rdwr failed\n");
- close(fd);
- return -1;
- }
-
- fprintf(stdout, "Width: %dmm, Height: %dmm\n", buf[0]*10, buf[1]*10);
- close(fd);
-
- return 0;
- }
对于i2c设备,读取信息时,主设备需要向从设备发送两个msg,第一个msg包含写操作(0)、写入的数据长度(BASE_ADDR长度)和需要读取的寄存器地址(BASE_ADDR);第二个msg包含需要的读操作(I2C_M_RD)、读取数据的长度(等于buf的长度)和数据读入的地址(buf)。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。