Nous utilisons la routine suivante (sous Linux, avec libudev) pour lire les données d'un microcontrôleur PIC configuré en tant que périphérique USB HID. Les données sont envoyées uniquement lorsqu'un bouton connecté au microcontrôleur PIC est enfoncé ou relâché.Problèmes de blocage des lectures avec libudev sous Linux
La routine manque des messages du contrôleur PIC, et je suppose que c'est parce que l'appel à interroger ci-dessous ne se comporte pas comme il se doit.
L'appel à interroger bloquera de manière fiable pendant 1 seconde à l'aide de la lecture du premier message. Dès que le premier message est lu, l'appel à interroger revient immédiatement au lieu de bloquer pendant 1 seconde (1000 millisecondes) comme il se doit.
J'ai résolu ce problème en fermant et en rouvrant le périphérique après chaque lecture. Cela fait que le sondage se comporte correctement, mais je pense que la fermeture et la réouverture de l'appareil peuvent être la raison des messages perdus.
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;
}
La fonction PicDeviceDescriptor() ne vérifiant sur l'appareil pour vous assurer qu'il est présent. Voici les détails pertinents de la fonction PicDeviceDescriptor, montrant comment le périphérique est ouvert.
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;
}
Je suis sûr que je fais quelque chose de mal, mais j'ai googlé la question et ne peut pas sembler trouver des réponses pertinentes. Toute aide serait très appréciée - Thx.
Merci, c'est ce dont j'avais besoin. –
@SteveHawkins êtes-vous en mesure d'envoyer avec succès la sortie et de recevoir les rapports d'entrée au PIC. Utilisez-vous des API spécifiques pour y parvenir? – Raulp