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


von Andreas Martin (Gast)


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

von *.* (Gast)


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 ;)

von Andreas Martin (Gast)


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

von Holger (Gast)


Lesenswert?

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

von Andreas Martin (Gast)


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

von Holger (Gast)


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.

von Holger (Gast)


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.

von Andreas Martin (Gast)


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:
1
#define WIN32_LEAN_AND_MEAN
2
#include <windows.h>
3
#include <stdio.h>
4
5
HANDLE hCom = INVALID_HANDLE_VALUE;
6
DCB dcb = {sizeof(DCB)};
7
DCB dcb_check;
8
COMMTIMEOUTS to = {0}; // Disable all timeouts
9
COMMTIMEOUTS to_check;
10
DWORD dwEaten;
11
FILE *stream;
12
13
#define PRINTF_DCB_MEMBER(member) fprintf(stream, "%20s: %d\n", #member, dcb.member)
14
#define COM_PORT "COM1"
15
#define USE_LOG_FILE 1
16
17
const char strTest[] = "Testing COM port...";
18
char inBuf[MAX_PATH];
19
20
void check_err(int ok)
21
{
22
  if(!ok)
23
  {
24
    fprintf(stream, "Error!\n\n\n");
25
    if(hCom != INVALID_HANDLE_VALUE) CloseHandle(hCom);
26
    if(stream != stdout) fclose(stream);
27
    abort();
28
  }
29
  else
30
  {
31
    fprintf(stream, "ok\n");
32
  }
33
}
34
35
int main(int argc, char *args[])
36
{
37
  stream = stdout;
38
39
#if(USE_LOG_FILE)
40
  stream = fopen("E:\\xp_com_test\\log.txt","w");
41
  if(!stream)
42
  {
43
    printf("Could not create log file!\n");
44
    abort();
45
  }
46
#endif
47
48
  fprintf(stream, "Opening COM Port "COM_PORT":...");
49
  hCom = CreateFile( COM_PORT,
50
                     GENERIC_READ | GENERIC_WRITE, 0,
51
                     0, OPEN_EXISTING,
52
                     0, NULL);
53
54
  check_err(hCom != INVALID_HANDLE_VALUE);
55
56
  fprintf(stream, "GetCommState()...");
57
  check_err(GetCommState(hCom, &dcb));
58
59
  dcb.BaudRate = 9600;
60
  dcb.ByteSize = 8;
61
  dcb.StopBits = ONESTOPBIT;
62
  dcb.Parity = NOPARITY;
63
  dcb.fParity = (dcb.Parity != NOPARITY);
64
65
  // No flow control by default
66
  dcb.fOutxCtsFlow=0;
67
  dcb.fOutxDsrFlow=0;
68
  dcb.fDsrSensitivity=0;
69
70
  dcb.fRtsControl=RTS_CONTROL_DISABLE;
71
  dcb.fDtrControl=DTR_CONTROL_DISABLE;
72
73
  dcb.fOutX=0;
74
  dcb.fInX=0;
75
76
  fprintf(stream, "SetCommState()...");
77
  check_err(SetCommState(hCom, &dcb));
78
79
  fprintf(stream, "GetCommState() for verifying...");
80
  check_err(GetCommState(hCom, &dcb_check));
81
82
  fprintf(stream, "Verify DCB parameters...");
83
  check_err(!memcmp(&dcb, &dcb_check, sizeof(DCB)));
84
85
  fprintf(stream, "\nDCB members:\n");
86
  PRINTF_DCB_MEMBER(BaudRate);
87
  PRINTF_DCB_MEMBER(fBinary);
88
  PRINTF_DCB_MEMBER(fParity);
89
  PRINTF_DCB_MEMBER(fOutxCtsFlow);
90
  PRINTF_DCB_MEMBER(fOutxDsrFlow);
91
  PRINTF_DCB_MEMBER(fDtrControl);
92
  PRINTF_DCB_MEMBER(fDsrSensitivity);
93
  PRINTF_DCB_MEMBER(fTXContinueOnXoff);
94
  PRINTF_DCB_MEMBER(fOutX);
95
  PRINTF_DCB_MEMBER(fInX);
96
  PRINTF_DCB_MEMBER(fErrorChar);
97
  PRINTF_DCB_MEMBER(fNull);
98
  PRINTF_DCB_MEMBER(fRtsControl);
99
  PRINTF_DCB_MEMBER(fAbortOnError);
100
  PRINTF_DCB_MEMBER(XonLim);
101
  PRINTF_DCB_MEMBER(XoffLim);
102
  PRINTF_DCB_MEMBER(ByteSize);
103
  PRINTF_DCB_MEMBER(Parity);
104
  PRINTF_DCB_MEMBER(StopBits);
105
  PRINTF_DCB_MEMBER(XonChar);
106
  PRINTF_DCB_MEMBER(XoffChar);
107
  PRINTF_DCB_MEMBER(ErrorChar);
108
  PRINTF_DCB_MEMBER(EofChar);
109
  PRINTF_DCB_MEMBER(EvtChar);
110
  fprintf(stream, "\n");
111
112
  fprintf(stream, "Set timeouts...");
113
  to.ReadTotalTimeoutConstant = 500; // Waits 0,5 sec before timout occures
114
  check_err(SetCommTimeouts(hCom, &to));
115
116
  fprintf(stream, "GetCommTimeouts() for verifying...");
117
  check_err(GetCommTimeouts(hCom, &to_check));
118
119
  fprintf(stream, "Verify timeout paramters...");
120
  check_err(!memcmp(&to, &to_check, sizeof(COMMTIMEOUTS)));
121
122
  fprintf(stream, "Write test string...");
123
  check_err(WriteFile(hCom, strTest, strlen(strTest), &dwEaten, (LPOVERLAPPED)NULL));
124
125
  fprintf(stream, "All characters written? ...");
126
  check_err(dwEaten == strlen(strTest));
127
128
  fprintf(stream, "Reading COM port...");
129
  check_err(ReadFile(hCom, inBuf, sizeof inBuf, &dwEaten, (LPOVERLAPPED)NULL) && dwEaten>0);
130
131
  fprintf(stream, "Read from COM port: \"%*s\"", dwEaten, inBuf);
132
133
  fprintf(stream, "\n\nDone!\n\n");
134
135
136
  CloseHandle(hCom);
137
  if(stream != stdout) fclose(stream);
138
  return 0;
139
}

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

von Arc N. (arc)


Lesenswert?

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

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

von Andreas Martin (Gast)


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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.