www.mikrocontroller.net

Forum: PC-Programmierung RS232: Geöffneter Port weder beschreib- noch lesbar (P5B)


Autor: Andreas Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi all,

vielleicht gibt es ja hier einen Crack, der mir helfen kann:
Ein ausgereiftes Programm (seit 2 Jahren erfolgreich im Einsatz) 
funktioniert plötzlich auf meinem (nur diesen!) PC nicht mehr.
Phänomen: Der Port kann geöffnet werden, das Handle ist gültig aber dann 
kann der Port weder gelesen, noch beschrieben werden (GetLastError()== 
29 bzw. 30)...
Wenn ich jetzt irgendein anderes Programm, das auf die RS232 zugreift 
starte (Hyperterminal, OCConsole, HotSync) und wieder beende 
funktioniert mein Programm auch wieder, bis zum nächsten Kaltstart.
Ich habe ein anderes Tool geschrieben, das verfügbare COM-Ports 
auflistet. In diesem wird die WMI bemüht (IWbemLocator). Auch danach 
funktioniert der Port auch wieder wie erwartet.
An fehlenden Administratorrechten liegt es übrigens auch nicht, das habe 
ich schon getestet.
Ich befürchte, das ist ein BIOS od. Treiberproblem, daher noch kurz das 
Board benannt:
ASUS P5B mit Windows XP.

Google hat dazu nicht viel ausgespuckt, einen Leidensgenossen habe ich 
gefunden:
http://www.cygwin.com/ml/cygwin/2006-01/msg01092.html
Bei ihm lag's jedoch an Cygwin, das ich bei mir nicht installiert 
habe...

Kann sich da jemand einen Reim drauf machen?

Danke und Gruß,
Andreas Martin

Autor: *.* (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hilft es, die COM-Ports im Gerätemanager zu löschen? (und dann Neustart)

Das BIOS hat da ausser Port ein/ausschalten eigentlich nicht viel zu 
sagen.
Wenn Windows mit sowas anfängt hilft evtl. Neuinstallation ;)

Autor: Andreas Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Neuinstallation ist gut. Der Rechner ist nagelneu...
Proprietäre Software hat ja kein Problem mit der RS232. Das ist ja 
gerade das was mich ärgert: An was haben DIE gedacht, was ICH nicht 
beachtet habe..?
Auf meinem alten Rechner lief alles keimfrei, deshalb hole ich den jetzt 
aber nicht wieder raus :)

Gruß,
Andreas Martin

Autor: Holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
CTS  aktiv ??? .
Versuche mal mit dienem Code die Handschakeleitung zu bewegen.
SetCom-Break ect. Mit LED-Status ansehen.

Autor: Andreas Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Holger,

ja, das Programm funktioniert einwandfrei. Da bin ich mir 100% sicher (2 
Jahre Einsatz/Entwicklung). Ein Thread arbeitet im Hintergrund und 
erkennt das angeschlossene Gerät. Mit den Handshakeleitungen wird die 
Stromversorgung für das Gerät geschaltet. Das funktioniert auch. 
Lediglich Daten Senden/Empfangen scheitert. Ich muss nach jedem 
Kaltstart einmalig Hyperterminal o.ä. auf COM1 schalten und dann ist der 
Port "reanimiert".
An den Defaulteinstellungen für den Port liegt es auch nicht: Nachdem 
das Programm wieder läuft hatte ich die Einstellungen mal verstellt 
(alles). Danach funktionierte es trotzdem.

Ich werd' wohl einen neuen Port kaufen müssen...


Danke und Gruß,
Andreas

Autor: Holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mir ist da noch was eingefallen.
Schau mal in der Systemsteuerung die COM Ports an.
Handschake Baudrate ect.

Das Hotsync als Task installiert für PDA_s ist ein ganz gefährliches 
Teil.
( Dienst Kanalarbeiter Prozess )
Das Pollt und Triggert die Handschakeleitungen rum.
Tip:
Mach dir mal ein extra USB-COM Port da dran,und versuche das zu öffnen.,
und im Loop-Back zu schreiben.Pin.2<---->Pin.3-

Schau dir mal mit den Status-Leds den Com-Port beim
hochbooten an, ob da die Handschake-Pins sich toggeln.
( Das Handshake Toggen kan man mit dem Reg-Editor sogar unterbinden.  )

Lösche mal brutal die Com-Ports aus dem System,


Bau dir mal ein kleines Terminal-Prog mit dienem Compiler auf dem 
System.
Open Close ect.
Wenn der DCB nicht genullt ist, und die DCB-Struktur nicht richtig,
oder der Transmit-Receiver-Buffer = Null ect..
Poste mal dein Test Code für das Mini-Terminal hier rein. )


(  Was habe ich vergessen ??? was andere da noch machen )
Was ist das für ein Compiler ???

Ich hatte mal mit XP-Laptop USB-COM so was ähnliches.
Habe den Treiber entfernt u. explizit neu aufgezogen....
Gruss Holger.

Autor: Holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mir ist da noch was eingefallen.
Die neuen COM-Chips haben sogar sleep Funktioen,
Fifo-Buffers und Timeouts.
Auf welchem Betriebssystem hast du das Prog. vorher
entwickelt. Hast du eine echte HW-COM oder USB-COM
Kanst du das Kompilat auf einer anderen XP-Platform testen ???.
Kanst du ein TestCom-Prog mit z.B MS-VC 6.x machen.

Mit dem Tool womit du die freien Com-Ports ermittelst
geht das eigentliche  Prog. danach.  ????
( Damit wird der Driver ja auch verkettet u. ermittelt ect. Properies 
...
Ist dein Handle global ????
und auch im DCB eingetragen.

Worauf hin wird Thread Prozess gestartet.
bzw auf welches Ereignisses Synchronisiert ect.
( Interprozesskommunikation )
Das XP-System ist nach dem Kaltstart hochgebootet.
Deine Com-Exe wird gestartet.
Daraufhin wird der Com-Treiber VXD ,Com-.Dll in den Cache Dll-Cache 
geholt.
Der Thread wird ..... auf erfolgreiches Open gestartet oder 
..sync-timing ....
Ich denke da an das Timing was da abgeht. Nachrichtenschleife ect...
Der Com-Empfangsbuffer-Treiber wird durch das XP-System alloziert ect.

Versuche mal eine Aplikation mit deinem Compiler-Tool zu schreiben,
die ohne den "Thread" für den (Handshake ect.pp ) auskommt, und einfach 
nur sendet.
Du must das Problem auf diesem System frakturiesieren.
( Ich habe damals unter NT-4 Prozessverhalten erlebt die bei WIN98 ganz
anders abliefen Nachrichtenschleife ect. Oder auch speziell nur unter NT 
so
realieserbar waren  )
Schade das du nich noch mal das gleiche XP-System u.HW hast.
Ich habe immer grosse Interesse an solchen Effekten.
Ich hatte mal mit XP-Laptop und USB-COM so was ähnliches.
Das Prog. lief auf dem Teil schon immer gut.
Bis ich es eines Tages neu angestöpselt hatte, u die Com auch noch
explizit auf die Nummer gesetzt hatte, weil beim USB die Com immer
mit einem neuen Nummer vergeben wird, wenn man nicht den gleichen
USB-Buchsenklinke nimmt, die man vorher hatte.
( USB-Bus ist Platz-Portorientiert )
Das war ein simples Terminal-Prog mit poll Thread für die Zeichen.
Geschreiben in MS-VC 6.0
Trotz Loop-Back von 2 auf 3 Pin, ging nix rein was auf dem Keyboard 
getippt wurde .
( Bis ich daraufhin den Treiber neu aufgedröselt hatte )
( Also HW-Treiber und Prozessoren u. Compiler-Tools u. die 
entsprechenden
Platformen-Betriebssysteme sind immer für Überraschungen gut.)
Bei den neuen Doppel-KernProzessoren kan auch noch  der Zonk drin sein.
FTDI  232 ect. hat sogar extra Treiber für AMD 
Prozessoren..Derivate.....
Mach mal einen File-Compare von den beiden Compilaten,
alt u. neu System.
Das muss man halt einkreisen.
Hier im Formum habe ich auch schon so etwas in der Richtung
vor ca. 6 Monaten gelesen.

Berichte mal wie du da vorgehst.

Gruss Holger.

Autor: Andreas Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Holger,

erstmal vielen Dank für Deine Unterstützung!
Ich habe ein kleines Testprogramm geschrieben und hiermit stellt sich 
für mich wieder alles auf den Kopf:
Danach funktioniert auch mein "Problem-Programm"...
Das kann doch alles nicht wahr sein! In dem anderen Programm nutze ich 
die SAPI (sourceforge.net) und hat auf mehreren Rechnern (mind. 6) nie 
Probleme gemacht...
Wenn ich doch noch was Interessantes herausfinden sollte poste ich es.
Aber möglichweise kann jemand anderes ja den Code für eigene Zwecke 
gebrauchen:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>

HANDLE hCom = INVALID_HANDLE_VALUE;
DCB dcb = {sizeof(DCB)};
DCB dcb_check;
COMMTIMEOUTS to = {0}; // Disable all timeouts
COMMTIMEOUTS to_check;
DWORD dwEaten;
FILE *stream;

#define PRINTF_DCB_MEMBER(member) fprintf(stream, "%20s: %d\n", #member, dcb.member)
#define COM_PORT "COM1"
#define USE_LOG_FILE 1

const char strTest[] = "Testing COM port...";
char inBuf[MAX_PATH];

void check_err(int ok)
{
  if(!ok)
  {
    fprintf(stream, "Error!\n\n\n");
    if(hCom != INVALID_HANDLE_VALUE) CloseHandle(hCom);
    if(stream != stdout) fclose(stream);
    abort();
  }
  else
  {
    fprintf(stream, "ok\n");
  }
}

int main(int argc, char *args[])
{
  stream = stdout;

#if(USE_LOG_FILE)
  stream = fopen("E:\\xp_com_test\\log.txt","w");
  if(!stream)
  {
    printf("Could not create log file!\n");
    abort();
  }
#endif

  fprintf(stream, "Opening COM Port "COM_PORT":...");
  hCom = CreateFile( COM_PORT,
                     GENERIC_READ | GENERIC_WRITE, 0,
                     0, OPEN_EXISTING,
                     0, NULL);

  check_err(hCom != INVALID_HANDLE_VALUE);

  fprintf(stream, "GetCommState()...");
  check_err(GetCommState(hCom, &dcb));

  dcb.BaudRate = 9600;
  dcb.ByteSize = 8;
  dcb.StopBits = ONESTOPBIT;
  dcb.Parity = NOPARITY;
  dcb.fParity = (dcb.Parity != NOPARITY);

  // No flow control by default
  dcb.fOutxCtsFlow=0;
  dcb.fOutxDsrFlow=0;
  dcb.fDsrSensitivity=0;

  dcb.fRtsControl=RTS_CONTROL_DISABLE;
  dcb.fDtrControl=DTR_CONTROL_DISABLE;

  dcb.fOutX=0;
  dcb.fInX=0;

  fprintf(stream, "SetCommState()...");
  check_err(SetCommState(hCom, &dcb));

  fprintf(stream, "GetCommState() for verifying...");
  check_err(GetCommState(hCom, &dcb_check));

  fprintf(stream, "Verify DCB parameters...");
  check_err(!memcmp(&dcb, &dcb_check, sizeof(DCB)));

  fprintf(stream, "\nDCB members:\n");
  PRINTF_DCB_MEMBER(BaudRate);
  PRINTF_DCB_MEMBER(fBinary);
  PRINTF_DCB_MEMBER(fParity);
  PRINTF_DCB_MEMBER(fOutxCtsFlow);
  PRINTF_DCB_MEMBER(fOutxDsrFlow);
  PRINTF_DCB_MEMBER(fDtrControl);
  PRINTF_DCB_MEMBER(fDsrSensitivity);
  PRINTF_DCB_MEMBER(fTXContinueOnXoff);
  PRINTF_DCB_MEMBER(fOutX);
  PRINTF_DCB_MEMBER(fInX);
  PRINTF_DCB_MEMBER(fErrorChar);
  PRINTF_DCB_MEMBER(fNull);
  PRINTF_DCB_MEMBER(fRtsControl);
  PRINTF_DCB_MEMBER(fAbortOnError);
  PRINTF_DCB_MEMBER(XonLim);
  PRINTF_DCB_MEMBER(XoffLim);
  PRINTF_DCB_MEMBER(ByteSize);
  PRINTF_DCB_MEMBER(Parity);
  PRINTF_DCB_MEMBER(StopBits);
  PRINTF_DCB_MEMBER(XonChar);
  PRINTF_DCB_MEMBER(XoffChar);
  PRINTF_DCB_MEMBER(ErrorChar);
  PRINTF_DCB_MEMBER(EofChar);
  PRINTF_DCB_MEMBER(EvtChar);
  fprintf(stream, "\n");

  fprintf(stream, "Set timeouts...");
  to.ReadTotalTimeoutConstant = 500; // Waits 0,5 sec before timout occures
  check_err(SetCommTimeouts(hCom, &to));

  fprintf(stream, "GetCommTimeouts() for verifying...");
  check_err(GetCommTimeouts(hCom, &to_check));

  fprintf(stream, "Verify timeout paramters...");
  check_err(!memcmp(&to, &to_check, sizeof(COMMTIMEOUTS)));

  fprintf(stream, "Write test string...");
  check_err(WriteFile(hCom, strTest, strlen(strTest), &dwEaten, (LPOVERLAPPED)NULL));

  fprintf(stream, "All characters written? ...");
  check_err(dwEaten == strlen(strTest));

  fprintf(stream, "Reading COM port...");
  check_err(ReadFile(hCom, inBuf, sizeof inBuf, &dwEaten, (LPOVERLAPPED)NULL) && dwEaten>0);

  fprintf(stream, "Read from COM port: \"%*s\"", dwEaten, inBuf);

  fprintf(stream, "\n\nDone!\n\n");


  CloseHandle(hCom);
  if(stream != stdout) fclose(stream);
  return 0;
}

Das Ganze spuckt dann folgendes aus:

Opening COM Port COM1:...ok
GetCommState()...ok
SetCommState()...ok
GetCommState() for verifying...ok
Verify DCB parameters...ok

DCB members:
            BaudRate: 9600
             fBinary: 1
             fParity: 0
        fOutxCtsFlow: 0
        fOutxDsrFlow: 0
         fDtrControl: 0
     fDsrSensitivity: 0
   fTXContinueOnXoff: 0
               fOutX: 0
                fInX: 0
          fErrorChar: 0
               fNull: 0
         fRtsControl: 0
       fAbortOnError: 0
              XonLim: 2048
             XoffLim: 512
            ByteSize: 8
              Parity: 0
            StopBits: 0
             XonChar: 17
            XoffChar: 19
           ErrorChar: 0
             EofChar: 0
             EvtChar: 0

Set timeouts...ok
GetCommTimeouts() for verifying...ok
Verify timeout paramters...ok
Write test string...ok
All characters written? ...ok
Reading COM port...ok
Read from COM port: "Testing COM port..."

Done!





Gruß,
Andreas

Autor: Arc Net (arc)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die andere Variante zum Erzeugen des DCB ausprobiert?
Wenn auch das keinen Anhaltspunkt bringt, würde ich auch auf den Treiber 
tippen.
if (!GetCommState(handle, &dcb)) { ... }
if (!BuildCommDCB("baud=9600 parity=N data=8 stop=1", &dcb)) { ... }
dcb.XonLim = dcb.XoffLim = dcb.fOutX = dcb.fInX = 0;
SetCommState(handle, &dcb);

p.s. u.U. nochmal mit anderen Timeouts und anderen Buffergrößen 
(SetupComm) probieren.

Autor: Andreas Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe den (meinen) Fehler gefunden:
Nur(!) auf meinem neuen Rechner ist das Flag fDsrSensitivity per default 
auf 1 gesetzt. Daher konnten keine Zeichen gelesen werden.
Ich habe den DCB immer mit GetCommState() ausgefüllt, daher blieb das 
Flag gesetzt.
(So'n Mist)

Danke trotzdem Holger, Arc Net und *.*

Gruß,
Andreas

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.