Transmisja szeregowa, zabezpieczenie przed usunięciem sprzętu przy zapisie/odczycie

0

Chciał bym zapisać ciąg znaków do urządzenia komunikującym się po RS232.
Otwieram więc port i przygotowuje się do wysłania

 
int funkcja(przekazuje bufory itp)
{
//powyżej inicjalizacja zmiennych w funkcji i pobranie buforów

while (AByteLeft) { //gdy pozostały znaki do wysłania
		ASendBuffer += ABytesWritten;  //poruszanie się po buforze //i w tym momencie odłączam urządzenie lecz kompilator 
		
                 if(!WriteFile(hHandle, ASendBuffer, AByteLeft, &ABytesWritten, NULL)) { //zwraca w wyniku WriteFile '1' co oznacza poprawny zapis jednak zapisu nie było bo 
			*ApSystemError = GetLastError();                                                //&ABytesWritten nie zwiększa się //GetLastError() zwraca 0 jakby wszystko było ok
			
                         if (*ApSystemError == ERROR_INVALID_HANDLE || *ApSystemError == ERROR_DEVICE_REMOVED) {
				return -1;
			}
			return -2;
		}                                                                     
		AByteLeft -= ABytesWritten;
	}                                                                                                 //dochodzi do tego, że program zawiesza się w pętli
	return 0;
}

Niestety zamiast zwrócić błąd, program zostaje w pętli. Jest na to jakieś rozwiązanie?

0

Dodaj sobie sprawdzanie jeżeli ABytesWritten było równe zero z rzędu, dajmy na to 5 razy, to załóż błąd i wyjdź z funkcji.

 
int funkcja(przekazuje bufory itp)
{
//powyżej inicjalizacja zmiennych w funkcji i pobranie buforów

int NumFailed = 0;
static const int MAX_FAILED = 5;
while (AByteLeft && NumFailed != MAX_FAILED) { //gdy pozostały znaki do wysłania
		ASendBuffer += ABytesWritten;
		
		if(!WriteFile(hHandle, ASendBuffer, AByteLeft, &ABytesWritten, NULL)) {
			*ApSystemError = GetLastError();
			 
			if (*ApSystemError == ERROR_INVALID_HANDLE || *ApSystemError == ERROR_DEVICE_REMOVED) {
				return -1;
			}
			return -2;
		}                                                                     
		
		if (ABytesWritten == 0)
		{
			++NumFailed;
			continue;
		}

		AByteLeft -= ABytesWritten;
		NumFailed = 0;
	}
	return 0;
}
0

No tak, to by nawet rozwiązało sprawę.

Kolejnym problemem jest odebranie danych. Na porcie COM1 działa mi aplikacja, która ma wysłać i odebrać dane. Wysyłam ciąg znaków AAAA i on trafi do urządzenia bez problemu jednak gdy na z COM1 aplikacja ma odczytać dane przy pomocy ReadFile, coś dziwnego zaczyna się dziać. Na port jest wysyłane "BBBBB" a ReadFile widzi to jako np B(.BB

       ClearCommError(FPortHandle, &AErrors, &FCOMSTAT);
	if (FCOMSTAT.cbInQue>0) {
		ReadFile(hHandle, AReadBuffer, ABytesLeft, &AReadedBytes, NULL);
	}

 
0

Wyślij coś bardziej znaczącego, jak "abcdef", bo tak to nie wiadomo czy przychodzi dodatkowy smietnik, czy dane są psute po drodze..

0

Bez różnicy.
Mam jeszcze taką strukturę

 
COMMTIMEOUTS  ACOMMTIMEOUTS;                                            //Contains the time-out parameters for a communications device.
		ACOMMTIMEOUTS.ReadIntervalTimeout 		= MAXDWORD;                  
		ACOMMTIMEOUTS.ReadTotalTimeoutMultiplier 	= 0;                        
		ACOMMTIMEOUTS.ReadTotalTimeoutConstant 	= 0;
		ACOMMTIMEOUTS.WriteTotalTimeoutMultiplier 	= 0;
		ACOMMTIMEOUTS.WriteTotalTimeoutConstant 	= 0;

1

Ale co bez różnicy? Wysyłasz "abcde" i przychodzi "B(.BB". Pisz konkrety, a nie każ mi się domyślać każdej pierdoły.

0

Zacznij od odpalenia sobie HyperTerminal (chyba nadal jest w Windows) połącz się z urządzeniem i zobacz co ono odbiera i co możesz wysłać.
Jak już to ogarniesz wróć do kodowania.

1 użytkowników online, w tym zalogowanych: 0, gości: 1