我们正在使用以下例程(在Linux上,使用libudev)从配置为USB HID设备的PIC单片机读取数据。仅当按下或释放连接到PIC单片机的按钮时才会发送数据。
该例程缺少来自PIC控制器的消息,我怀疑这是因为下面的调查调用不符合预期。
对poll的调用将可靠地阻塞1秒,读取第一条消息。一旦读取了第一条消息,对poll的调用立即返回,而不是像它应该的那样阻塞1秒(1000毫秒)。
我在每次阅读后关闭并重新打开设备,解决了这个问题。这使得民意调查行为正确,但我认为关闭和重新打开设备可能是丢失消息的原因。
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 (i.e. its
// device node is present) and if the descriptor does not already exist
picDeviceDescriptor = open (picDevicePath.c_str(), O_RDONLY);
}
return picDeviceDescriptor;
}
我确信我做错了什么,但我用Google搜索了这个问题,似乎无法找到任何相关答案。任何帮助将非常感谢 - 谢谢。
答案 0 :(得分:4)
poll
继续表明文件描述符可读的原因是你永远不会read()
。 ioctl()
不计为read()
。据推测,该设备可以读取一些数据 - 即使它只是唤醒用户空间进程的虚拟值。