Kommunauty
Connexion
Inscription

( C ) Port série overlapped: problème de récupération des données


rasta69 Messages : 1

système: windows 7

IDE: code::block

Bonjour,

Je sollicite encore une fois de l'aide sur ce site car j'ai un rencontrer un problème pour programmer un événement sur un port série sou windows.

Mon but est était d'abord de créer un "time out" sur la fonction de lecture du port série ( ReadFile() ) pour qu'elle ne bloque indéfiniment le programme, sa j'ai pue le faire avec la fonction SetCommTimeout(). Ce "time out" une fois configurer, on peut invoquer la fonction ReadFile() qui ce stop au bout du temps configurer précédemment, mais le probléme c'est que si on reçoit des données à la moitié du "time out" il faut attendre la totalité du temps pour pouvoir traiter les données.

Donc dans deuxième temps j'ai voulue instauré un événement avec un "time out" qui lui ci stop quand des données sont présente sur le port série(ou plutôt dans les buffer interne du port série...enfin là je suis pas sur)

Sa aussi j'ai réussit à le réaliser, mais mon problème vient du fait que je n'arrive pas à récupérer les données aprés que l'événement se soit déclenché.

En faite mon programme réagit très bien, j'ai raccordé deux pc, sur l'un j'ai créer un générateur de trame qui envoi une chaîne de caractère passé en argument et sur l'autre il y a mon programme avec un événement qui attend des données en reception. Quant je déclenche le générateur de trame, mon événement détecte les données, puis il invoque la fonction ReadFile() qui au passage génére une erreur ( ERROR_IO_PENDING -> Overlapped I/O operation is in progress), puis j'affiche mon buffer de reception et là rien .

(ps: je vous rassure mes port comme sur chaque pc sont configurer exactement pareil)

Je pense que l'erreur généré y est pour quelque chose, et encore je ne croie pas (là aussi je ne suis pas sur).

voici mon code:


#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

#define READ_TIMEOUT      9000

int main()
{

  HANDLE fd = NULL;   // descripteur de fichier du port com
  struct _DCB info;   // struture de configuration du port com
  unsigned char buffer_r[101];    // buffer de donnees de reception
  DWORD bit_rw; // variable du nombre d'octet ecrit sur le port com
  char port[]="COM4\0";  // identifiant du port com sur le système

// ouverture du port com

fd = CreateFile(                 port,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL );

if(fd == INVALID_HANDLE_VALUE)
{
printf("\n :: Erreur d'ouverture du port %s ::\n", port);
exit(0);
}
else printf("\n :: Ouverture du port %s ::\n", port);


// recuperation de la configue du port com

memset(&info, '\0', sizeof(struct _DCB));

// recupere la configue du port com
if ( GetCommState(fd, &info) == 0)
{
printf(" :: Impossible de recuperer la configuration du port %s ::\n", port);
exit(0);
}
else printf(" :: Configuration actuelle du port %s ::\n", port);


// configuration du port com pour une utilisation classique  8N1 (8 data bits, N no parity, 1 stop bit)

info.ByteSize = 8;
info.BaudRate = CBR_9600;
info.Parity   = NOPARITY;
info.StopBits = ONESTOPBIT;

info.fBinary = 1;
info.fParity = 0;
info.fNull = 0;

info.fOutxCtsFlow = 1;
info.fOutxCtsFlow = 1;

info.fDtrControl = DTR_CONTROL_ENABLE;
info.fRtsControl = RTS_CONTROL_ENABLE;

// configure le port com
if( SetCommState(fd, &info) == 0)
{
printf("\n :: Impossible de configurer le port %s ::\n", port);
exit(0);
}
else printf("\n :: Changement de la configuration du port %s ::\n", port);


// création de l'événement

OVERLAPPED com_ev  = {0};  
DWORD mask;
DWORD iHandle;

com_ev.hEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); // crée l'événement

SetEvent( com_ev.hEvent ); // enregistre l'événement

SetCommMask( fd, EV_RXCHAR ); // spécifie le type d'événement (ici EV_RXCHAR indique que l'on attend une donnée sur la broche RX de reception du port série)

WaitCommEvent( fd, &mask, &com_ev ); // enregistre le type d'événement souhaité


iHandle = WaitForSingleObject(com_ev.hEvent, READ_TIMEOUT); // attend que l'événement souhaité se produise, avec une valeur de time out de 9s

if( iHandle == WAIT_OBJECT_0 ) // si l'événement c'est réalisé avec succée alors on récupére les données
{
if( ReadFile(fd, &buffer_r, (sizeof(buffer_r)-1), &bit_rw, &com_ev) == 0 ) // lit les données sur le port série
{
printf("ERROR: %ld\n\n", GetLastError() );
}

printf(" buffer de reception: \n\n %s\n\n\n", buffer_r );  // affiche le buffer de reception des données

}

Voilà, je pense que il y a quelque chose que je n'ai pas compris, peut-être que mon code n'est pas bon, la fonction ReadFile() n'est peut être pas à la bonne place.

J'ai aussi pensé que je devais mal configurer ma stucture _DCB qui à son tour paramétre le port série (c'est probable).

J'ai testé tout un tas de chose dont voicie les liens et rien ne marche ou du moins je suis ppas doué. En tout cas j'ai trouvé aucun exemple propre qui fonctionne :

http://cpp.developpez.com/faq/vc/?page [...] ithSerialPort (je me suis inspiré de celui-ci)

http://msdn.microsoft.com/en-us/librar [...] serial_topic4

http://www.siteduzero.com/forum-83-804 [...] ertinent.html

http://forum.hardware.fr/hfr/Programma [...] t_35230_1.htm

Merci d'avance pour toute réponse ou lien qui pourrait me mettre sur la voie.

samedi 13 octobre 2012

Répondre Pour répondre, tu dois d'abord t'inscrire rapidement sur Kommunauty. Rejoins-nous vite !