akaryqin
驱动牛犊
驱动牛犊
  • 注册日期2009-06-01
  • 最后登录2010-04-29
  • 粉丝0
  • 关注0
  • 积分17分
  • 威望131点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:8107回复:7

求访问显卡I2C方法,通过DVI或者VGA端口通讯(EDID及DDC/CI读写)

楼主#
更多 发布于:2010-01-05 09:56
我想通过显卡的DVI或者VGA端口与显示器进行通讯,也就是进行EDID的读写及DDC/CI的相关通讯。
我知道通过显卡厂商提供的SDK,如NVAPI、ATI SDK等应该可以办到。
但是这些SDK都是仅应用于各自的显卡,不能通用,我想找到一个可以适用于所有支持I2C通讯的显卡的方法。
是否必须做成一个WDM驱动?如果是的话,请说明一下详细些的内容。
不知道谁能帮帮忙,非常感谢!
akaryqin
驱动牛犊
驱动牛犊
  • 注册日期2009-06-01
  • 最后登录2010-04-29
  • 粉丝0
  • 关注0
  • 积分17分
  • 威望131点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2010-04-27 16:32
这段时间断断续续地试了一些代码,
我知道做成wdm驱动方式挂到显卡驱动上(具体方法没试)应该可以实现,
但是因为NT式驱动使用方便的原因,我还是想使用NT式驱动实现,
但是还是出问题,也不知道是不是在NT式驱动下不能实现。
下面贴出我的代码,请高人指点一下。

系统为WinXP SP2,DDK为XP DDK 2600。

下面的代码要包含“i2cgpio.h”,
因为仅为简要说明,下面代码不完全,直接复制后可能不能编译成功。
下面代码执行到“i2cProviderInterface.i2cOpen”一句时出问题。



    // 显卡设备路径(不同电脑路径不同)
    UNICODE_STRING ustrDeviceName;
    RtlInitUnicodeString(&ustrDeviceName, L"\\Device\\NTPNP_PCI0012");

    PDEVICE_OBJECT pAdapterDeviceObject = NULL;
    PFILE_OBJECT pAdapterFileObject = NULL;

    // 尝试获取设备指针
    ntStatus = IoGetDeviceObjectPointer(&ustrDeviceName, FILE_ALL_ACCESS, &pAdapterFileObject, &pAdapterDeviceObject);
    if (!NT_SUCCESS(ntStatus))
        return ntStatus;

    I2CINTERFACE i2cProviderInterface;
    i2cProviderInterface.i2cOpen = NULL;
    i2cProviderInterface.i2cAccess = NULL;


    PIRP    pIrp;
    PIO_STACK_LOCATION    pNextStack;
    NTSTATUS            ntStatus;
    KEVENT                Event;

    // 创建IRP
    pIrp = IoAllocateIrp(pAdapterFileObject->StackSize, FALSE);
    if( pIrp == NULL)
    {
        ObDereferenceObject(pAdapterFileObject);
        return STATUS_UNSUCCESSFUL;
    }

    // 取得下一层IO堆栈
    pNextStack = IoGetNextIrpStackLocation( pIrp);
    if( pNextStack == NULL)
    {
        IoFreeIrp( pIrp);
        ObDereferenceObject(pAdapterFileObject);
        return STATUS_UNSUCCESSFUL;
    }

    pIrp->IoStatus.Status = STATUS_NOT_SUPPORTED;
    pNextStack->MajorFunction = (UCHAR)IRP_MJ_PNP;
    pNextStack->MinorFunction = IRP_MN_QUERY_INTERFACE;
    KeInitializeEvent( &Event, NotificationEvent, FALSE);

    IoSetCompletionRoutine(    pIrp,
        I2CScriptIoSynchCompletionRoutine,
        &Event, TRUE, TRUE, TRUE);

    pNextStack->Parameters.QueryInterface.InterfaceType = ( struct _GUID *)&GUID_I2C_INTERFACE;
    pNextStack->Parameters.QueryInterface.Size = sizeof( I2CINTERFACE);
    pNextStack->Parameters.QueryInterface.Version = 1;
    pNextStack->Parameters.QueryInterface.Interface = ( PINTERFACE)&i2cProviderInterface;
    pNextStack->Parameters.QueryInterface.InterfaceSpecificData = NULL;

    // 调用驱动
    ntStatus = IoCallDriver( pDeviceObject, pIrp);
    if( ntStatus == STATUS_PENDING)
        KeWaitForSingleObject(    &Event,Suspended, KernelMode, FALSE, NULL);
    if((i2cProviderInterface.i2cOpen == NULL) || (i2cProviderInterface.i2cAccess == NULL))
    {
        IoFreeIrp( pIrp);
        ObDereferenceObject(pAdapterFileObject);
        return STATUS_UNSUCCESSFUL;
    }
    if( pIrp != NULL)
        IoFreeIrp( pIrp);

    // 尝试初始化I2C
    I2CControl  i2cAccessBlock;
    i2cAccessBlock.Status = I2C_STATUS_NOERROR;

    // 执行到下面这一句时,Window XP会崩溃蓝屏
    ntStatus = i2cProviderInterface.i2cOpen( pAdapterDeviceObject, TRUE, &i2cAccessBlock);
    
    if(ntStatus  != STATUS_SUCCESS)
    {
        ObDereferenceObject(pAdapterFileObject);
        return STATUS_UNSUCCESSFUL;
    }

    //-------------------------
    // 使用I2C通讯
    // …………
    // 关闭I2C
    // …………
    //-------------------------

    ObDereferenceObject(pAdapterFileObject);


代码执行到“i2cProviderInterface.i2cOpen”一句时出问题,请教一下各位能不能看出什么原因?
还是NT式驱动下根本不能这样实现?
谢谢了!
游客

返回顶部