void setLed (int led, int value) { unsigned int ledValue = 0; ledValue = GetLEDs(); ledValue = value ? ledValue | (1 << led) : ledValue & ~(1 << led); SetLEDs(ledValue); }
// 这里面的IO操作是经过序列化的。一个挨着一个,所以绝不会发生重入问题。 // VOID CY001Drv::DeviceIoControlSerial(IN WDFQUEUE Queue, IN WDFREQUEST Request, IN size_t OutputBufferLength, IN size_t InputBufferLength, IN ULONG IoControlCode) { NTSTATUS ntStatus = STATUS_SUCCESS; ULONG ulRetLen = 0; size_t size; void* pBufferInput = NULL; void* pBufferOutput = NULL; KDBG(DPFLTR_INFO_LEVEL, "[DeviceIoControlSerial]"); // 取得输入/输出缓冲区 if(InputBufferLength)WdfRequestRetrieveInputBuffer(Request, InputBufferLength, &pBufferInput, &size); if(OutputBufferLength)WdfRequestRetrieveOutputBuffer(Request, OutputBufferLength, &pBufferOutput, &size); switch(IoControlCode) { // 设置数码管 case IOCTL_USB_SET_DIGITRON: { CHAR ch = *(CHAR*)pBufferInput; KDBG(DPFLTR_INFO_LEVEL, "IOCTL_USB_SET_DIGITRON"); SetDigitron(ch); break; } // 读数码管 case IOCTL_USB_GET_DIGITRON: { UCHAR* pCh = (UCHAR*)pBufferOutput; KDBG(DPFLTR_INFO_LEVEL, "IOCTL_USB_GET_DIGITRON"); GetDigitron(pCh); ulRetLen = 1; break; } // 设置LED灯(共4盏) case IOCTL_USB_SET_LEDs: { CHAR ch = *(CHAR*)pBufferInput; KDBG(DPFLTR_INFO_LEVEL, "IOCTL_USB_SET_LEDs"); SetLEDs(ch); break; } // 读取LED灯(共4盏)的当前状态 case IOCTL_USB_GET_LEDs: { UCHAR* pCh = (UCHAR*)pBufferOutput; KDBG(DPFLTR_INFO_LEVEL, "IOCTL_USB_GET_LEDs"); GetLEDs(pCh); ulRetLen = 1; break; } // 控制命令。 // 分为:USB协议预定义命令、Vendor自定义命令、特殊类(class)命令。 case IOCTL_USB_CTL_REQUEST: { KDBG(DPFLTR_INFO_LEVEL, "IOCTL_USB_CTL_REQUEST"); ntStatus = UsbControlRequest(Request); if(NT_SUCCESS(ntStatus))return; break; } // 开启中断读 case IOCTL_START_INT_READ: KDBG(DPFLTR_INFO_LEVEL, "IOCTL_START_INT_READ"); ntStatus = InterruptReadStart(); break; // 控制程序发送读请求。它们是被阻塞的,放至Queue中排队,所以不要即可完成他们。 case IOCTL_INT_READ_KEYs: KDBG(DPFLTR_INFO_LEVEL, "IOCTL_INT_READ_KEYs"); ntStatus = WdfRequestForwardToIoQueue(Request, m_hInterruptManualQueue); if(NT_SUCCESS(ntStatus)) return;// 成功,直接返回;异步完成。 break; // 终止中断读 case IOCTL_STOP_INT_READ: KDBG(DPFLTR_INFO_LEVEL, "IOCTL_STOP_INT_READ"); InterruptReadStop(); ntStatus = STATUS_SUCCESS; break; default: // 不应该到这里。 // 对于不能识别的IO控制命令,这里做错误处理。 KDBG(DPFLTR_INFO_LEVEL, "Unknown Request: %08x(%d)!!!", IoControlCode, IoControlCode); ntStatus = STATUS_INVALID_PARAMETER; break; } WdfRequestCompleteWithInformation(Request, ntStatus, ulRetLen); return; }