CreateFile schlägt fehl - serielle schnittstelle (kein zugriff)
-
Hallo,
ich versuche grade mal auf die serielle Schnittstelle zugriff zu nehmen. Ich habe von winapi.net aus dem Tutorial den Code genommen, aber es funktioniert leider nicht. Hier der Code (CreateFile schlägt mit Fehlercode 5 fehl (ERROR_ACCESS_DENIED).
bool init (int nPort, int nBaud, int nBits, int nStopp, int nParity) { char szPort[15]; /* if (INVALID_HANDLE_VALUE != hComm) return (TRUE); */ // Aus einer "1" in nPort schreiben wir so "COM1" in szPort z.B.. wsprintf (szPort, "\\\\.\\COM%d", nPort); hComm = CreateFile (szPort, // COM-Port ffnen GENERIC_READ|GENERIC_WRITE, // wir wollen lesen und schreiben 0, 0, OPEN_EXISTING, 0, NULL); // nicht OVERLAPPED, wir holen uns den Port exclusiv if (hComm == INVALID_HANDLE_VALUE) // hat es geklappt? Bei Fehler ist hier Schluss! { int lasterror = -1; char error [200 +1]; lasterror = GetLastError (); (void)sprintf (error, "Fehler beim ffnen des COM-Ports (%d)", lasterror); MessageBox (NULL, error, "CreateFile", NULL); //return false; } // Alte Timeouts merken. Bei Fehler ist hier Schluss! if (!GetCommTimeouts(hComm, &timeouts_alt)) { //Close (); MessageBox (NULL, "Fehler beim ffnen des COM-Ports!\nGetCommTimeouts()", NULL, NULL); return false; } // Eine Struktur vom Typ COMMTIMEOUTS erzeugen und neue Timeouts setzen COMMTIMEOUTS timeouts; timeouts.ReadIntervalTimeout = 200; timeouts.ReadTotalTimeoutMultiplier = 200; timeouts.ReadTotalTimeoutConstant = 200; timeouts.WriteTotalTimeoutMultiplier = 200; timeouts.WriteTotalTimeoutConstant = 200; // Neue Timeouts setzen. Bei Fehler ist hier Schluss! if (!SetCommTimeouts(hComm, &timeouts)) { //Close (); MessageBox (NULL, "Fehler beim ffnen des COM-Ports!\nSetCommTimeouts()", NULL, NULL); return false; } DCB dcb; memset (&dcb, 0, sizeof(dcb)); // Die bestehenden Parameter holen. Bei Fehler ist hier Schluss! if (!GetCommState (hComm, &dcb)) { //Close (); MessageBox (NULL, "Fehler beim ffnen des COM-Ports!\nGetCommState()", NULL, NULL); return false; }edit: cpp-Tags korrigiert.
-
fluxy schrieb:
(CreateFile schlägt mit Fehlercode 5 fehl (ERROR_ACCESS_DENIED).
Dieser Fehler tritt u.a. dann auf, wenn schon ein anderes Programm den COM-Port benutzt.
-
aha was mache ich denn wenn ich die daten von einem programm lesen will, welches auf den port von der gegenseite schreibt?
-
Wie ist das eigentlich mit WindowsXP und 2000? Ich habe gehört da soll der Zugriff geblockt werden oder so. Im C Standard gab es doch früher auch Funktionen für die Schnittstellen ich glaube die heisse _inp und _outp, die nur assamblercode ausführen....
-
fluxy schrieb:
Im C Standard gab es doch früher auch Funktionen für die Schnittstellen ich glaube die heisse _inp und _outp, die nur assamblercode ausführen....
Ich kenne den C-Standard nicht auswendig, aber die Unterstriche vor den Funktionsnamen sprechen stark dafür, dass es keine Standardfunktionen waren. Außerdem ist Standard-C plattformunabhängig, daher können _inp und _outp IMHO nicht im Standard gestanden haben.
aha was mache ich denn wenn ich die daten von einem programm lesen will, welches auf den port von der gegenseite schreibt?
Ein Port ist eine begrenzte Resource, die nur ein Programm gleichzeitig in Anspruch nehmen kann.
Willst du die Daten mitschneiden, die über das Kabel gehen? Das kann z.B. Portmon.
-
nein ich will mich ein wenig mit Mikrocontroler arbeiten. Jemand den ich kenne macht nur eine Platine fertig, mit welcher man z.B. externe Schaltungen über einen Computer steuern kann. Das ganze verfügt über 8 analoge Ein-/Ausgänge und über eine serielle und eine parallele Schnittstelle, über die Daten zum PC gesendet werden können.
ich wollte einfach mal eine Verbindung aufbauen und die Daten von der seriellen Schnittstelle lesen, aber wie es scheint ist das gar nicht so einfach.
Ich habe also eigentlich 2 Programme. Einmal das Programm, welches den Mikrocontroler steuert (wird übertragen) und einmal mein Programm, welches von der Schnittstelle liest.
Gruß Sebastian
-
"Access denied" kommt, wenn schon ein anderes Programm den Port hat (siehe posting von @cd9000).
Außerdem fehlt in Deinem Prog noch die Baudrateneinstellung. Die Timeouts liegen auch völlig daneben, lies mal in der MSDN die Beschreibung.So klappts:
// DOS32-Programm zum Senden/Empfangen von Bytes über COM (9600-8N1) // Alle empfangenen Bytes werden zurückgesendet. // OS: W95, W98, W98SE, WinME, WinNT, Win2000, WinXP // Note: Keine Fehlerbehandlung implementiert! #include <windows.h> #include <stdio.h> #define COM_BUFFER_SIZE 256 // Read- und Write-Buffer-Size #define BD_RATE CBR_9600 // 9600 Baud #define HELP_STRING TEXT("Aufruf mit: progname <COM-Port-Nummer>\r\n") // Hauptprogramm: Aufruf mit: progname <COM-Port-Nummer> int main (int argc, char **argv) { DCB dcb; DWORD iBytesWritten; BOOL bRet = true; DWORD dwRead = 0; DWORD dwSetMask = EV_RXCHAR | EV_ERR; DWORD dwEvtMask; OVERLAPPED o; COMMTIMEOUTS ct; unsigned char InString[COM_BUFFER_SIZE + 1]; TCHAR szCOM[6]; if (argc == 2 && // progname + COM-Port-Nummer ? atoi (argv[1]) > 0 && atoi (argv[1]) < 5) // COM1 ... COM4? wsprintf (szCOM, TEXT("COM%s"), argv[1]); // String "basteln" ... else { printf (TEXT("\r\nERROR:\t %s"), HELP_STRING); return (1); // und tschüß ... } memset (&o, 0, sizeof (OVERLAPPED)); // Struktur mit 0en füllen o.hEvent = CreateEvent (NULL, FALSE, FALSE, NULL); // einen Event setzten HANDLE hCom = CreateFile (szCOM, GENERIC_WRITE | GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); if (hCom == INVALID_HANDLE_VALUE) { // Fehlerausgabe: LPVOID lpMsgBuf; FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL); MessageBox (NULL, (LPCTSTR)lpMsgBuf, "Error: CreateFile", MB_OK | MB_ICONINFORMATION); LocalFree (lpMsgBuf); return (1); // und tschüß ... } dcb.DCBlength = sizeof(DCB); // Laenge des Blockes MUSS gesetzt sein! GetCommState (hCom, &dcb); // COM-Einstellungen holen und aendern dcb.BaudRate = BD_RATE; // Baudrate dcb.ByteSize = 8; // Datenbits dcb.Parity = NOPARITY; // Parität dcb.StopBits = ONESTOPBIT; // Stopbits SetCommState (hCom, &dcb); // COM-Einstellungen speichern GetCommTimeouts (hCom, &ct); // Warte-Zeit [ms] vom Beginn eines Bytes bis zum Beginn des nächsten Bytes ct.ReadIntervalTimeout = 1000 / BD_RATE * (dcb.ByteSize + (dcb.Parity == NOPARITY ? 0 : 1) + (dcb.StopBits == ONESTOPBIT ? 1 : 2)) * 2; ct.ReadTotalTimeoutMultiplier = 0; // [ms] wird mit Read-Buffer-Size multipliziert ct.ReadTotalTimeoutConstant = 50; // wird an ReadTotalTimeoutMultiplier angehängt ct.WriteTotalTimeoutMultiplier = 0; ct.WriteTotalTimeoutConstant = 0; SetCommTimeouts (hCom, &ct); // Zwischenspeicher des serial-Drivers einstellen (für read und write): SetupComm (hCom, COM_BUFFER_SIZE, COM_BUFFER_SIZE); SetCommMask (hCom, dwSetMask); // Empfangssignale definieren do // in Endlos-Schleife auf Empfangssignale warten: { WaitCommEvent (hCom, &dwEvtMask, &o); // Event mit Empfangssignalen verknüpfen if (WAIT_OBJECT_0 == WaitForSingleObject (o.hEvent, INFINITE)) // warten bis Event { if (dwEvtMask & EV_RXCHAR) // Zeichen an RxD empfangen: { bRet = ReadFile (hCom, &InString, sizeof (InString), &dwRead, NULL); if (!bRet) { // Fehlerausgabe: LPVOID lpMsgBuf; FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL); MessageBox (NULL, (LPCTSTR)lpMsgBuf, "Error: ReadFile", MB_OK | MB_ICONINFORMATION); LocalFree (lpMsgBuf); } else { // Ausgabe (oder Verarbeitung) der empfangenen Bytes: InString[dwRead] = '\0'; // in "zero-ended"-String verwandeln printf (TEXT("\r\n\tRxD (%d Byte(s)): %s"), dwRead, InString); WriteFile (hCom, &InString, dwRead, &iBytesWritten, NULL); // Senden der Bytes } } if (dwEvtMask & EV_ERR) { MessageBox (NULL, "Error empfangen", "Error: ReadFile", MB_OK); break; // Schleifen-Abbruch } } } while (1); CloseHandle (hCom); // COM schließen CloseHandle (o.hEvent); // Event-Handle zurückgeben return (0); }Die Quellcode-Teile kannst Du nach Belieben in Dein Prog einbauen.
Blackbird