2009-07-16 11 views
1

J'utilise select call pour communiquer avec un sous-système externe (le protocole pour celui-ci a été fourni et implémenté comme un thread Qt) en utilisant le port série RS232. Nous n'avons pas le matériel pour les systèmes externes et nous avons donc développé des simulateurs internes utilisant .Net 2.0 et C# pour imiter le comportement du matériel du sous-système sous-jacent. Il y a 5 sous-systèmes différents qui communiquent avec notre application. Chaque interface du sous-système est implémentée en tant que thread Qt. Comme ce n'est pas une application en temps réel, et que nous n'avons pas le matériel réel lorsque nous communiquons à l'aide de simulateurs, tous les systèmes le trouvent pendant 24 heures environ et après cela, la communication va et vient, mais quand je redémarre la machine de simulation sans fermer mon application, les choses se passent bien. Pourquoi cela arrive-t-il? Je pense que, puisque .Net/C# n'est pas un framework en temps réel et que les simulateurs ont fonctionné pendant 24 heures, les débits d'envoi de données commencent à ralentir, les ports série se colmatent; le redémarrage rince tout et donc tout revient à la normale. C'est juste une supposition. Si quelqu'un a une meilleure opinion, partagez-la. Notez que les simulateurs ont été réalisés par une équipe différente de gars .Net.anomalie de communication série sous Linux?

Remarque: Chaque protocole a des débits de données différents, 1 Hz, 5 Hz, 10 Hz.

Il existe un système qui ne reprend pas la communication même après que le simulateur pour celui-ci soit redémarré après le redémarrage. La configuration du port pour ce système est

SetPortConfiguration() 
{ 
    tcgetattr(Fd,&mOldtio); 
     mNewtio.c_cflag = B4800 | CS8 | CLOCAL | CREAD | CRTSCTS; 
     mNewtio.c_iflag = 0; //setting the input flag to icrnl causes a blank frame to be displayed after every frame. 
     mNewtio.c_oflag = 0; 
     mNewtio.c_lflag =ICANON; 
     mNewtio.c_cflag &=~PARENB; 
     mNewtio.c_cflag &= ~CSTOPB; 
     //mNewtio.c_cflag &= ~HUPCL; //added on 24/3/09 
     mNewtio.c_cc[VEOL]=0; //setting VEOL to '\r' or '\n' causes a blank frame to be displayed after every frame. 
     mNewtio.c_cc[VKILL] = 0;  /* @ */ 
     mNewtio.c_cc[VSTART] = 0;  /* Ctrl-q */ 
     mNewtio.c_cc[VSTOP] = 0;  /* Ctrl-s */ 
     mNewtio.c_cc[VMIN]=0; 
     mNewtio.c_cc[VTIME]=0; 
     tcflush(Fd, TCIFLUSH); 
     tcflow(Fd,TCION); 
     tcsetattr(Fd,TCSANOW,&mNewtio); 
} 

Il y a également une fonction de port reset:

ResetPort() 
{ 
    tcflush(Fd, TCIFLUSH); //flush all data received but not read 

    tcflow(Fd,TCIOFF); //transmits a STOP character, which stops the terminal device from transmitting data to the system 
    tcsetattr(Fd, TCSANOW, &mOldtio);//set the old terminal settings 

    ClosePort(); //close port 
    OpenPort(mStrPortNo); //open the port specified by port number and in read mode 
    SetPortConfiguration(); 
} 

En cas de rupture de la communication, j'appeler la fonction ResetPort qui ferme et rouvre le port. Cela résout le problème dans tous les cas sauf un système dit XYZ. Le système XYZ envoie des données au format NMEA avec chaque paquet sous la forme d'une chaîne de données terminée par une combinaison Carriage Return, LineFeed.

Des idées sur ce qui pourrait être le problème?

+0

Vous devez être plus clair; il n'est pas clair pour moi si le système de réception est connecté aux cinq sous-systèmes sur le même port, ou s'ils ont chacun un port série dédié. Je suppose que ce dernier point, puisque les ports série sont point à point et ne sont pas facilement partagés, mais il serait bon que cela soit clair dans la question. – unwind

Répondre

0

J'ai résolu le problème. Mes excuses si je ne pouvais pas comprendre ce que je voulais dire. Auparavant, nous utilisions la gestion des signaux pour l'interfaçage série avec chaque système connecté à un port série dédié, cette conception était défectueuse dès le départ car le gestionnaire de signal dans notre cas était trop complexe. Idéalement, un gestionnaire de signal devrait simplement définir des drapeaux, ne pas impliquer d'appels de fonctions car il peut y avoir des problèmes de synchronisation à gérer, puis il se propage dans un cauchemar de synchronisation difficile à débuguer comme je l'ai découvert dans mon application. Cette conception entraîne une perte de paquets provenant des ports série. Pour faire face à cette situation, nous utilisions la fonction de remise à zéro du port, qui était une manière grossière de rectifier le problème de la perte de paquets. J'ai laissé tomber le gestionnaire de signal et utilisé l'appel select pour des systèmes individuels. Mais n'a pas laissé tomber le port de réinitialisation qui faisait partie de la conception antérieure. Lors du débogage, j'ai trouvé une fonction parasite de resetport et l'ai abandonnée. Voila !! tout fonctionne parfaitement maintenant. Enregistre, mon conseil à toute personne qui utilise la communication série sur un paltform linux pour utiliser l'appel système sélectionné. Vous êtes dispensé de gérer les détails de la communication série et vous vous concentrez uniquement sur le traitement des paquets entrants.

J'espère que cette solution aidera tous ceux qui travaillent sur la communication série sur les plates-formes Linux/Unix. Il n'y a pas beaucoup de littérature sur le sujet et toute recherche sur le net vous mènera à certains documents de Mike et Sweet qui bien que peu d'aide dans des applications pratiques. Je reconnais l'aide offerte par tous les membres de stackoverlow qui m'a donné des perspectives impensables pour regarder le problème à portée de main. Merci les gars, bravo !!!!!!

1

Le bit ".Net temps réel" est un faux-fuyant. Les ports série sont si lents qu'un 8086 pourrait les contrôler. Tout processeur moderne aura probablement des cycles à épargner, même à 115200 bauds. Même si ce n'est pas le cas, la profondeur des tampons RS232 est généralement mesurée en millisecondes et non en heures. Le "colmatage" des ports série pousse trop loin les analogies physiques.

Il est difficile de savoir exactement ce qui cause votre problème car vous ne nous avez pas dit ce que c'est. "Breaks down" n'est pas quelque chose que nous pouvons résoudre. Les octets perdus, les écritures expirent - c'est le genre de comportement concret que nous pouvons aborder.