Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Timeout de port COM et ReadFile

8 réponses
Avatar
Michael
Bonjour à tous,

je me pose une question sur la bonne manière de gérer les timeouts en
lecture sur un port COM.

Je configure mon port COM comme suit:

hPortCOM = CreateFile("COM1",GENERIC_READ,0,NULL,OPEN_EXISTING,0,NULL);

if(hPortCOM != INVALID_HANDLE_VALUE)
{
bool OK = GetCommState(hPortCOM, &dcb);
if(OK)
{
dcb.BaudRate = CBR_57600;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;

OK = SetCommState(hPortCOM, &dcb);

// Modification des timeouts :
// - on attend toujours la fin de l'émission.
// - la fin de la réception est provoquée après avoir
attendu
// plus de 10 ms après le dernier caractère reçu. Si on
n'a
// rien reçu après 100 ms on sort.
COMMTIMEOUTS timeouts;
GetCommTimeouts(hPortCOM, &timeouts);

timeouts.ReadIntervalTimeout = 10;
timeouts.ReadTotalTimeoutConstant = 100;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = 0;
timeouts.WriteTotalTimeoutMultiplier = 0;

SetCommTimeouts(hPortCOM, &timeouts);

}
else
throw Exception("Impossible de configurer le port COM");
}
else
throw Exception("Impossible de configurer le port COM");


Ensuite j'aimerais lire continuellement ce qui arrive du port COM jusqu'à
ce que l'utilisateur arrête le processus:

while (!stopProcess)
{
DWORD OctetLu;
char a[17];

if (!ReadFile(hPortCOM, &a, 17, &OctetLu , 0))
throw Exception("Impossible de lire les valeurs du logger");
}

Est-ce qu'en faisant ça je suis assuré de respecter les 100ms de timeout
en lecture imposé par le matériel? (ReadFile ne quitte pas tant que ce
timeout n'est pas écoulé)

Ou bien est-ce à moi d'ajouter une condition dans la boucle while?


Merci d'avance

Mike

8 réponses

Avatar
Bertrand Lenoir-Welter
Michael :

Est-ce qu'en faisant ça je suis assuré de respecter les 100ms de timeout
en lecture imposé par le matériel? (ReadFile ne quitte pas tant que ce
timeout n'est pas écoulé)



ReadFile retourne quand 100 ms se sont écoulées OU quand les 17
caractères ont été lus.


Ou bien est-ce à moi d'ajouter une condition dans la boucle while?



Pas compris. Une condition sur quoi ?
Avatar
michael.delva
> ReadFile retourne quand 100 ms se sont écoulées OU quand les 17
caractères ont été lus.



OK, merci. Mais comme je suis dans une boucle while (!stopProcess), le
programme va continuellement aller lire les données, ce qui fait que
je vais avoir des données identiques pendant 100ms, non?

> Ou bien est-ce à moi d'ajouter une condition dans la boucle while?

Pas compris. Une condition sur quoi ?



Ben en gros un timer qui n'exécute ReadFile que toutes les 100ms...
Avatar
Bertrand Lenoir-Welter
Si vous voulez lire en continu ce qui arrive sur le port jusqu'à ce
qu'un événement externe arrête le processus, il me semble que la
solution est plus simple. Vous gardez votre timeout à 100 ms et vous ne
demandez la lecture que d'un seul caractère à la fois. Comme ça,
ReadFile vous rendra la main à chaque fois qu'un octet est disponible
dans le buffer de communication. Et vous pouvez alors oublier les
timeouts. Si ça sort sur timeout, votre variable OctetLu restera à 0.

En fait, si rien n'est arrivé sur le port, la valeur du timeout va dire
combien de temps votre processus va rester bloqué dans ReadFile. Comme
vous n'êtes pas en mode Overlapped, ça peut vous gêner pour choper
l'événement utilisateur. Donc réglez le timeout en conséquence.
Avatar
adebaene
On 22 nov, 10:21, wrote:
> ReadFile retourne quand 100 ms se sont écoulées OU quand les 17
> caractères ont été lus.OK, merci. Mais comme je suis dans une bou cle while (!stopProcess), le
programme va continuellement aller lire les données, ce qui fait que
je vais avoir des données identiques pendant 100ms, non?




Non : Quand tu lis des données depuis le port série, elles sont
suprimées du buffer de réception (heureusement!).

Ce qui va se passer, c'est que ton code va tenter de lire 17
caractères en 100ms maximum, et ce en boucle. Si les caractères
demandés n'arrivent pas dans ce délai, tu sort avec une exception.

Autrement dit, il faut que ton périphérique fournisse un flux continu
de données au rythme de 17 caractères toutes les 100ms. S'il ne
fournit pas à cette vitesse, tu sors en exception, et s'il fournit
plus vite, tu vas tomber en erreur parce que le buffer de réception
séri va se remplir jusqu'à déborder (tu n'as mis en place aucun
mécanisme pour purger ce buffer).
Il est très peu probable que ton périphérique fournisse ce genre de
garantie. Généralement, on essaie de consommer la totalité des
données au fur-et-à-mesure qu'elles arrivent. Les timeouts sont
surtout là pour détecter quand un périphérique ne parle pas alors
qu'il devrait le faire (ca permet donc de détecter les pannes ou les
déconnexions).
C'est difficile de te conseiller sur la meilleure façon
d'architecturer tout çà vu qu'on ne sait pas comment est censé
fonctionner ton périphérique.

Arnaud
MVP - VC
Avatar
Michael
> C'est difficile de te conseiller sur la meilleure façon
d'architecturer tout çà vu qu'on ne sait pas comment est censé
fonctionner ton périphérique.



Voici ce que dit la doc que j'ai sur le périphérique:

7. By using corresponding Software send via serial Port of PC following
information to "Transceiver for PC" : 0x1B 0x06 0x00 0x01 0x00 0x00
The parameters of serial port are: Baudrate 57600 Baud, 1 Startbit, 8
Databits, 1 Stopbit, no parity.
8. The "Telemetry Logger" receives this information, starts the
measurement (during measurement it makes buzz) and sends via "Remote
Transceiver" all 10 ms following information:
0xFE (first Byte as synchro Byte), 16 Bytes of pressure values of sensors 1
to 16.
The pressure values of the sensors are between 0 and 0xFA. The value 0xFA
corresponds to pressure value 62,5 N/cm², if the correction file of sensor
has been used.
Avatar
Bertrand Lenoir-Welter
> Voici ce que dit la doc que j'ai sur le périphérique:
(...)



Attends, on va pas décortiquer à ta place le fonctionnement de ton
bidule et de son environnement. Si tu veux lire des octets sur le port
série, c'est quand même pas bien sorcier et de plus super-facile à
expérimenter et débugguer. T'as toutes les infos en main : tu sais que
ReadFile vide en FIFO le buffer de réception des N octets que tu lis,
que la fonction retourne quand le nombre demandé est atteint ou que le
timeout est passé, et qu'en cas de timeout elle te dit combien d'octets
ont été effectivement reçus. Après, c'est un peu à toi de jouer...
Avatar
Arnold McDonald \(AMcD\)
Tssss. On dirait du AMcD...

--
Arnold McDonald (AMcD)

http://arnold.mcdonald.free.fr/
Avatar
Bertrand Lenoir-Welter
> Tssss. On dirait du AMcD...



Meuh non. AMcD est inimitable.