Membres inscrits :2359
Membres en ligne : 0
Invités en ligne : 2


|
Conversation : wxFile::Read bloquante tant que rien à lire ? |
Serge Delarbre (Nouveau membre)
Inscrit le : 18-02-2012
Messages: 2
Snippets: 0
Tutoriels: 0
Hors ligne |
Bonjour,
J’écris un minuscule terminal pour tester la communication entre une carte à µcontrôleur que j'ai développée et mon PC, et j'ai un problème avec la fonction Read :
J'utilise un wxFile pour contrôler un port série, le nom du fichier est donc du type "comx".
Les fonctions ci-dessous fonctionnent, sauf la fonction wxFile::Read qui attend indéfiniment un caractère jusqu'à ce qu'il y en ai un de dispo (j'ai réduis la réception à 1 caractère pour essayer de comprendre ;o).
Code wxWidgets: wxFile ntds; //stream serial comport wxString WinCom; //content of terminal's window char buff[256]; //rx buffer // open com selected void mmmDialog::OnOpenComClick(wxCommandEvent& event) { wxString str; if(ntds.Open(GTCom.Name, wxFile::read_write)) //GTCom.Name contient com1 par exemple { str= wxT("Open ok : "); if(ntds.Access(GTCom.Name, wxFile::read)) str+= wxT("R"); if(ntds.Access(GTCom.Name, wxFile::write)) str+= wxT("W"); } else str= wxT("Open error"); Info->SetValue(str); } // send commande void mmmDialog::OnSendClick(wxCommandEvent& event) { wxString str; if(ntds.IsOpened()) { WinCom= Sender->GetValue() + wxT("\r"); if(ntds.Write(WinCom)) { Receiver->SetValue(WinCom); str= wxT("Write ok"); } else { str= wxT("Write error"); } } else { str= wxT("Can't write : not open"); } Info->SetValue(str); } // read answer void mmmDialog::OnReadComClick(wxCommandEvent& event) { wxString str; if(ntds.IsOpened()) { if(ntds.Read(buff, 1) == 1) //attend indéfiniment jusqu'à réception d'un caractère { str= wxT("Read ok"); buff[1]= 0; WinCom= WinCom.FromAscii(buff); Receiver->SetValue(WinCom); } else { str= wxT("Read error"); } } else { str= wxT("Can't read : not open"); } Info->SetValue(str); } // close port com void mmmDialog::OnCloseComClick(wxCommandEvent& event) { wxString str; if(ntds.IsOpened()) { ntds.Close(); str= wxT("Close ") + GTCom.Name; } else str= wxT("Can't close : not open"); Info->SetValue(str); }
D’après l'extrait de doc ci_dessous, cette fonction devrait retourner le nombre de caractères effectivement lus ou un code d'erreur...
Code: wxFile::Read size_t Read(void* buffer, size_t count) Reads the specified number of bytes into a buffer, returning the actual number read. Parameters buffer A buffer to receive the data. count The number of bytes to read. Return value The number of bytes read, or the symbol wxInvalidOffset (-1) if there was an error.
Pourriez-vous me dire ou est-ce que je merdoie ?
Merci par avance
Serge
|
|
Xaviou (Administrateur)
Lieu: Annecy (74)
Inscrit le : 27-08-2007
Messages: 1390
Snippets: 25
Tutoriels: 6
Site web
Hors ligne |
Salut.
Je viens de faire un test similaire, et effectivement, ça bloque à la lecture (j'ai même essayé de modifier les paramètres de contrôle de flux du port, mais ça ne change rien).
Ça vient sans doute du fait qu'un port com ne se comporte pas tout à fait comme un fichier normal.
J'ai également fait le même test avec les fonctions de l'API Windows (CreateFile, ReadFile, CloseHandle), et le comportement est le même.
Est-ce que tu as essayé wxCtb qui est un composant spécialement prévu pour la communication avec les ports série ?
Tiens moi au courant, ça m'intéresse. @+ Xav'
|
Le nouveau portail wxWidgets francophone : www.wxdev.fr Ben en fait, vous y êtes déjà ... et effectivement, depuis le temps, ce n'est plus tellement nouveau....
|
Xaviou (Administrateur)
Lieu: Annecy (74)
Inscrit le : 27-08-2007
Messages: 1390
Snippets: 25
Tutoriels: 6
Site web
Hors ligne |
J'ai fait de nouveaux tests sous Windows en passant directement par l'API, et cette fois-ci, ça a marché. Le problème vient tout simplement du timeout par défaut du port qui doit être trop élevé.
Voici le code utilisé, si tu veux tester (C'est un mélange wxWidgets pour la GUI et API Windows pour le test du port; m_txtLog est un wxTextCtrl multilignes)
Code wxWidgets: char szBuff[1024]; m_txtLog->AppendText(_T("Opening : ")); HANDLE hCom=CreateFile(L"\\\\?\\COM1", GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL); if (hCom!=INVALID_HANDLE_VALUE) { m_txtLog->AppendText(_T("Ok\n")); } else { m_txtLog->AppendText(_T("Error !\n")); return; } m_txtLog->AppendText(_T("Getting actual timeouts : ")); _COMMTIMEOUTS ct; if (GetCommTimeouts(hCom, &ct)) { m_txtLog->AppendText(_T("Ok !")); *m_txtLog << _T("\n ReadIntervalTimeout\t= ") << (int)ct.ReadIntervalTimeout; *m_txtLog << _T("\n ReadTotalTimeoutMultiplier\t= ") << (int)ct.ReadTotalTimeoutMultiplier; *m_txtLog << _T("\n ReadTotalTimeoutConstant\t= ") << (int)ct.ReadTotalTimeoutConstant; *m_txtLog << _T("\n WriteTotalTimeoutMultiplier\t= ") << (int)ct.WriteTotalTimeoutMultiplier; *m_txtLog << _T("\n WriteTotalTimeoutConstant\t= ") << (int)ct.WriteTotalTimeoutConstant; *m_txtLog << _T("\n"); } else { m_txtLog->AppendText(_T("Error !\n")); } DWORD dwMs=1000; *m_txtLog << _T("Setting timeout to ") << (int)dwMs << _T(" milliseconds : "); ct.ReadIntervalTimeout = 0; ct.ReadTotalTimeoutMultiplier = 0; ct.ReadTotalTimeoutConstant = dwMs; ct.WriteTotalTimeoutMultiplier = 0; ct.WriteTotalTimeoutConstant = dwMs; if( SetCommTimeouts(hCom, &ct) ) { m_txtLog->AppendText(_T("Ok\n")); } else { m_txtLog->AppendText(_T("Error !\n")); CloseHandle(hCom); return; } m_txtLog->AppendText(_T("Reading : ")); DWORD dwRead=0; if (ReadFile(hCom, szBuff, 20, &dwRead, NULL)) { m_txtLog->AppendText(wxString(_T("Ok (")) << dwRead << _T(" bytes read)\n")); } else { m_txtLog->AppendText(_T("Error !\n")); } CloseHandle(hCom);
En espérant que ça pourra t'aider. @+ Xav'
|
Le nouveau portail wxWidgets francophone : www.wxdev.fr Ben en fait, vous y êtes déjà ... et effectivement, depuis le temps, ce n'est plus tellement nouveau....
|
Serge Delarbre (Nouveau membre)
Inscrit le : 18-02-2012
Messages: 2
Snippets: 0
Tutoriels: 0
Hors ligne |
Bonsoir,
Un grand merci Xaviou, effectivement ça fonctionne aussi chez moi avec cette façon de faire (Seven, Code::Blocks 10.05, minGW32, wxWidgets 2.8.12).
Après avoir remis tout ça au propre (.cpp et .h séparés et non spécifiques à mon design), je vais pouvoir poursuivre mon dev.
Si, après tests poussés, cette gestion très simplifiée de port série s'avère stable et intéressante, je la mettrais à disposition sur ce site.
J'avais trouvé wxCTB, mais la doc n'est pas très fournie et la solution me semblait trop complète et donc complexe pour mon micro terminal ;o)
Merci encore @+
Serge
Dernière modification par Serge Delarbre (11-03-2012 23:53:21)
|
|
|