【问题标题】:Problems with blocking reads using libudev on Linux在 Linux 上使用 libudev 阻塞读取的问题
【发布时间】:2010-04-29 01:02:36
【问题描述】:

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

例程缺少来自 PIC 控制器的消息,我怀疑这是因为下面的 poll 调用没有正常运行。

在读取第一条消息之前,对 poll 的调用将可靠地阻塞 1 秒。读取第一条消息后,对 poll 的调用立即返回,而不是像应有的那样阻塞 1 秒(1000 毫秒)。

我已通过在每次读取后关闭并重新打开设备来解决此问题。这使得 poll 行为正确,但我认为关闭和重新打开设备可能是丢失消息的原因。

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;
}

我确定我做错了什么,但我已经用谷歌搜索了这个问题,但似乎找不到任何相关的答案。任何帮助将不胜感激——谢谢。

【问题讨论】:

    标签: linux hid udev


    【解决方案1】:

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

    【讨论】:

    • @SteveHawkins 您能否成功发送输出并接收输入报告给 PIC。您是否使用任何特定的 API 来实现此目的。?
    猜你喜欢
    • 1970-01-01
    • 2014-11-17
    • 1970-01-01
    • 2012-07-17
    • 2011-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-21
    相关资源
    最近更新 更多