Hallo ich brauche nochmal einen tip.
soweit ich bisher gelernt habe gibt die Funktion read() bei non_blocking
0 zurück wenn ein eof gekommen ist, int > 0 wenn's was zu lesen gab, der
string aber noch nicht zu ende ist und int < 0 + EAGAIN == errno wenn
noch nichts angekommen ist. Das seltsame ist, bei mir gibt sie 0 zurück
obwohl noch gar kein eof gekommen sein kann, da der String noch nicht
fertig gelesen wurde.
statt dessen
root:~> ./uart
,12,-gesendete_bytes
AT#SELINT=2
,6,-empfangene_bytes
n==0
,AT#SEL,-empfangener_string
und
AT#SELINT=2
OK
sollte gelesen werden
----------------------------------------------------------------
....
fd = open(path, O_RDWR | O_NOCTTY | O_NDELAY);
fcntl(fd, F_SETFL, FNDELAY);
....
----------------------------------------------------------------
int receive(int fd, char * rx_buffer,int sec, int usec)
{
int n,bytes_read;
fd_set rdfs;
struct timeval timeout;
timeout.tv_sec = sec;
timeout.tv_usec = usec;
FD_ZERO(&rdfs);
FD_SET (fd,&rdfs);
n = select(fd + 1, &rdfs, NULL, NULL, &timeout);
if(n < 0)
{
perror("select failed\n");
}
else if (n == 0)
{
puts("Timeout!");
}
else if (FD_ISSET(fd, &rdfs))
{
bytes_read=0;
while(1)
{
n = read(fd,rx_buffer + bytes_read + 1, rx_buffer_size -
bytes_read);
if (n >0)
{
bytes_read = bytes_read + n;
printf( "\n,%d,-empfangene_bytes\n", n );
}
if (n==0)
{
puts("n==0");
break;
}
if ((n<0)&&(EAGAIN != errno))
{
perror("read error\n");
break;
}
}
printf( "\n,%s,-empfangener_string\n", rx_buffer );
return bytes_read;
}
Hat jemand eine Idee?
vielen Dank im Voraus
Ralph Feuchter schrieb: > fd = open(path, O_RDWR | O_NOCTTY | O_NDELAY); > fcntl(fd, F_SETFL, FNDELAY); mit dem fcntl setzt du aber fd wieder zurück auf blocking.
Stimmt, ich habe aber VMIN und VTIME auf 0. müsste das nicht trotzdem read() zu non_blocking Verhalten zwingen? Ich probiere es aber noch mal ohne fcntl(fd, F_SETFL, FNDELAY) aus und melde mich wieder. Vielen Dank ralph
Ralph Feuchter schrieb: > Hallo ich brauche nochmal einen tip. > soweit ich bisher gelernt habe gibt die Funktion read() bei non_blocking > 0 zurück wenn ein eof gekommen ist, Das ist unabhängig davon ob er blocking oder non-blocking ist. > int > 0 wenn's was zu lesen gab, der string aber noch nicht zu ende ist Was verstehst du hier unter "der string"? read() gibt 0 zurück, wenn das Ende des Files erreicht wurde, es also auch in Zukunft nichts mehr zu lesen geben wird, oder wenn man ihm als Anzahl zu lesender Bytes 0 übergibt. Die Funktion arbeitet einfach mit Bytes und weiß überhaupt nichts von Strings. Ralph Feuchter schrieb: > Stimmt, ich habe aber VMIN und VTIME auf 0. müsste das nicht trotzdem > read() zu non_blocking Verhalten zwingen? Ich probiere es aber noch mal > ohne fcntl(fd, F_SETFL, FNDELAY) aus und melde mich wieder. Die richtige Methode für fcntl wäre, die Flags erst auszulesen (F_GETFL), dann mit den gewünschten zusätzlichen Flags zu verODERn und dann das Ergebnis zu setzen.
also ganz kurz was ich machen will: ich schicke an ein modem ein AT befehl und das modem antwortet dann in der Regel mit dem echo des Befehls + LF + OK. Mit select() warte ich jetzt wann auf dem file descriptor was passiert. sobald das modem antwortet wird read() in einer while Schleife solange aufgerufen bis die komplette Antwort ausgelesen wurde. Allerdings was bei mir passiert ist, dass read() beim ersten Durchlauf den Teil aus dem Buffer liest der angekommen ist und die anzahl der gelesenen Bytes zurück gibt. Bis her ist alles ok. Nun im zweiten Durchlauf ist wahrscheinlich noch kein byte des Rests angekommen. jetzt sollte read() -1 zurück geben und EAGAIN = errno setzen. Aber was machts, es gibt 0 zurück als ob eof angekommen wäre und die Schleife bricht ab. offensichtlich sind die Settings für fd falsch, aber welche??
Ralph Feuchter schrieb: > also ganz kurz was ich machen will: > ich schicke an ein modem ein AT befehl und das modem antwortet dann in > der Regel mit dem echo des Befehls + LF + OK. > Mit select() warte ich jetzt wann auf dem file descriptor was passiert. > sobald das modem antwortet wird read() in einer while Schleife solange > aufgerufen bis die komplette Antwort ausgelesen wurde. Woran erkennst du denn, daß die Antwort komplett ist? > Allerdings was bei mir passiert ist, dass read() beim ersten Durchlauf > den Teil aus dem Buffer liest der angekommen ist und die anzahl der > gelesenen Bytes zurück gibt. Bis her ist alles ok. Nun im zweiten > Durchlauf ist wahrscheinlich noch kein byte des Rests angekommen. jetzt > sollte read() -1 zurück geben und EAGAIN = errno setzen. Aber was > machts, es gibt 0 zurück als ob eof angekommen wäre und die Schleife > bricht ab. Ist dein Puffer vielleicht voll? Wie gesagt, wenn du an read() als Anzahl der zu lesenden Bytes 0 übergibst, gibt es auch 0 wieder zurück. Das tust du, wenn du am Ende deines Puffers angekommen bist, denn dann ist rx_buffer_size - bytes_read==0. > offensichtlich sind die Settings für fd falsch, aber welche?? Ich wüßte keine Settings, die dazu führen, daß read() einfach so 0 zurückgibt.
vielen dank für die Antwort. die Antwort besteht immer aus dem Echo und einem "OK". Der buffer hat für 20 bytes Platz und die Antwort ist maximal 15 bytes lang. Wenn ich mit dem read() Aufruf lange genug warte, liegt die Antwort auch komplett im buffer. Das Problem tritt auf wenn ich zu zeitig lese. Dann ist im besten Fall das erste Fragment der Antwort im tty-buffer. Lese ich ein zweites mal, sollte eignetlich, wenn noch nichts da ist, -1 returned werden. Aber es gibt 0 zurück. übrigens auch wenn ich einige ms später lese, wenn der rest längst angekommen sein sollte. Dann wäre die 0 zwar richtig aber read() hätte was gelesen haben müssen, was es nicht tut. also das der buffer voll ist, ist ziehmlich ausgeschlossen. ralph
Bitte auch nicht ausser acht lassen, dass hier von einem seriellen Port gelesen werden soll. D.h. die 'File-Nomenklatur' EOF (End of File) ist da nur bedingt anwendbar. read() liefert einfach nur die Anzahl der Zeichen, die gelesen werden konnten. Bei einer seriellen Schnittstelle kann das auch schon mal 0 sein, ganz einfach deswegen, weil in der Zwischenzeit kein Zeichen eingetrudelt ist. Bei einem File gibt es aber nur den einen Fall, dass 0 zurückgeliefert werden kann: nämlich wenn das Ende des Files erreicht ist. Aber: Die ganze EOF Systematik ist auf Dinge wie Netzwerk und/oder externe Schnittstellen nicht wirklich anwendbar, weil kein Programm und auch kein I/O System in die Zukunft schauen kann. Wenn momentan keine weitere Daten abholbereit vorhanden sind, dann sind eben momentan keine weiteren Daten vorhanden. Was nicht heißt, dass das 10 Millisekunden später nicht schon wieder ganz anders sein kann. Hier ist also ein Returnwert von 0 zu lesen als: Im Moment hab ich nichts, was ich dir geben könnte. Deine ganze Sichtweise > Das seltsame ist, bei mir gibt sie 0 zurück obwohl noch gar kein eof > gekommen sein kann, da der String noch nicht fertig gelesen wurde. macht mich stutzig. Kein einziges dieser Konzepte ist auf das Lesen mittels read() auf einem mit einer Seriellen verbundenen Stream-Descriptor anwendbar. Weder EOF macht in diesem Kontext Sinn, noch weiß read() irgendwas von irgendwelchen Strings. read() liefert einfach nur gelesene Bytes (deren Anzahl auch schon mal 0 sein kann) und ansonsten obliegt es dir aus den Bytes was zu machen.
Karl Heinz Buchegger schrieb: > Bitte auch nicht ausser acht lassen, dass hier von einem seriellen Port > gelesen werden soll. > > D.h. die 'File-Nomenklatur' EOF (End of File) ist da nur bedingt > anwendbar. read() liefert einfach nur die Anzahl der Zeichen, die > gelesen werden konnten. Bei einer seriellen Schnittstelle kann das auch > schon mal 0 sein, ganz einfach deswegen, weil in der Zwischenzeit kein > Zeichen eingetrudelt ist. Nein, eigentlich nicht. Wenn der Port blockierend geöffnet wird, wartet read() einfach, bis was da ist. Bei non-blocking, gibt die Funktion -1 zurück und setzt errno auf EAGAIN, wenn gerade nichts da ist. Das sollte auch unabhängig davon sein, ob das nun ein File, ein Socket, ein Device oder sonstwas ist.
Vielen Dank für Eure ausfürlichen Erklährungen. Karl Heinz seine Erklährung ist einleuchtend, wenn nichts zu lesen ist würde read() 0 zurückgeben. Rolf seine Sache deckt sich eher mit dem was ich bis her gehört habe und würde mir auch mehr nützen. Zumal ich jetzt das ganze auf einem richtigen Linuxrechner ausprobiert habe und da kommt bei nonblocking -1 und EAGAIN wenn noch nichts angekommen ist. beim Blackfin-uClinux kommt 0 statt -1 an der Stelle. Habe es auch ans Blackfin forum geschrieben. werde mich wieder melden wenn ich etwas von dort höre. Aber nochmal: Wenn read() in jedem falle 0 zurück gibt wenn nichts zu lesen ist, wie kann man denn dann eine längere Zeichenkette, deren Länge nicht bekannt ist vollständig empfangen, ohne unnötig lange zu warten bis nun alles angekommen sein müsste? ralph
Rolf Magnus schrieb: > Karl Heinz Buchegger schrieb: >> Bitte auch nicht ausser acht lassen, dass hier von einem seriellen Port >> gelesen werden soll. >> >> D.h. die 'File-Nomenklatur' EOF (End of File) ist da nur bedingt >> anwendbar. read() liefert einfach nur die Anzahl der Zeichen, die >> gelesen werden konnten. Bei einer seriellen Schnittstelle kann das auch >> schon mal 0 sein, ganz einfach deswegen, weil in der Zwischenzeit kein >> Zeichen eingetrudelt ist. > > Nein, eigentlich nicht. Hast recht. Da haben mich heut nachmittag irgendwie ein paar Links verwirrt, die das anders zu beschreiben schienen. Ich find die aber jetzt nicht mehr (bin auf einem anderen Rechner)
Ralph Feuchter schrieb: > Vielen Dank für Eure ausfürlichen Erklährungen. Karl Heinz seine > Erklährung ist einleuchtend, aber laut Doku der read() Funktion falsch. Was natürlich nicht heißt, dass sich deine read Funktion nicht genau so verhält, wenn von einee Seriellen die Rede ist. Aber mitlerweile tendiere ich auch (wieder) dazu, das dann als Fehler der Implementierung von read anzusehen.
Ralph Feuchter schrieb: > Wenn read() in jedem falle 0 zurück gibt wenn nichts zu lesen ist, wie > kann man denn dann eine längere Zeichenkette, deren Länge nicht bekannt > ist gar nicht. Irgendetwas musst du vom String wissen. Entweder wieviele Zeichen da daher kommen oder du musst eine Übereinkunft mit dem Sender haben, welches Zeichen er als letztes an jeden String drann hängt. Üblich ist zb ein \n oder ein ;. \n deswegen weil man dann an die andere Leitung ein Terminal hängt und wenn der Benutzer auf 'Return' haut, dann ist das das Zeichen für den Sender, dass der String (die 'Zeile') jetzt komplett ist. Aber zaubern oder hellsehen kann weder der Sender, der Empfänger, die Runtime Library noch read(). Da du anscheinend am anderen Ende ein AT-Modem hängen hast: Jede Antwort vom Modem wird mit einem \n abgeschlossen. Das ist dein Zeichen, dass das Modem eine Zeile (eiunen String) komplett rausgeblasen hat.
Hallo ich bin wieder da. jetzt funktioniert alles wie erwartet. read()gibt -1 und errno == eagaine zurück und liest auch das kommando bis zum CR aus dem buffer. was es nun war kann ich leider nicht sagen, der Rat vom BF-forum war, eine andere uClinux version zu testen. hier der link zum tread: http://ez.analog.com/message/61525 eigenartig ist nur, das meine version nach dem Neucompilieren auch funktionierte. nicht recht zufriedenstellend, .. wenn man nicht weiss woran es nun gelegen hat. finde ich es noch raus, schreibe ich es noch. bis dahin und vielen Dank für Eure unterstützung ralph
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.