1. #1
    Membre du Club
    Inscrit en
    octobre 2009
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : octobre 2009
    Messages : 47
    Points : 41
    Points
    41

    Par défaut Communication via port serie

    Bonjour,

    J'ai développé un petit driver pouvoir transmettre des informations via le port COM1 entre un petit noyau et une machine hôte.
    En indiquant à Bochs d'enregistrer ce qui sort du port serie depuis le noyau, ça marche nickel (donc avec comme paramètre indiqué à bochs : com1: enabled=1, mode=file, dev=serial.txt).
    Mon but est maintenant de transmettre des info depuis ma machine hôte vers le noyau. J'ai pour ça essayer d'écrire dans le fichier sans trop d'espoir, j'ai ensuite testé avec l'utilisation d'un pipe mais ça ne semble juste pas possible sous linux... quelqu'un pour confirmer ? Si oui existe-t-il un autre moyen ? (j'ai testé avec ça mais bizarrement aucune erreur, rien ne se passe.. com1: enabled=1, mode=pipe, dev=/tmp/myfifo).

    J'ai vérifié la configuration du pic, et la l'interruption en question n'est pas masquée à priori :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    mov al, 0xEC
    out 0x21, al ; horloge, clavier et COM1
    J'ai vérifié l'état de mon idt, j'ai bien l'adresse de ma routine de renseignée à priori, et celle de l'horloge est bien appelée donc pas de problème d'interruption :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    IDT[0x20]=32-Bit Interrupt Gate target=0x0008:0x000016b0, DPL=0 // horloge (IRQ0)
    IDT[0x21]=32-Bit Interrupt Gate target=0x0008:0x000016d0, DPL=0 // clavier (IRQ1)
    IDT[0x22]=32-Bit Interrupt Gate target=0x0008:0x00001690, DPL=0 // routine par defaut...
    IDT[0x23]=32-Bit Interrupt Gate target=0x0008:0x00001690, DPL=0
    IDT[0x24]=32-Bit Interrupt Gate target=0x0008:0x000016f0, DPL=0  // port COM1 (IRQ4)
    IDT[0x25]=32-Bit Interrupt Gate target=0x0008:0x00001690, DPL=0
    Bonne journée

    Edit : j'ai aussi tenté le coup avec qemu, pour le coup j'ai réussi à recevoir des données depuis le noyau dans mon pipe (au lieu d'un fichier avec bochs), mais je n'arrive toujours pas à envoyer des données à mon noyau via ce même pipe... La commande utilisée pour qemu : qemu-system-i386 -boot a -fda floppyA -serial pipe:/tmp/myfifo

  2. #2
    Membre confirmé Avatar de bifur
    passe le balais et l'aspirateur
    Inscrit en
    mars 2008
    Messages
    274
    Détails du profil
    Informations personnelles :
    Âge : 33

    Informations professionnelles :
    Activité : passe le balais et l'aspirateur

    Informations forums :
    Inscription : mars 2008
    Messages : 274
    Points : 460
    Points
    460

    Par défaut

    j'y connait rien en Bosch et qemu donc je ne pourrait pas t'aider si c'est un problème de configuration de ces logiciel (je travaille sur machine réelle)

    j'ai regardé de mon coté comment j'avait fait pour gérer les port com et je me suis aperçu que j'utilisait les irq 3 et 4 qui me renvoyait sur une routine chargé de vérifier sur chaque port lequel avait reçu des données. si mes souvenir sont bon c'était l'irq 4 pour com 1 et 3 et l'irq 3 pour com 2 et 4 (mais j'ai pas vérifié) donc normalement il ne devrait pas y avoir de problème de ce coté la

    je récupère l'adresse du contrôleur de COM1 a l'adresse mémoire 0:400h, comment fait tu sur ton système? je sais qu'il y as des adresses standards mais je me méfie toujours de la bonne application des standards



    pour info ma routine pour l'irq des ports com:
    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
    irqcom: ;interruption par un controleur de port COM
    cli
    push eax
    push ebx
    push edx
    push edi
    push ds
    push es
    mov bx,seldat
    mov ds,bx
    mov bx,selramh
    mov es,bx
     
     
    xor ebx,ebx
    cherche_origine_irq_com:
    mov dx,[ebx+port_com_base]
    add dx,2    ;adress du Interrupt Identification Register
    in al,dx
     
    and al,07h   ;on test si une interruption données disponible est en cours sur le controleur
    cmp al,04h 
    ;test al,1
    je trouve_origine_irq_com
    add ebx,4
    cmp ebx,20h
    jne cherche_origine_irq_com
    jmp fin_irq_com
     
    trouve_origine_irq_com:
    sub dx,2  ;lit l'octet reçu
    in al,dx
     
    ;verifie que la zt n'est pas pleine
    mov edi,[ebx+port_com_zt]
    mov ecx,[ebx+port_com_to]
    add ecx,10h
    es
    cmp ecx,[edi+to_tache]
    jae fin_irq_com 
     
    ;ajoute dans la zt
    add edi,ecx
    es
    mov [edi],al
    inc dword[ebx+port_com_to]
     
    fin_irq_com:
    mov al,20h
    out 20h,al
    pop es
    pop ds
    pop edi
    pop edx
    pop ebx
    pop eax
    sti
    iret

  3. #3
    Membre du Club
    Inscrit en
    octobre 2009
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : octobre 2009
    Messages : 47
    Points : 41
    Points
    41

    Par défaut

    Salut !

    Merci pour ta réponse !

    Alors pour l'adresse du port COM1, je suis parti du principe que ce serait quelque chose de classique (comme indiqué sur un wiki d'osdev), mais maintenant que j'y pense peut-être devrais-je aller la chercher à la main pour être sûr !
    Pour le moment je la définie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define COM1_PORT 0x3F8
    Cependant, je ne pense pas que ce soit ça le problème étant donné que depuis le noyau, j'arrive à écrire sur le port série (et afficher le résultat en demandant à bochs de rediriger la sortie du port série vers un fichier).

    Par contre rien à faire pour envoyer, depuis mon pc (machine hôte donc), vers mon noyau émulé par bochs... J'ai tenté avec bochs et qemu, via un pipe ou encore en udp mais toujours rien.

    J'ai par contre modifié l'initialisation du port COM sur le noyau et la routine associée à l'interruption du port COM est exécutée une fois après cette initialisation (mais aucune données à lire dessus apparemment...). Ce qui me laisse penser que ce n'est pas un problème d'IDT.

    Initialisation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    void init_serial ()
    {
        outb (COM1_PORT + 1, 0x00); // Desactive les interruptions
        outb (COM1_PORT + 3, 0x80); // Active le DLAB (Divisor Latch Access Bit)
        outb (COM1_PORT + 0, 0x03); // 38400 baud (115200 / 3), bits de poid faible
        outb (COM1_PORT + 1, 0x00); //                                       fort
        outb (COM1_PORT + 3, 0x03); // 8 bits, pas de parite, un bit de stop
        outb (COM1_PORT + 2, 0xC7);
        outb (COM1_PORT + 4, 0x0B);
        outb (COM1_PORT + 1, 0x02);
    }
    Peut-être un problème lié au bit stop ? Quelque chose que je n'ai pas compris à ce sujet ?

  4. #4
    Membre confirmé Avatar de bifur
    passe le balais et l'aspirateur
    Inscrit en
    mars 2008
    Messages
    274
    Détails du profil
    Informations personnelles :
    Âge : 33

    Informations professionnelles :
    Activité : passe le balais et l'aspirateur

    Informations forums :
    Inscription : mars 2008
    Messages : 274
    Points : 460
    Points
    460

    Par défaut

    oui effectivement si l'envoie fonctionne ça ne doit pas être un problème d'adresse, et je dirait aussi que si l'envoie fonctionne, ça veut aussi dire que l'UART est bien configuré (au moins en ce qui concerne les vitesses et format des données)

    en comparant avec ma routine de configuration je voit que tu as configuré le "Interrupt enable register" avec le bit 2 qui doit déclencher une interruption lorsque que le "Transmitter" est empty (vide donc) et je croie bien que c'est pour l'envoie de donnée en plus. personellement je configure ce registre avec 0x01 (Data available)

    un autre problème pourrait survenir c'est un blocage du contrôleur d'interruption par un interruption précédente non correctement acquitté (par exemple l'interruption du timer) mais essaye de changer d'abord la configuration du IER

  5. #5
    Membre du Club
    Inscrit en
    octobre 2009
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : octobre 2009
    Messages : 47
    Points : 41
    Points
    41

    Par défaut

    Super ! Ca marche !

    Merci beaucoup pour ton aider, c'était un problème de configuration, l'"Interrupt enable register" était mal configuré... je ne pensais pas que ça marchait de cette manière... autant pour moi ! Merci encore !

    Bonne journée,

    Guidono

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

Discussions similaires

  1. communication avec port serie
    Par seignseifer dans le forum C++
    Réponses: 2
    Dernier message: 14/03/2007, 09h34
  2. communication avec port serie
    Par seignseifer dans le forum C++
    Réponses: 1
    Dernier message: 28/02/2007, 02h56
  3. Communication par port serie sous vb
    Par kapjoel dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 23/10/2006, 10h02
  4. communication par port serie
    Par sofiane61 dans le forum MFC
    Réponses: 3
    Dernier message: 06/02/2004, 15h06

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