2010-04-29 4 views
2

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.

Répondre

4

La raison pour laquelle poll continue d'indiquer que le descripteur de fichier est lisible est que vous ne lui avez jamais read(). ioctl() ne compte pas comme read(). On peut supposer que l'appareil rend certaines données disponibles à lire - même si c'est seulement une valeur fictive pour réveiller le processus de l'espace utilisateur.

+0

Merci, c'est ce dont j'avais besoin. –

+0

@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

Questions connexes