Serielle Schn. mit ReadFile



  • Hi zusammen,
    ich habe hier kleines Programm, das leider aus mir unerklärlichen Grunden nicht richtig läuft 😕 . Es soll nichts anderes als paar Bytes vom COM1 auslesen die andere Rechner sendet. Es sieht ung. so aus:

    FILE *f1;
    
    char mein[256];
    HANDLE comHandle;
    DCB dcb;
    unsigned long numRead;
    COMMTIMEOUTS ctmoNew = {MAXDWORD,0,0,0,0},ctmoOld;
    char list[1];
    char i = 0;
    	HANDLE hThread[1];
    	DWORD dwThreadID;
    
    DWORD WINAPI ThreadProc(LPVOID lpParameter)
    {
    
    	for(;;)
    	{
    	ReadFile(comHandle,mein,20,&numRead,NULL);
    
    	if(numRead>0)
    		fwrite(mein,sizeof(char),numRead,f1);
    	}
    	return((DWORD)lpParameter);
    }
    
    BOOL CProbe_ReadFileDlg::OnInitDialog()
    {
    
                                .
                                .
    
    	if((f1 = fopen("daten.ike","w"))==NULL)
    		AfxMessageBox("Datei daten.ike konnte nicht geöffnet werden.");
    
    	comHandle = CreateFile("COM1",GENERIC_READ|GENERIC_WRITE,
    		0,0,
    		OPEN_EXISTING,
    		FILE_ATTRIBUTE_NORMAL,
    		NULL);
    
    	if(comHandle==INVALID_HANDLE_VALUE)
    		AfxMessageBox("Unable to use Port");
    
    	GetCommState(comHandle,&dcb);
    	dcb.BaudRate = 38400;
    	dcb.ByteSize = 8;
    	dcb.Parity = NOPARITY;
    	dcb.StopBits = 1;
    	dcb.fOutxCtsFlow = FALSE;
    	dcb.fOutxDsrFlow = FALSE;
    	dcb.fDtrControl = DTR_CONTROL_DISABLE;
    	dcb.fDsrSensitivity = FALSE;
    	dcb.fTXContinueOnXoff = FALSE;
    	dcb.fOutX = FALSE;
    	dcb.fInX = FALSE;
    	dcb.fErrorChar = FALSE;
    	dcb.fNull = FALSE;
    	dcb.fRtsControl = RTS_CONTROL_DISABLE;
    	dcb.fAbortOnError = FALSE;
    
    	SetCommState(comHandle,&dcb);
    
    	GetCommTimeouts(comHandle,&ctmoOld);
    	SetCommTimeouts(comHandle,&ctmoNew);
    
    	hThread[0] = CreateThread(NULL,
    							0,
    							ThreadProc,
    							0,
    							0,
    							&dwThreadID);
    	SetThreadPriority(hThread[0],THREAD_PRIORITY_NORMAL);
    	return TRUE;  // return TRUE  unless you set the focus to a control
    
    }
    void CProbe_ReadFileDlg::OnClose() 
    {
    	// TODO: Add your message handler code here and/or call default
    
    	ResumeThread(hThread[0]);
    	CloseHandle(comHandle);
    	CloseHandle(hThread[0]);
    	_fcloseall();
    	CDialog::OnClose();
    }
    

    Wie man es sieht nichts besonders.
    Da ist ein Thread, der läuft und da sollte über ReadFile COM1 ausgelesen werden. Leider schafft ReadFile nichts auszulesen... 😞



  • Ah,
    komm Jungs, was habe ich übersehen? Damit kennt sich bestimmt jemand aus. 😉



  • Hast du schon mal dran gedacht dass winNT (4.0,2000,XP,2003) keinen direkten hardware zugriff erlaubt ?

    Nur eine Vermutung
    printf("Nicht schlagen!"); // 😉

    MfG,
    Mike



  • Hi MikeTC,
    ich benutze zwar W98, aber die CreateFile,ReadFile,WriteFile sind so weit ich weiss WinAPI Funktionen, also so wie ich es sehe hätte ich auch XP, müssten die funktionieren. Gerade deswegen habe ich vermieden _outp(PORT+1,..) und _inp... zu benutzen. Aber ich stecke irgendwie fest. Ich habe den Eindruck irgendwas mit der Einstellungen bei CreateFile oder COMMTIMEOUTS stimmt nicht. ReadFile liest einfach nichts aus obwohl ich weiss dass die Daten an COM1 angekommen sind. 😕
    Hat jemand noch eine Idee. Komm, diese Forum habe ich immer so geschätzt. Kann nicht sein dass niemand damit schon die Erfahrung gesammelt hat. 😉 Lass euch nicht durch Thread Geschichte einschüchtern. Die ist hier mehr oder weniger unwichtig.



  • Was hier allerdings sehr wichtig wäre sind folgende Punkte:

    a) was sagt dein debugger beim Durchsteppen?
    b) wie wärs wenn du uns mal mit einer Beschreibung beglückst, was nicht funktioniert?

    Ausserdem solltest du die Thread-Main-Schleife irgendwie definiert beenden lassen statt den thread einfach aus dem Speicher zu schmeissen.

    -junix



  • Hi junix,
    a) Debugger sagt nichts besonders .👎 Wenn ich das Programm nach dem ReadFile anhalte dann ist numRead nie >0 was die Bedingung wäre was in meine Datei "daten.ike" zu schreiben. (ich glaube ich werde als nächstes Return Value von ReadFile genauer prüfen müssen)
    b) ich sende über benachbarten PC einige Bytes zu meinem zweitem Rechner. Der soll dass abfangen und in die Datei daten.ike schreiben. In dem OnInitDialog wirs erstmals die Datei geöffnet und mein "comunication resource" der dann als Ergebnis ein comHandle liefert. Danach werden die DCB Einstellungen vorgenommen. Es blieb noch mein Thread zu erzeugen (Create Thread...) usn seine Prioritäten zu setzen. Der Thread tut nichts anders danach als in eine ewige Schleife COM1 zu beobachten und auszulesen.

    Was den Thread selbst betrifft ist er weithin meine Meinung nach nicht von entscheidende Bedeutung.



  • Na also, da haben wir doch was womit wir arbeiten können. Schlägt ReadFile fehl? Wenn ja, was sagt GetLastError?

    Kommen die Bytes an, wenn du einach an beiden Rechnern ein Hypertermianl öffnest? (Hardwarefehler (z.B. Kabel) ausgeschlossen?)

    Was den Thread im allgemeinen Betrifft: Es wird später von alleine esenziell... Stichwörter: Applikationsdesign, definiertes Verhalten, etc...

    -junix



  • das hat vielleicht nichts mit deinem problem zu tun, aber ich habe mir bei WinApi forum sagen lassen dass man immer _beginthread () anstadt CreateThread () benutzen soll.



  • comHandle = CreateFile("com1",GENERIC_READ | GENERIC_WRITE,
                0,
                0,
                OPEN_EXISTING,
                0,
                0); // <------------- fehlt da nicht was bei dir ??
    


  • An junix:
    die Verbindung ist (elektrisch) absolut vorhanden. Alles kontroliert (u.a. Laplink).
    An Matten 2003:
    Ich weiss nicht was du meinst.
    An ich_ich:
    man kann jetzt über dem Thread diskutieren wie lange man will. Aber es liegt nicht an Thread.Ich habe mal auch mit einem Timer polling gemacht hat aber auch nicht geholfen.



  • junix schrieb:

    Schlägt ReadFile fehl? Wenn ja, was sagt GetLastError?

    -junix



  • Hi junix,
    meine for Schleife sieht inzwischen so aus:

    for(;;)
    {
      bResult = ReadFile(comHandle,&mein,1,&numRead,NULL);
      if(bResult==FALSE)
      {
        dwError = GetLastError();
        switch(dwError)
        {
          case ERROR_HANDLE_EOF:AfxMessageBox("ERROR_HANDLE_EOF");break;
          default:AfxMessageBox("andere Fehler");break;
        }
      }
      if(numRead>0)
       fwrite(mein,sizeof(char),numRead,f1);
    }
    

    von Fehlermeldung bis jetzt gar keine Reaktion. 😕
    als wäre alles mehr als super.



  • Schau mal nach dem Return der Funktion 'SetCommState'
    Vermute, dass die fehlschlägt !

    Könnte z.B. an der Baudrate liegen....



  • Volltreffer !👍
    Aber warum?
    Ich war mir dabei so sicher dass ich es überhaupt nicht geprüft habe.Blöd.
    Jetzt muss ich aber sehen was daran falsch ist.



  • Ich habe den Fehler 🤡 .

    dcb.Stopbits = 1;
    😡

    richtig ist

    dcb.Stopbits = ONESTOPBIT;

    und an der Zeile habe ich so viel Zeit verloren. Unglaublich.
    Ich gehe jetzt aber richtig saufen (Kaffee klar was sonst).
    Danke an Junix,ich_ich,Matten2003 und
    an Wanna für entscheidende Tipp 👍
    Von mir aus könnte man es auch in FAQ schieben. So weit ich weiss ist da nichts über CreateFile,ReadFile,WriteFile in zusammenhang mit COM's vorhanden.


Anmelden zum Antworten