在Linux上使用libudev阻塞读取的问题

我们使用以下例程(在Linux上使用libudev)从configuration为USB HID设备的PIC单片机读取数据。 仅当连接到PIC单片机的button被按下或释放时,才会发送数据。

该例程缺less来自PIC控制器的消息,我怀疑这是因为调用下面的轮询不是应该如此。

轮询调用将可靠地阻塞1秒钟使用第一条消息被读取。 只要第一条消息被读取,轮询调用立即返回,而不是像它应该阻塞1秒(1000毫秒)。

我已经解决了这个问题,每次阅读后closures并重新打开设备。 这使投票performance正确,但我认为closures和重新打开设备可能是丢失信息的原因。

bool PicIo::Receive (unsigned char* picData, const size_t picDataSize) { static hiddev_report_info hidReportInfo; static hiddev_usage_ref_multi hidUsageRef; if (-1 == PicDeviceDescriptor()) { return false; } // Determine whether or not there is data available to be read pollfd pollFd; pollFd.fd = PicDeviceDescriptor(); pollFd.events = POLLIN; int dataPending = poll (&pollFd, 1, 1000); if (dataPending <= 0) { return false; } // Initialize the HID Report structure for an input report hidReportInfo.report_type = HID_REPORT_TYPE_INPUT; hidReportInfo.report_id = 0; hidReportInfo.num_fields = 64; if (-1 == ioctl(PicDeviceDescriptor(), HIDIOCGREPORT, &hidReportInfo)) { return false; } // Initizlize the HID Usage Reference for an Input report hidUsageRef.uref.report_type = HID_REPORT_TYPE_INPUT; hidUsageRef.uref.report_id = 0; hidUsageRef.uref.field_index = 0; hidUsageRef.uref.usage_index = 0; hidUsageRef.num_values = 64; if (-1 == ioctl(PicDeviceDescriptor(), HIDIOCGUSAGES, &hidUsageRef)) { return false; } // Transfer bytes from the usage report into the return value. for (size_t idx=0; (idx < 64) && (idx < picDataSize); ++idx) { picData[idx] = hidUsageRef.values[idx]; } return true; } 

PicDeviceDescriptor()函数检查设备以确保它存在。 以下是PicDeviceDescriptor函数的相关细节,展示了如何开始打开设备。

 int PicIo::PicDeviceDescriptor(int command) { struct stat statInfo; static int picDeviceDescriptor = -1; string picDevicePath = "/dev/usb/hiddev0"; if ((-1 != picDeviceDescriptor) && (CLOSE == command)) { close (picDeviceDescriptor); picDeviceDescriptor = -1; } else if ((-1 != picDeviceDescriptor) && (-1 == fstat(picDeviceDescriptor, &statInfo))) { // Handle the case where the PIC device had previously been detected, and // is now disconnected. close (picDeviceDescriptor); picDeviceDescriptor = -1; } else if ((-1 == picDeviceDescriptor) && (m_picDevice.IsConnected())) { // Create the PIC device descriptor if the PIC device is present (ie its // device node is present) and if the descriptor does not already exist picDeviceDescriptor = open (picDevicePath.c_str(), O_RDONLY); } return picDeviceDescriptor; } 

我敢肯定,我做错了什么,但我已经Google了这个问题,似乎无法find任何相关的答案。 任何帮助将非常感激 – Thx。

poll继续指出文件描述符是可读的原因是您从不read()ioctl()不算作read() 。 据推测,该设备使一些数据可以读取 – 即使它只是一个虚拟值来唤醒用户空间进程。