Probleme Port SERIE avec XON/XOFF

koros

Nouveau membre
Bonjour,

Je veux pouvoir envoyer une chaine de caratcere (4) du port Com1 et la recevoir sur le port Com2 de mon pc (sous Linux red hat 9.0).
Mon probleme est que ca envoi la chaine de caractere mais je ne recois que le dernier caractere envoyé.
Cela est du au fait que si le port COM2 ne lit pas assez vite, la donnée sera ecrasé par la donnée suivante envoyé du COM1!
Donc j'ai voulu utiliser XON/OFF qui permet de regler se probleme en retardant l'émission de caractere pour ne pas ecraser le precedent sans qu'il soit lu.
Mais voilà il ne prends pas en compte le XON/XOFF que j'ai mis a l'interieur du programme suivant!

Si vous pouvez m'aider car là je suis vraiment embeter!

merci @+++
PS: je suis obligé de le faire avec ioperm...

Programme:
...
...
[cpp]
void Init_Com1(void)
{
outb(0x80,LCR); /* DLAB=1*/
outb(0x0c,DLLB); /* 9600 bauds */
outb(0x00,DLHB);
outb(0x1b,LCR); /* DLAB=0 8bits de donnee, 1 bit de stop, parite paire*/
}

void Emet_car(char car)
{
/*sleep(1);*/
while((inb(LSR)&0x40)!=0x40)
{printf("Buffer transmission plein \n ";};

if(inb(RXD)==0x13) // XON/XOFF
{ while((inb(RXD))!=0x11);
}
outb(car,TXD);
}

void Emet_chaine(char chaine[4])
{
char car_tempo;
int i=0;
while(i<4)
{ car_tempo=chaine;
Emet_car(car_tempo);
i++;
}
}

int main()
{
unsigned char val;
char buffer[4]="bonj";
char ecrit;

/*Ouverture COM1*/
val=ioperm(COM1,8,1); // ouverture com1

if (val)
{
printf("\nErreur Ioperm = %d",val);
exit(1);
}
else {printf("\nPort Com1 ouvert=%d\n",val);}

Init_Com1(); // Initialisation Com1

printf("Ecriture ?\n");
scanf("%c",&ecrit);
if (ecrit=='o')
{
Emet_chaine(buffer);
}

/* Fermeture Com1 */
val=ioperm(COM1,8,0);
if (val)
{
printf("\nErreur Ioperm = %d",val);
exit(1);
}
else {printf("\nPort Com1 ferme=%d\n",val);}

} [/cpp]


Par contre si je mets le "SLEEP(1);" dans la fonction Emet_car() ca marche tres bien! mais je voudrai ne pas le mettre!
Si ca peux vous aider voici le programme qui lit la chaine de caractere sur le port COM2:

programme:

[cpp]
void Init_Com2(void)
{
outb(0x80,LCR); /* DLAB=1*/
outb(0x0c,DLLB); /* 9600 bauds */
outb(0x00,DLHB);
outb(0x1b,LCR); /* DLAB=0 8bits de donnee, 1 bit de stop, parite paire*/
}

char Recep_car(void)
{
while((inb(LSR)&0x01)!=0x01) //Attente de donnée
return (inb(RXD));
}

cahr *Recep_chaine(void)
{
char *ptr;
ptr=(char *)malloc(sizeof(char));
char i=0,j=0,recep_car;
while(i<4)
{ recep_car=Recep_car();
*(ptr+j)=recep_car;
i++;j++; }
*(ptr+j)='\0';
return (ptr);
}

int main()
{
unsigned char val;
char *buffer;

/*Ouverture COM2*/
val=ioperm(COM2,8,1); // ouverture com1

if (val)
{
printf("\nErreur Ioperm = %d",val);
exit(1);
}
else {printf("\nPort Com1 ouvert=%d\n",val);}

Init_Com2(); // Initialisation Com2

buffer=Recep_chaine();

/* Fermeture Com2 */
val=ioperm(COM2,8,0);
if (val)
{
printf("\nErreur Ioperm = %d",val);
exit(1);
}
else {printf("\nPort Com1 ferme=%d\n",val);}

} [/cpp]

 

koros

Nouveau membre
et tu fais comment avec les semaphore?
car je suis pas un tres fort en programmation

merci
 

KangOl

Grand Maître
alors la faut que je remette mon nez dans mes cours...

mais apparement puisque tu utilise 2 programmes, il te faut une semaphore nommée (accessible a tout l'os donc)
 

Rodolphe

Habitué
C'est bien gentil les semaphores (d'ailleur un mutex suffirait à mon avis) mais si la communication se fait entre 2 PC différents (j'imagine que c'est le but final de l'appli) ben ça marchera plus.

Je n'ai jamais vraiment fait de programmation avec les ports série mais j'imagine que le destinataire doit envoyer une info de synchro lorsque que l'info a été reçu et traitée, un peu comme les ACK du protocole TCP.
Reste à savoir si l'OS le fait directement (comme dans TCP) ou qu'il faut que ce soit fait par le programmeur (comme dans UDP)
Dans le dernier cas, il faut que ton programme connecté au port Com2 envoi le ACK dès qu'il a lu l'octet que le Com1 à envoyé.
 

KangOl

Grand Maître
effectivement si c'est sur 2 pc différents, adieu les semaphores :(

il faut effectivement etablir un protocol applicatif pour que le programme 2 indique au programme 1 qu'il a lu la donnée et qu'il attend la donnée suivante.
 

zerlin

Nouveau membre
Il y a plusieurs erreurs dans le programme que je vois.
J'aimerais bien pouvoir voir les constantes...

Exemples du programme 1 (transmmission):

ligne 13: Je ne sais pas si tu as compilé, mais il manque une parenthèse:
printf("Buffer transmission plein \n ");

ligne 13: La logique qui est écrit fait en sorte que la chaîne "Buffer transmission plein \n " fload (remplie, bourre) . l'écran si le buffer est plein... Ce qui est désagréable.

Une façon plus conviviale serait:
printf("Buffer transmission plein...\n");
while((inb(LSR)&0x40)!=0x40);
printf("Buffer transmission non contingenté.\n");


ligne 13: {printf("Buffer transmission plein \n ";}; il y a un ; de trop.

ligne 15: Je crois que tu as oublié de faire un ET BINAIRE avec la lecture de RXD:
if( ( inb(RXD) & 0x13 ) ==0x13)

Même chose pour la ligne 16...

ligne 16: Même chose que la ligne 15: while((inb(RXD) & 0x11 )!=0x11);

Il y bcp d'autres erreur dans le programme, mais je crois qu'il est trop tard que je réponde à ce post presqu'un an plus tard ... Répond à ce poste si tu veux que je continu à dire les erreurs. De toute façon, même si je ne connais pas XON/XOFF, je crois que ton erreur est à la ligne 15 et 16...
 

zeb

Modérateur
Re-up intelligent (prétencieux) pour celles ou ceux qui relirait ce post :
Utiliser les fichiers spéciaux /dev/ttySN et /dev/cuaN.
 
Vous devez vous inscrire ou vous connecter pour répondre ici.
Derniers messages publiés
Statistiques globales
Discussions
730 135
Messages
6 718 110
Membres
1 586 397
Dernier membre
Chachabidou
Partager cette page
Haut