NSFileHandle > richtig schließen

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • NSFileHandle > richtig schließen

    Hallo,

    ich bin immer noch an meinem NSFileHandle mit der seriellen Schnittstelle.
    Als solches funktioniert alles wie soll, aber es gibt noch einige unschöne Sachen.

    # Wie beende ich NSFileHandle richtig?

    Ich verwende dazu -closeFile, wie es logisch erscheint.
    Leider wirft es aber ab und an einen Fehler. So steht es auch in der Dokumentation, wenn noch mit dem "file handle" weiter gearbeitet wird.
    Meine Anwendung ist es aber nicht. Ich habe definitiv keine Aktionen mehr drauf laufen.

    Ich habe zum Test mal -synchronizeFile und -readDataToEndOfFile vor dem -closeFile ausgeführt.
    Um vielleicht mögliche Aktionen zum Ende laufen zu lassen.

    Das scheint aber keine Änderung zu bewirken.
    Was muss ich also tun, um -closeFile sicher auszuführen?

    Derweil fange ich es mit einem try-Block, aber das ist wirklich sehr unschön…

    # NSFileHandle liefert "altes Zeugs"

    Ich starte NSFileHandle und bekomme schlagartig ein paar Bytes kommuniziert.
    Das, obwohl mein Endgerät nicht angesteckt ist. D.h. der Adapter, der mit NSFileHandle redet, liefert etwas Altes.
    Es gibt kein Muster, das zu erkennen ist. Wie kann ich vorher "aufräumen"?

    # Geschriebene Daten werden immer wieder gelesen

    Schreibe ich etwas mit NSFileHandle, dann bekomme ich die Daten immer wieder als gelesen zurück.
    Ich arbeite derweil mit einem Index um diesen Schnodder zu ignorieren. Chris hat mir geraten "echo" auszuschalten.
    Das hatte ich auch schon vorher versucht, aber leider hat das keine Wirkung. Kann mir jemand ein Beispiel zeigen, wie man es wirklich ausschaltet?
    "attributes.c_oflag &= ~ECHO", oder was mache ich falsch?

    Danke.

    Viele Grüße
  • Vielen Dank für Deine Antwort!

    Die Frage habe ich mir auch schon gestellt und kann sie mir leider nicht selbst beantworten.

    Die Kette vom Anschluss ist so:
    Endgerät > USB-Dongle > USB-Anschluss am Rechner > Apple-Zauberwelt > meine Anwendung

    Ich habe zwar "Unterstützung" vom Hersteller, aber der weiß selbst nicht was dadrin abgeht.
    War wohl alles mal eine externe Auftragsarbeit.

    Die Sache ist mir aber gar nicht so dringlich, da ich die eben mit einem Index gelöst habe.
    Den schleife ich zwar unnötig mit, aber da stimmt alles immer genau und da war bislang nie ein Byte verklemmt.

    Viele Grüße
  • Ich hab mal in alten Sourcen gewühlt und was zusammen kopiert.

    int descriptor = open([self.path cStringUsingEncoding:NSASCIIStringEncoding], O_RDWR | O_NOCTTY | O_EXLOCK | O_NONBLOCK);
    fcntl(descriptor, F_SETFL, 0); // blocking wieder an

    struct termios options;
    tcgetattr(descriptor, &options);

    cfmakeraw(&options);

    options.c_cc[VMIN] = 1;
    options.c_cc[VTIME] = 2;

    // Auf 8n1 setzen
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS8;

    options.c_cflag &= ~PARENB;

    options.c_cflag & ~CSTOPB;

    options.c_lflag &= ~(ICANON | ECHO | ISIG); // canonical mode, echo und signale aus

    options.c_cflag & ~CRTSCTS; // RTS/CTS Flow Control aus
    options.c_cflag & ~(CDTR_IFLOW | CDSR_OFLOW); // DTR/DSR Flow Control aus
    options.c_cflag & ~CCAR_OFLOW; // DCD Flow Control aus

    options.c_cflag |= CREAD; // receiver an
    options.c_cflag |= HUPCL; // hangup on close an
    options.c_cflag |= CLOCAL; // cd ignorieren

    cfsetspeed(&options, 9600); // 9600 baud
    tcsetattr(descriptor, TCSANOW, &options);

    So hab ich die Initialisierung gemacht.
    cfmakeraw() schaltet in den "raw" mode und damit jegliches input und output processing ab. Damit dürfte eigentlich options.c_lflag &= ~(ICANON | ECHO | ISIG); überflüssig sein, habs aber nie ausprobiert.
    VMIN und VTIME sind nur bei blocking descriptor im raw-mode wirksam. VMIN bezeichnet die minimale Anzahl Zeichen die gelesen werden soll. VTIME ist die Zeit zwischen den Zeichen in ms. Ist VMIN erreicht und wird VTIME überschritten kommt read() zurück.
    Ich hab damals das ganze lesen mit select() und read() in einem pthread gemacht.

    Zum beenden wurde der descriptor auf nonblocking gesetzt, damit kommen select() oder read() zurück.
    fcntl(descriptor, F_SETFL, O_NONBLOCK);

    Die ursprünglichen termios Einstellungen wurden am Anfang gesichert und am Ende wieder eingespielt.
    tcsetattr(descriptor, TCSANOW, &originalOptions);
    close(descriptor); und feritch

    es gibt dann noch so Aufrufe wie tcdrain()oder tcflush(), einfach mal deren man page konsultieren.

    Wie gesagt nehme ich mittlerweile die orsserial lib.

    Chris
    Man macht einfach solange irgendwelche Dinge, bis man tot ist.
    Und dann bekommen die anderen Kuchen.