Мы используем следующую процедуру (в 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.
Спасибо, это то, что мне нужно. –
@SteveHawkins вы можете успешно отправить вывод и получить отчеты ввода в PIC. Используете ли вы какие-либо конкретные API для достижения этого? – Raulp