POSIX (QNX) RS232
-
Hiho @ all!
Ich möchte über eine RS232 Schnittstelle von meinem Laptop aus auf ein Board einen String senden, welches das Program abfangen soll.
Mit ByteArrays funtkioniert das ganze schon recht gut, aber als ich nun versucht habe einen string zu senden, diesen zu empfangen und in einem charArray abzuspeichern haut das ganze nicht mehr so hin.
Scheinbar werden nur die ersten 8 Zeichen empfangen bevor der Lesevorgang abgebrochen wird. bei einem zweiten leseaufruf wird der gesamte rest ohne muren aufgenommen.
Ich häng mal die Codeausschnitte am Ende mit rein. getestet habe ich das ganze indem ich zuerst ein ByteArray mit dem Wert (insgesamt) "600" sende (das funktioniert ganz wunderbar) und danach in einem zweitem sendedurchlauf einen String "Hallodudadraußen". Überprüfen tue ich das ganze mit qDebug()-Ausgaben auf die Konsole (ich verwende Qt). Als Ausgabe bekomme ich auf dem Board:
count: 3
value: 600
data: 0 , 4 , 92
data als char:ID 600
string: "hallodud"
count: 8
charData: hallodud
SizeOf(CharData): 50
z: 0
texttexttexttext: "hallodud"count: 3
value: 600
data: 97 , 100 , 114
data als char: adrID 600
string: "au?en"
count: 5
charData: au?en
SizeOf(CharData): 50
z: 1
texttexttexttext: "au?en"Ich habe die ausgaben mal unterteilt. der erste Absatz ist der erste Leseaufruf, welcher eine Zahl erwartet. Der zweite Absatz ist dann der Leseaufruf für den string, welcher aber dann abgebrochen wird. Danach kommt nochmals der erste Leseaufruf für die Zahl (liest aber diesmal chars ein) und dann wieder der string leseaufruf mit den restlichen zeichen.
Bei dem zweiten Leseaufruf können dann auch 50 Zeichen kommen, die werden alle brav eingelesen! Nur beim ersten Lesevorgang des Strings werden nur 8 Zeichen eingelesen!!hier der (wie ich denke) interessante Codeabschnitt. Es umfasst eigentlich alle wichtigen einstellungen und den Lesevorgang um den es mir geht.
Für eure Hilfe und Anregungen wäre ich sehr dankbar!!//--------------------------------------------------- //--------------------------------------------------- // Open the port if ((fd = open ("/dev/ser1", O_RDWR)) == -1) { fprintf(stderr, "Error with open() on /dev/ser1. Make sure exists.\n"); perror (NULL); exit(EXIT_FAILURE); } // Get the attributes if (tcgetattr( fd, &raw)) { close( fd ); return -1; } // Set input baud rate speed = B115200; cfsetispeed(&raw, speed);//inputspeed cfsetospeed(&raw, speed);//outputspeed //gewünschte Eigenschaften setzen raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON ); raw.c_oflag &= ~(OPOST); raw.c_cflag &= ~(CSIZE|IHFLOW|OHFLOW); raw.c_cflag |= CS8 | CREAD | CLOCAL; raw.c_cflag &= ~CSTOPB; raw.c_cflag &= ~PARENB; raw.c_lflag &= ~(ECHO | ICANON | ISIG | ECHOE | ECHOK | ECHONL | IEXTEN); raw.c_cc[VMIN] = 1;//minimale Characteranzahl raw.c_cc[VTIME] = 0;//zeit in deciseconds für jeden read-aufruf if ( tcsetattr( fd, TCSADRAIN, &raw ) == -1 ) // CHECK FOR -1 failure here - this is the actual "set" and it must succeed on nothing may have changed { fprintf(stderr, "Error with tcsetattr() on /dev/ser1.\n"); perror (NULL); exit(EXIT_FAILURE); } while(1) { for(int i = 0; i < sizeof(data); i++) {data[i] = 0;} for(int i = 0; i < sizeof(charData)-1; i++) {charData[i] = 0;} //erster Lesevorgang -> Bytearray, daher aufgesplittet count = read(fd, data, 3); if(data[1] == 0){value = ((int)data[2]);} if(data[1] == 1){value = ((int)data[2]) + 127;} if(data[1] == 2){value = ((int)data[2]) + 254;} if(data[1] == 3){value = ((int)data[2]) + 381;} if(data[1] == 4){value = ((int)data[2]) + 508;} if(data[1] == 5){value = ((int)data[2]) + 635;} if(data[1] == 6){value = ((int)data[2]) + 762;} if(data[1] == 7){value = ((int)data[2]) + 889;} if(data[1] == 8){value = ((int)data[2]) + 1016;} switch(value) { case 600: count = read(fd, charData, sizeof(charData)-1); *key = "TEXTFIELD"; *message = charData; emit setText(*key, *message); //#################################### qDebug() << "ID" << value; qDebug() << "string: " << *message; qDebug() << "count: " << count; qDebug() << "charData: " << charData; qDebug() << "SizeOf(CharData): " << sizeof(charData); qDebug() << "z: " << z; //#################################### z++; break; } }
-
So, ich habe es nun herausgefunden und poste die Lösung für andere WIssbegierige
Im Grunde war es ein Fehler meinerseits.. In den Man-Pages steht:
On success, the number of bytes read is returned (zero indicates end of file), and the file position is advanced by this number. It is not an error if this number is smaller than the number of bytes requested; this may happen for example because fewer bytes are actually available right now (maybe because we were close to end-of-file, or because we are reading from a pipe, or from a terminal), or because read() was interrupted by a signal.
Was in meinem Fall soviel bedeutet wie:
"Im moment nicht mehr als 8 Zeichen im Buffer, versuch es später nochmal"Dementsprechend habe ich dann den Einlesevorgang ein wenig abgeändert:
count2 = 0; temp = '0'; while(count2 < sizeof(charData)) { count = read(fd, &temp, 1); if(temp != '\r') { charData[count2] = temp; count2++; } else break; }
Nun wird solange eingelesen bis die abbruchbedingung auftritt oder das Array vollgeschrieben ist.
Ist auch die richtige herangehensweise fü das senden uund lesen wie ich im nachhinein festgestellt habeSo long,
-
Und jetzt hast du ein busy wait und verschwendest Prozessorzeit bei jedem Leseversuch. Ist das beabsichtigt oder hinderlich im Gesamtkonzept? Und meine QNX Doku sagt es explizit:
When read() returns successfully, its return value is the number of bytes actually read and placed in the buffer. This number will never be greater than nbyte, although it may be less than nbyte for one of the following reasons
-
@knivil: es ist nur ein busy wait, wenn der "fd" non-blocking geöffnet wurde (und ich sehe im code nicht die Verwendung von O_NONBLOCK).
Wenn nicht blockiert read solange bis wieder Daten gelesen werden können.