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

时间:2010-04-29 01:02:36

标签: linux hid udev

我们正在使用以下例程(在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搜索了这个问题,似乎无法找到任何相关答案。任何帮助将非常感谢 - 谢谢。

1 个答案:

答案 0 :(得分:4)

poll继续表明文件描述符可读的原因是你永远不会read()ioctl()不计为read()。据推测,该设备可以读取一些数据 - 即使它只是唤醒用户空间进程的虚拟值。