2010-04-29 3 views
2

Мы используем следующую процедуру (в Linux, с libudev) для чтения данных с микроконтроллера PIC, настроенного как USB HID-устройство. Данные отправляются только при нажатии или отпускании кнопки, подключенной к микроконтроллеру PIC.Проблемы с блокировкой чтения с использованием libudev в Linux

Подпрограмма пропускает сообщения от контроллера ПИК, и я подозреваю, что это связано с тем, что вызов опроса ниже не ведет себя так, как должен.

Звонок на опрос будет надежно блокироваться в течение 1 секунды, используя первое сообщение. Как только первое сообщение будет прочитано, вызов опроса немедленно возвращается, а не блокируется в течение 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; 
} 

Я уверен, что я делаю что-то неправильно, но я Гугл вопроса и не могу найти соответствующие ответы. Любая помощь будет очень оценена - Thx.

ответ

4

Причина, по которой poll продолжает указывать, что файловый дескриптор является читаемым, состоит в том, что из него никогда не было read(). ioctl() не считается read(). Предположительно, устройство позволяет считывать некоторые данные - даже если это всего лишь фиктивное значение для пробуждения процесса пользовательского пространства.

+0

Спасибо, это то, что мне нужно. –

+0

@SteveHawkins вы можете успешно отправить вывод и получить отчеты ввода в PIC. Используете ли вы какие-либо конкретные API для достижения этого? – Raulp

 Смежные вопросы

  • Нет связанных вопросов^_^