Мы используем следующую процедуру (в Linux, с libudev) для чтения данных с микроконтроллера PIC, настроенного как устройство HID USB. Данные отправляются только при нажатии или отпускании кнопки, подключенной к микроконтроллеру 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;
}
Я уверен, что я делаю что-то не так, но я погуглил проблему и, похоже, не могу найти соответствующих ответов. Любая помощь будет принята с благодарностью - Thx.