Bonjour à tous,
Je ressors un vieux dossier qui me hante...
Pour explication je refais un driver (ancien en basic donc je n'ai pas le code source, nouveau en c++) de communication avec du matériel avec lequel on communique de deux manières différentes mais le tout sur port série (SUBD9)
Pour le 1er protocole, tout va bien et ça marche du feu de Dieu : Communication asynchrone sur un simple rx/tx/masse... donc le driver marche mieux que l'ancien en terme de temps de réponse etc... surement une illusion.
Pour le second, ça se corse (enfin pour moi) : il s'appuie sur le contrôle CTS/RTS.
Après avoir bataillé sur les différentes options de mon "m_dcb.fRtsControl" en mode : ENABLE/HANDSHAKE/DISABLE... j'ai craqué et j'ai visualisé mes trames à l'oscillo numérique...
J'ai constaté un décalage de 3ms à 38400baud/s...
Résultat : j'ai fait le bourrin et j'ai désactivé toute forme de CTS/RTS géré, j'ai juste vérifié le RTS lors de la réception et j'ai mis un vieux "Sleep" dégueulasse au début de ma réception.
Ça fonctionne dans l'état, mais j'ai tout de même des pertes de trames non négligeables (voire gênant sur un port série émulé en USB)
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 /////////////////////////////////////////////////////////////////////////////// // Get data from the connection int CSerialPort::ReceiveData(DWORD lg, LPBYTE data) { DWORD read = 0; DWORD result = 0; double timer = 0; LARGE_INTEGER frequency, timeBefore, timeAfter; QueryPerformanceFrequency(&frequency); QueryPerformanceCounter(&timeBefore); while(timer < m_iTimeOut && result < lg) { if(m_bUseRTS) {Sleep(3*38400/m_iBaudRate);} else {Sleep(5*38400/m_iBaudRate);} // Reading informations from port if (!ReadFile(m_hCom, &data[result], lg-result, &read, NULL)) {return -1;} result += read; // Updating timer QueryPerformanceCounter(&timeAfter); timer = 1000.0 * (timeAfter.QuadPart - timeBefore.QuadPart) / frequency.QuadPart; } return result; } /////////////////////////////////////////////////////////////////////////////// // send data on the connection int CSerialPort::SendData(DWORD lg, LPBYTE data) { DWORD result = 0; DWORD total = 0; if(m_bUseRTS) EscapeCommFunction(m_hCom, CLRRTS); // Write data to com port if (!WriteFile(m_hCom, data, lg, &result, NULL)) {result = -1;} // CTS/RTS period if(m_bUseRTS) { Sleep(3*38400/m_iBaudRate); EscapeCommFunction(m_hCom, SETRTS); } return result; }
Donc je recherche toujours une soluce propre...
J'ai mis un '\0' à la fin de mes trames pour essayer mais ça change rien (si je me mets en 'RTS_CONTROL_HANDSHAKE' ou 'RTS_CONTROL_ENABLE')
J'ai essayé certaines classes de gestion de port série (ca passe pas), j'ai lu plusieurs fois les tutos associés dans la section qui va bien...
Si vous avez ne serait-ce que des ombres de suggestions je suis prenneur.
Merci d'avance!![]()
Partager