wxDev.fr, le portail francophone consacré à wxWidgets ! ( The french portal for wxWidgets )  
Esp. membre
Recheche rapide



Recherche avancée
Statistiques
Membres inscrits :2359

Membres en ligne : 0
Invités en ligne : 5

Valid XHTML 1.0 Transitional

Valid CSS2

Menu forum (navigation):
Pages: 1  
 
Accueil » Accueil forums » Développement C/C++
» wxFile::Read bloquante tant que rien à lire ?
Conversation : wxFile::Read bloquante tant que rien à lire ?
09-03-2012 19:29:20  wxFile::Read bloquante tant que rien à lire ? #1
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
10-03-2012 10:27:14  Re: wxFile::Read bloquante tant que rien à lire ? #2
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....
10-03-2012 22:31:10  Re: wxFile::Read bloquante tant que rien à lire ? #3
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....
11-03-2012 23:52:53  Re: wxFile::Read bloquante tant que rien à lire ? #4
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)

Menu forum (navigation):
Pages: 1  
 
Accueil » Accueil forums » Développement C/C++
» wxFile::Read bloquante tant que rien à lire ?