IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Accéder à un boitier 8 relais USB, erreur de segmentation


Sujet :

C

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 42
    Points : 30
    Points
    30
    Par défaut Accéder à un boitier 8 relais USB, erreur de segmentation
    Bonjour,

    Je suis sous Debian 7.

    Je tente d'écrire un programme en C me permettant de commander des relais connectés sur un port USB.
    J'utilise la librairie libusb

    J'initialise l'accès à l'USB
    OK

    Je scanne les devices USB
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    libusb_get_device_list(...)
    OK

    Je recherche mon boitier USB dans la liste connaissant idVendor et idProduct (boitier KEMO : 0x1781 et 0x08c0)
    C'est une boucle avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    libusb_get_device_descriptor(dev, &desc)
    OK

    J'ai donc bien ma structure libusb_device_descriptor desc avec desc.idVendor et desc.idProduct
    et je trouve mes données desc.idVendor 0x1781 et desc.idProduct 0x08c0

    et enfin je veux ouvrir mon device :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int usb_open = libusb_open(dev, handle);
    ça plante méchamment : Erreur de segmentation !!!

    Là, je bloque...

    Quelqu'un a t-il une idée ?


    Merci
    Bertrand

  2. #2
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Sans chercher dans la doc, vu que c'est un open, je parie que tu n'as pas initialisé un pointeur correctement.
    Je pense qu'il faut lui donner l'adresse d'une variable bien construite

    je m'attend à voir un code du type:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int usb_open = libusb_open(dev, &handle);
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  3. #3
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2014
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2014
    Messages : 345
    Points : 1 211
    Points
    1 211
    Par défaut
    D'après la doc :

    int libusb_open(libusb_device *dev, libusb_device_handle **devh)

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 42
    Points : 30
    Points
    30
    Par défaut
    Côté déclaration, j'ai bien fait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    struct libusb_device_handle *handle;
    et je n'ai aucun warning avec le compilateur...


    Je viens d'essayer avec la fonction directe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    handle = libusb_open_device_with_vid_pid(...);
    le programme ne se plante pas...

    mais quand je transfert des données, ça me retourne -1
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    r = libusb_submit_transfer(commande);
    en pensant bien initialiser la "commande"...
    Je cherche...

  5. #5
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 678
    Points
    13 678
    Billets dans le blog
    1
    Par défaut
    et je n'ai aucun warning avec le compilateur...
    Quelle est la ligne de commande pour compiler ?

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 42
    Points : 30
    Points
    30
    Par défaut
    Je n'ai pas de ligne de commande à part make (Makefile) repris de l'exemple livré avec la librairie libusb-1.0.9

  7. #7
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Regarde le makefile.
    Dans la compilation, y a-t-il -Wall -Wextra?
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  8. #8
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 376
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 376
    Points : 23 655
    Points
    23 655
    Par défaut
    Vérifie également si le répertoire qui contient ton code et ton Makefile ne contient pas également un script nommé « configure ». Si c'est le cas, ça veut dire qu'il s'appuie sur les autotools et qu'il faut le lancer une fois au préalable pour qu'il adapte à ton environnement en particulier.

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 42
    Points : 30
    Points
    30
    Par défaut
    Décidément, je n'arrive à résoudre mon problème. Je n'ai plus d'erreur de segmentation mais je le message "No such file or directory" sur la commande libusb_submit_transfer !
    C'est fort en chocolat. Si l'on regarde le résultat de strace, c'est l'équivalent d'un ioctl avec le bon descripteur...

    Source :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
     
    int main(int argc, char *argv[])
    {
        unsigned char *buf;
     
        libusb_device **list;
        libusb_device_handle *handle;
     
        printf("Hello world !\n");
     
        int r;
        ssize_t cnt;
     
        //initialisation des fonctions d'accès à USB
        r = libusb_init(NULL);
        if (r < 0)  {
            printf("Probleme d'initialisation de libusb... %d\n", r);
    		return r;
        } else {
            printf("Initialisation de libusb réussi... %d\n", r);
        }
     
        // scan des devices USB
        cnt = libusb_get_device_list(NULL, &list);
    	if (cnt < 0)    {
    	    printf("Probleme aucun device USB trouve...\n");
    		return (int) cnt;
        }
     
        //recherche du device KEMO 0x1781 - 0x08c0
        handle = (libusb_device_handle *)cherche_KEMO(list);
     
     
        libusb_free_device_list(list, 0);
        // on alloue une structure pour le transfert
        commande = libusb_alloc_transfer(0);
        buf = malloc(4);
        buf[0] = 0x00;
        buf[1] = 0x08;
        libusb_fill_bulk_transfer(commande, handle, 2, buf, 2, NULL, NULL, 0);
     
        r = libusb_submit_transfer(commande);
        if ( r == -1 )  {
            switch (errno)  {
                case LIBUSB_ERROR_ACCESS : printf("device déconnecté\n");
                case LIBUSB_ERROR_BUSY : printf("transfert déjà réalisé\n");
                case LIBUSB_ERROR_NOT_SUPPORTED : printf("flags de transfer non supportés\n");
                default : perror("Default : ");
            }
            perror("Problème : ");
            printf("\n");
            printf("retour de commande de transfert %d et %d\n", r, errno);
        }

    J'insère aussi chercheKEMO
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
     
    libusb_device_handle* cherche_KEMO(libusb_device **list)   {
     
        libusb_device *dev;
        libusb_device_handle *handle;
     
        int i = 0;
        int r;
     
        printf("Recherche du device KEMO...\n");
     
        while ((dev = list[i++]) != NULL)    {
            struct libusb_device_descriptor desc;
     
            r = libusb_get_device_descriptor(dev, &desc);
            if ( r < 0 )    {
                printf("Problème pour lire le descripteur\n");
                return NULL;
            }
     
            printf("%04x:%04x (bus %d, device %d)\n",
                desc.idVendor, desc.idProduct,
                libusb_get_bus_number(dev), libusb_get_device_address(dev));
     
            if (desc.idVendor == VENDEUR && desc.idProduct == PRODUIT)   {
                //on a trouve le KEMO !
                printf("Le module KEMO est trouve...\n");
     
                //on demande un accés
                int usb_open = libusb_open(dev, &handle);
     
                if ( usb_open == 0) {
                    printf("usb_open est à 0, c'est bon !\n");
     
                    dump_dev(dev);
     
                    return handle;
                }
     
                printf("Le module KEMO n'est pas accessible...\n");
                printf("erreur code %d.\n", usb_open);
            }
     
        }
     
     
     
        return NULL;
    }

    et la fin du résultat strace...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    write(1, "1781:08c0 (bus 2, device 2)\n", 281781:08c0 (bus 2, device 2) ) = 28
    write(1, "Le module KEMO est trouve...\n", 29Le module KEMO est trouve... ) = 29
    open("/dev/bus/usb/002/002", O_RDWR)    = 6
    write(4, "\1", 1)                       = 1
    read(3, "\1", 1)                        = 1
    write(1, "usb_open est \303\240 0, c'est bon !\n", 31usb_open est à 0, c'est bon ! ) = 31
    ioctl(6, USBDEVFS_SUBMITURB or USBDEVFS_SUBMITURB32, 0xf683d0) = -1 ENOENT (No such file or directory)
    dup(2)                                  = 7
    fcntl(7, F_GETFL)                       = 0x8002 (flags O_RDWR|O_LARGEFILE)
    fstat(7, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0
    mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f831e867000
    lseek(7, 0, SEEK_CUR)                   = -1 ESPIPE (Illegal seek)
    write(7, "Default : : No such file or dire"..., 38Default : : No such file or directory ) = 38
    close(7)                                = 0
    munmap(0x7f831e867000, 4096)            = 0
    dup(2)                                  = 7
    fcntl(7, F_GETFL)                       = 0x8002 (flags O_RDWR|O_LARGEFILE)
    fstat(7, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0
    mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f831e867000
    lseek(7, 0, SEEK_CUR)                   = -1 ESPIPE (Illegal seek)
    write(7, "Probl\303\250me : : No such file or di"..., 40Problème : : No such file or directory ) = 40
    close(7)                                = 0
    munmap(0x7f831e867000, 4096)            = 0
    write(1, "\n", 1
    )                       = 1
    write(1, "retour de commande de transfert "..., 40retour de commande de transfert -1 et 2 ) = 40
    write(4, "\1", 1)                       = 1
    read(3, "\1", 1)                        = 1
    close(6)                                = 0
    exit_group(0)                           = ?

    Des idées ???

  10. #10
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 42
    Points : 30
    Points
    30
    Par défaut
    Autres tests plus simples...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    int fd;
    int ret;
    int size = 0;
    char *buffer;
     
    //struct hidraw_report_descriptor report;
     
    int main(int argc, char *argv[])
    {
        fd = open("/dev/bus/usb/002/002", O_RDWR);
        if (fd < 0 )    {
            perror("Erreur d'ouverture du device ");
        }
     
        ret = write(fd, "coucou", 6);
        if (ret != 0)   {
            perror("Erreur sur la cmd write");
        }
     
        buffer = malloc(1024);
        buffer[0] = 0;
        buffer[1] = 0x08;
        ret = ioctl(fd, USBDEVFS_SUBMITURB, buffer);
        if (ret != 0)   {
            perror("Erreur sur la cmd ioctl");
        }
     
        close(fd);
    La commande write sort en erreur : invalid argument

    La commande ioctl sort en erreur No such file or directory



    et le strace

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    open("/dev/bus/usb/002/002", O_RDWR)    = 3
    write(3, "coucou", 6)                   = -1 EINVAL (Invalid argument)
    dup(2)                                  = 4
    fcntl(4, F_GETFL)                       = 0x8002 (flags O_RDWR|O_LARGEFILE)
    brk(0)                                  = 0x641000
    brk(0x662000)                           = 0x662000
    fstat(4, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0
    mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f72117a4000
    lseek(4, 0, SEEK_CUR)                   = -1 ESPIPE (Illegal seek)
    write(4, "Erreur sur la cmd write: Invalid"..., 42Erreur sur la cmd write: Invalid argument ) = 42
    close(4)                                = 0
    munmap(0x7f72117a4000, 4096)            = 0
    ioctl(3, USBDEVFS_SUBMITURB or USBDEVFS_SUBMITURB32, 0x641010) = -1 ENOENT (No such file or directory)
    dup(2)                                  = 4
    fcntl(4, F_GETFL)                       = 0x8002 (flags O_RDWR|O_LARGEFILE)
    fstat(4, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0
    mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f72117a4000
    lseek(4, 0, SEEK_CUR)                   = -1 ESPIPE (Illegal seek)
    write(4, "Erreur sur la cmd ioctl: No such"..., 51Erreur sur la cmd ioctl: No such file or directory ) = 51
    close(4)                                = 0
    munmap(0x7f72117a4000, 4096)            = 0
    close(3)                                = 0
    exit_group(0)                           = ?

  11. #11
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 42
    Points : 30
    Points
    30
    Par défaut
    Toujours en période de test....

    La commande
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ioctl(fd,USBDEVSFS_IOCTL, buffer);
    plante avec l'erreur "Inappropriate ioctl for device"...


    Comment peut-on connaitre les significations des paramètres comme USBDEVSFS_IOCTL ?

  12. #12
    Membre expérimenté Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    625
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 625
    Points : 1 564
    Points
    1 564
    Par défaut
    Hello,

    Citation Envoyé par Le Bertch Voir le message
    Autres tests plus simples...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
        ....
     
    int main(int argc, char *argv[])
    {
        ....
     
        ret = write(fd, "coucou", 6);
        if (ret != 0)   {
            perror("Erreur sur la cmd write");
        }

    write() renvoie le nombre de bytes écrits, 0 signifiant aucun byte écrit, et -1 en cas d'erreur: http://man.developpez.com/man2/write/. Il te faut donc tester un retour <> du nombre de byte demandé en écriture pour savoir si tu as une erreur, et si oui, laquelle.

    A+

    Edgar.
    On écrit "J'ai tort" ; "tord" est la conjugaison du verbre "tordre" à la 3ème personne de l'indicatif présent

  13. #13
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 42
    Points : 30
    Points
    30
    Par défaut
    Merci edgarjacobs

    Je n'avais pas trop fait attention....




    Je commence à comprendre :

    ioctl(fd, USBDEVS_RESET, NULL);

    ça marche !! C'est bon signe.

    Si j'ai bien compris, si j'utilise le paramètre USBDEFS_IOCTL, alors l'info complémentaire doit être une structure usbdevfs_ioctl comme signaler dans http://lxr.free-electrons.com/source...vice_fs.h#L117





    USBDEVS_RESET n'a pas besoin d'info complémentaire donc NULL.




    Si j'utilise ret = ioctl(fd, USBDEVFS_SUBMITURB, buffer);
    buffer doit être une structure usbdevfs_urb
    (cf #define USBDEVFS_SUBMITURB _IOR('U', 10, struct usbdevfs_urb)

    ==> gloupsssss
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     96 struct usbdevfs_urb {
     97         unsigned char type;
     98         unsigned char endpoint;
     99         int status;
    100         unsigned int flags;
    101         void __user *buffer;
    102         int buffer_length;
    103         int actual_length;
    104         int start_frame;
    105         union {
    106                 int number_of_packets;  /* Only used for isoc urbs */
    107                 unsigned int stream_id; /* Only used with bulk streams */
    108         };
    109         int error_count;
    110         unsigned int signr;     /* signal to be sent on completion,
    111                                   or 0 if none should be sent. */
    112         void __user *usercontext;
    113         struct usbdevfs_iso_packet_desc iso_frame_desc[0];
    114 };
    115

    C'est pour cela qu'il existe des fonctions d'aide libusb_fill_...


    Bon je continue...

  14. #14
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 42
    Points : 30
    Points
    30
    Par défaut
    Je me lance :



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
        struct usbdevfs_urb *urb;
        size = sizeof(struct usbdevfs_urb);
     
        printf("Taille de la struct usbdevfs_urb %d\n", size);
     
        urb = malloc(size);
     
        urb->type = USBDEVFS_URB_TYPE_CONTROL;
        urb->endpoint = ENDPOINT;
     
        buffer = malloc(2);
        urb->buffer = (void *)buffer;
        urb->buffer_length = 2;
        buffer[0] = 0;
        buffer[1] = 0x08;
     
        ret = ioctl(fd, USBDEVFS_SUBMITURB, urb);
        if (ret != 0)   {
            perror("Erreur sur la cmd ioctl");
        }
    Si ENDPOINT 0x00
    invalid argument

    Si ENDPOINT 0x01
    No such file or directory

    Si ENDPOINT 0x80
    invalid argument

    Si ENDPOINT 0x81
    Device or resource busy





    Je sens que je m'approche de la solution...

  15. #15
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 42
    Points : 30
    Points
    30
    Par défaut
    Comment connaître le endpoint ?

  16. #16
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    google USB ENDPOINT usbdevfs?

    cat /proc/mounts ?
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  17. #17
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 42
    Points : 30
    Points
    30
    Par défaut [RESOLU] Accéder à un boitier 8 relais USB, erreur de segmentation
    Merci de vos suggestions !

    Bon mon affaire est résolue après deux jours de tâtonnement et la découverte de la programmation d'un port USB, il faut en faire profiter les autres !

    1/ Comment connaître le endpoint ?
    google USB ENDPOINT usbdevfs ? Non ça m'a encore plus perturbé qu'autre chose !

    Simplement avec la commande lsusb -v qui donne tout ce qu'il faut. Les infos intéressantes sont :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    Bus 005 Device 009: ID 1781:08c0 Multiple Vendors 
    Device Descriptor:
      bLength                18
      bDescriptorType         1
      bcdUSB               1.10
      bDeviceClass            0 (Defined at Interface level)
      bDeviceSubClass         0 
      bDeviceProtocol         0 
      bMaxPacketSize0         8
      idVendor           0x1781 Multiple Vendors
      idProduct          0x08c0 
      bcdDevice            0.02
      iManufacturer           1 Kemo-Electronic GmbH
      iProduct                2 USB general purpose interface (c)
      iSerial                 0 
      bNumConfigurations      1
      Configuration Descriptor:
        bLength                 9
        bDescriptorType         2
        wTotalLength           34
        bNumInterfaces          1
        bConfigurationValue     1
        iConfiguration          0 
        bmAttributes         0x80
          (Bus Powered)
        MaxPower              100mA
        Interface Descriptor:
          bLength                 9
          bDescriptorType         4
          bInterfaceNumber        0
          bAlternateSetting       0
          bNumEndpoints           1
          bInterfaceClass         3 Human Interface Device
          bInterfaceSubClass      0 No Subclass
          bInterfaceProtocol      0 None
          iInterface              0 
            HID Device Descriptor:
              bLength                 9
              bDescriptorType        33
              bcdHID               1.00
              bCountryCode            0 Not supported
              bNumDescriptors         1
              bDescriptorType        34 Report
              wDescriptorLength      52
              Report Descriptor:
                   ** UNAVAILABLE **
         Endpoint Descriptor:
            bLength                 7
            bDescriptorType         5
            bEndpointAddress     0x81  EP 1 IN
            bmAttributes            3
              Transfer Type            Interrupt
              Synch Type               None
              Usage Type               Data
            wMaxPacketSize     0x0008  1x 8 bytes
            bInterval              10
    Device Status:     0x0000
      (Bus Powered)

    Dans mon cas :
    bNumInterfaces 1 : 1 seul interface
    Interface Descriptor:
    bNumEndpoints 1 : un seul Endpoint (sans compter le Endpoint 0 par défaut)
    Endpoint Descriptor:
    bEndpointAddress 0x81 : à l'adresse 0x81

    Le type de transfert est l'interruption (sans compter le transfert Contrôle qui existe sur tous les devices USB)

    J'ai vite avancé grâce à ça cliquez ici
    et en arrangeant le programme à ma sauce ;

    2/ Initialiser la librairie pour USB :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        r = libusb_init(NULL);
        if (r < 0) {
            fprintf(stderr, "Failed to initialise libusb\n");
            exit(1);
        }
    3/ La recherche du device à partir de la lib libusb :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    static int find_lvr_hidusb(void)
    {
        devh = libusb_open_device_with_vid_pid(NULL, VENDOR_ID, PRODUCT_ID);
        return devh ? 0 : -EIO;
    }
    Avec la commande lsusb ou lsusb -v, on trouve les infos VENDOR_ID, PRODUCT_ID

    4/ Détacher le lien "bloquant" entre le noyau et le device qui s'est établit au moment de l'hotplug. ça je l'ai découvert un peu par hasard, sous windows pas besoin...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    libusb_detach_kernel_driver(devh, 0);
    5/ Lier l'interface à notre programme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    r = libusb_claim_interface(devh, 0);
        if (r < 0) {
            fprintf(stderr, "libusb_claim_interface error %d\n", r);
            goto out;
        }
        printf("Successfully claimed interface\n");
    6/ Y'a plus qu'à envoyer des données à ma carte pour commander les relais... Oui mais comment ?
    Cette carte est livrer avec un programme sous linux et quelques sources en C, pascal... mais pas d'explication. La société KEMO (en Allemagne) ne pas déniée m'aider...

    ==> utiliser un logiciel de trace USB sous windows, USBTrace, il est gratuit pendant 15 jours après l'installation... cliquez ici

    Voilà, il y avait deux paquet d'initialisation avant de pouvoir commander les relais ; j'ai utilisé le transfert par contrôle...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    void envoie_output(void)   {
        int r;
        r = libusb_control_transfer(devh,
                CTRL_OUT,
                HID_SET_REPORT,
                (HID_REPORT_TYPE_OUTPUT<<8)|0x00,
                0,
                buffer,
                PACKET_CTRL_LEN,
                TIMEOUT);
     
     
        if (r < 0) {
            fprintf(stderr, "Control Out error %d\n", r);
            fprintf(stderr, "%s\n", libusb_error_name(r));
            return;
        }
     
        printf("r = %d\n", r);
     
    }
    Voilà !

    Finalement c'était simple non ?

  18. #18
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 678
    Points
    13 678
    Billets dans le blog
    1
    Par défaut
    Merci pour ton retour d'expérience

    Je n'ai pas pensé à parler de lsusb, car je pensais que tu connaissais Visiblement, cela aurait pû te servir.

  19. #19
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 42
    Points : 30
    Points
    30
    Par défaut
    Connaître oui, l’interpréter, un peu moins, comme je l'ai signalé, je découvrais l'USB et je m'étais contenté de vérifier avec l'iVendor et iProduct que l'os reconnaissait bien la carte. Ensuite, je n'avais aucune certitude sur la méthode de dialogue (j'ai attaqué par du bulk, erreur !!!!) et le protocole de fonctionnement étais pratiquement inconnu...

  20. #20
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 678
    Points
    13 678
    Billets dans le blog
    1
    Par défaut
    Pour être honnête, je sais me servir de lsusb pour connaitre mes périphériques mais rien de plus ^^

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. communication usb erreur
    Par Deskwisk dans le forum C
    Réponses: 0
    Dernier message: 17/06/2010, 14h16
  2. USB - Erreur 997
    Par Themacprod2 dans le forum API, COM et SDKs
    Réponses: 1
    Dernier message: 24/08/2008, 01h26
  3. programme qui detecte une cle USB ERREUR
    Par dimainfo dans le forum Entrée/Sortie
    Réponses: 1
    Dernier message: 11/06/2008, 11h24
  4. [Cle USB] Erreur de redondance cyclique
    Par raymon dans le forum Composants
    Réponses: 2
    Dernier message: 02/05/2008, 15h54
  5. Disque USB erreur au Boot
    Par n1portki dans le forum Administration système
    Réponses: 5
    Dernier message: 24/03/2008, 00h24

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo