在上一节 Windows Phone 8.1 驱动开发——GPIO 简介 中,我们了解了Windows 8系统中GPIO驱动的大体架构,由于在工作中手机驱动开发人员很少涉及到GPIO Controller驱动的开发,该部分都由平台厂商开发完成,所以这里给大家讲解一下GPIO Peripheral Device Driver的开发步骤。
本文以微软官方提供的GPIO Sample为例进行讲解,你也可以到MSDN官网进行源码下载:GPIO Sample Drivers
电路示意图
根据该Sample Code,本人画了一张电路示意图,如下:
ACPI资源配置
编写驱动之前,我们首先看一下在ACPI配置表中,GPIO I/O Resource的分配:
从资源表中可以看到,该设备DEV1使用了GPIO10、GPIO11和GPIO1三个引脚,其中GPIO10/11用作普通IO口,而GPIO1则用作中断输入引脚。至于这里对GPIO10/11的引脚配置到底作输入还是输出,是否上拉等,其实大家并不用关心,因为在电源管理中,也就是加载PEP模块的时候,会重新根据电源管理中的配置文件(pep_common.asl)进行相应设置,这里的GpioIo方法只是告诉Peripheral Driver该设备使用到了哪些I/O引脚。同样,GpioInt方法也只是告诉驱动当前设备使用到那个GPIO作外部中断引脚,至于具体的配置细节也是在电源管理配置文件中进行描述的。
获取I/O资源
当PnP Manager加载设备时,会在EvtDevicePrepareHardware回调函数中,去读取I/O资源:
在以上代码中需要注意的是,函数WdfCmResourceListGetDescriptor()是按照ACPI资源表中的顺序依次读取的,所以这里SampleDrvExtension->ConnectionIds[0]对应GPIO10,SampleDrvExtension->ConnectionIds[1]对应GPIO11,顺序不能弄错了。
创建IO Target
当获取到I/O资源后,就可以使用该资源ID号创建一个IO Target来操作对应的GPIO口。这里对原始Sample Code做了点修改,增加了结构体SAMPLE_DRV_DEVICE_EXTENSION成员变量ReadIoTarget和WriteIoTarget,分别用于保存读、写IO TARGET的句柄。
创建一个读操作的IO Target:
创建一个写操作的IO Target:
发送IO请求
当创建并打开了一个IO TARGET后,就可以通过对该IO TARGET发送IOCTL请求来实现I/O引脚的读写操作。发送IOCTL_GPIO_READ_PINS进行读操作,发送IOCTL_GPIO_WRITE_PINS进行写操作。
设备初始化
实现以上函数后,就可以对设备进行初始化了。一般设备的初始化操作在PnP Manager的回调函数EvtDeviceD0Entry中完成:
至此,GPIO外设驱动就完成了。