Hallo, ich bin dabei die uart1 Schnittstelle auf einem BF537-stamp uClinux Plattform zu configurieren. Angeschlossen ist ein GSM modem, was über AT-Befehle gesteuert wird. Wird ein AT-Befehl gesendet antwortet das modem normalerweise mit OK. read() wird gleich nach send() aufgerufen und sollte warten bis was kommt. So viel ich weiss gibt read() null zurück wenn nach ablauf eines timers nichts angekommen ist. Nun ist dieses Interval aber zu kurz. wenn mir jemand sagen kann wie ich den timer verändern kann, wäre prima. also ich meine nicht tty_config.c_cc[VTIME] und select() wollte ich erstmal nicht nehmen. hat jemand eine idee? vielen Dank im voraus ralph
Ralph Feuchter schrieb: > So viel ich weiss gibt read() null zurück wenn nach ablauf eines > timers nichts angekommen ist. Du solltest dir Gewissheit verschaffen, indem du das manual der verwendeten Implementierung (GNU libc?) konsultierst. Arbeitest mit der GNU library und setzt den Timer mit timerfd_create() auf?
Ein Rückgabewert 0 von read() im Unix-Stil heißt "end of file". Das heißt, auf diesem file descriptor kann man auch in Zukunft nur "end of file" lesen. Und wieso send()? Das ist für Sockets, aber hier geht es doch um eine serielle Schnittstelle, richtig?
klar doch, ich meine natürlich write() sorry!!! so viel ich bisher weiss gibt read() die Anzahl der empfangen bytes zurück, wenn welche zum Abholen im tty bereitliegen. Ist nichts da bevor der timer abgelaufen ist, kommt NULL raus und wenn was schief ging <0. Die Frage war wie der Timer heist und wie ich ihn verändern kann. Der tip mit timer_fd scheint kein schlechter Weg zu sein, nur weiss ich nicht ob uClinux das auch unterstützt. muss es erst ausprobieren und meld mich wieder. vielen dank jedenfalls!!
danke für den tip. hoffe uClinux unterstützt das auch. ich meld mich wieder. ralph
feu schrieb: > so viel ich bisher weiss gibt read() die Anzahl der empfangen bytes > zurück, wenn welche zum Abholen im tty bereitliegen. Ist nichts da bevor > der timer abgelaufen ist, kommt NULL raus und wenn was schief ging <0. Falsch. 0 (nicht NULL) heißt "end of file" und sonst nichts. Wenn der Deskriptor mit der Option O_NONBLOCK geöffnet ist und bei read() nichts zum Lesen vorliegt, gibt es sofort -1 zurück mit errno gesetzt auf EAGAIN. Ohne O_NONBLOCK wartet es bis etwas da ist, potentiell endlos, außer es wird durch ein externes Signal unterbrochen. Da gibt es keinen Timer. Hat überhaupt das write() ohne Fehler funktioniert und alle Zeichen gesendet? Es klingt mir irgendwie so, als ob die Fehlererkennung fehlt, also erstmal alle open/write/read Aufrufe auf Fehler abfragen und in dem Falle den Fehlercode in errno ausgeben (Tip: mit perror() kann man automatisch einen beschreibenden Text zum Fehler in errno ausgeben lassen).
vielen Dank Andreas. habe alles noch mal neu aufgesetzt und jetzt geht es.schwer zu sagen woran es nun gelegen hat. am Ende wars ein Interpretationsfehler von mir. Wie du sagst, es gibt tatsächlich keinen timer. Aber was könnte mann dann machen um zu vermeiden, dass wenn das modem nicht mehr reagiert die read() funktion nach gegebener Zeit abgebrochen wird? bin ich da mit timerfd_settimer() richtig, oder gibts da was anderes. danke im voraus ralph
select() ist sicher keine schlechte Sache. Ich werde es mal ausprobieren und melde mich wieder. Derweilen würde ich trotzdem gerne wissen was es mit den fFunktionen timerfd_settimer() , ~creat() und ~gettimer() aufsich hat und wozu/wie man sie verwendet.also wenn jemand eine Idee hat oder gar profi drin ist... vielen dank ralph
select() (oder poll(), ein anderes Interface zur selben Funktionalität) ist genau die Lösung dafür und noch mehr. Wenn select() sagt, dass auf einem Deskriptor etwas zu lesen ist, dann wird das erste read() darauf nie blockieren. Dazu kann man mit select() auf mehrere Deskriptoren warten und eben einen Timeout spezifizieren. timerfd_* sind Intervall-Timer, die ein Ablaufen statt über Signale über Dateideskriptoren mitteilen. Damit kann man Timer ohne Signale implementieren (Signale sind ja wie Interrupts und entsprechend aufwendig) und über select() in den normalen Ablauf integrieren. Ansonsten haben die nichts mit Datenübertragung zu tun.
ganz prima sache mit dem select(). es läuft wie am Schnürchen.
vielleicht hilfts mal jemandem, .. unten ist die Funktion angehangen.
und zu dem timerfd, wenn ich dich richtig verstanden habe müsste ich
read() auf nonblocking setzen und in eine Schleife einbauen, wobei die
Abbruchbedingung der timerfd oder eof wäre, ..?
also ersmal vielen Dank Andreas und auch an alle Anderen
ralph
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))
{
while ((n=read(fd,rx_buffer + bytes_read, rx_buffer_size -
bytes_read))>0)
{
bytes_read += n;
}
}
}
return n;
}
Ralph Feuchter schrieb: > und zu dem timerfd, wenn ich dich richtig verstanden habe müsste ich > read() auf nonblocking setzen und in eine Schleife einbauen, wobei die > Abbruchbedingung der timerfd oder eof wäre, ..? Naja, in der man-page zu timerfd_create() steht eigentlich alles inklusive einem ausführlichen Beispiel. Ralph Feuchter schrieb: > if (FD_ISSET(fd, &rdfs)) > { > while ((n=read(fd,rx_buffer + bytes_read, rx_buffer_size - > bytes_read))>0) > { > bytes_read += n; > } > } select() garantiert nicht, dass beliebig viel gelesen werden kann. Also funktioniert das nur, wenn fd das Flag O_NONBLOCK besitzt. Aber auch in diesem Fall fehlt hier die Behandlung für EOF und andere Fehler als EAGAIN.
nIch bin bisher davon ausgegangen, dass read() von selbst aufhört zulesen wenn eof kommt, was es in meinem Fall anscheinend auch macht. es eof findet ja auch wie in (http://gd.tuwien.ac.at/languages/c/programming-bbrown/c_075.htm) beschrieben ...The read() function attempts to read nbytes from the file associated with handle, and places the characters read into buffer. If the file is opened using O_TEXT, it removes carriage returns and detects the end of the file.... vielleicht hae ich auch zufàllig die richtigen Einstellungen beim öffnen des ports gewählt. und was timerfd_~() angeht, um die man-page zu lesen und zu verstehen muss man natürlich wissen was man damit machen kann, was in meinem Fall bis her nicht so richtig zutraf. aber trotzdem weiss ich die Tips zu schätzen. ralph
Hallo, ich muss noch mal drauf zurückkommen. ganz funktioniert es immer noch nicht. wenn ich die read() man page richtig gelesen habe, dürfte, read() nur 0 zurückgeben wenn beim letzten auslesen mit EFO abgeschlossen wurde. nun gibt das read() bei mir aber nun 0 zurück obwohl kein eof gekommen sein kann. habe Andreas's tips versucht einzubauen, mit -1 und EAGAIN geht es jetzt aber das eof wird nicht richtig gelesen. hat jemand eine Idee? vielen Dank im voraus der code ist im Anhang
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.