Bei FTDI-seriell Chip geht nur fopen(), aber nicht open()

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Hallo,

    ich habe einen USB-zu-seriell Adapter (FTDI USB-COM485-PLUS-2, mit FT-2232H Chip) am Raspi (mit Raspian), der wird beim Booten als ttyUSB0 erkannt, und ich kann auch z.B. mit einer Shell-Umleitung, per Python oder von einem C-Programm aus mit fopen ( "/dev/ttyUSB0" usw. drauf zugreifen. Ich brauche für eine Binär-Protokollanwendung aber einen ungepufferten Zugriff.
    Wenn ich es daher mit open() versuche, bekomme ich aber auf meinem B+ Modell 1 als Filedescriptor den Wert 1 zurück, bzw. auf meinem Rev. 2 Modell den Wert 2, also stdout bzw. stderr. Und da landet dann auch das, was ich mit write sende - auf dem Schirm. Und nach der Programmausführung ist mein Tastaturecho am Prompt weg.
    Hier der Aufruf:

    int USB = open( "/dev/ttyUSB0", O_RDWR| O_NONBLOCK | O_NDELAY | O_NOCTTY );

    Ich habe schon einiges an den Aufrufparametern ausprobiert, die Rechte sind auch OK, benutze den Standardbenutzer Pi, habe ihn zur Gruppe Dialout hinzugefügt. Hab keinen zusätzlichen Treiber installiert, benutze den kernel-eigenen Treiber.

    Habe mich an diesem und ähnlichen Beispielen orientiert:
    http://stackoverflow.com/questions/1926…device-in-linux

    Hat jemand eine Idee woran es hängen könnte oder hat jemand auch dieses Problem?

  • Bei FTDI-seriell Chip geht nur fopen(), aber nicht open()? Schau mal ob du hier fündig wirst!

  • Hi,
    kann ich nicht nachvollziehen ...

    C
    #include <stdio.h>
    #include <fcntl.h>
    
    
    main()
    {
    int USB = open( "/dev/ttyUSB0", O_RDWR| O_NONBLOCK | O_NDELAY | O_NOCTTY );
    printf("descriptor is %d\n", USB);
    }


    bringt

    Code
    pi@raspberrypi ~ $ make berlinpi
    cc     berlinpi.c   -o berlinpi
    pi@raspberrypi ~ $ ./berlinpi 
    descriptor is 3
    pi@raspberrypi ~ $

    Ich denke, das Problem ist an anderer Stelle des Sources.
    Ich für meinen Teil empfinde solche Dinge wie

    Code
    int USB = open ...


    also Definition direkt bei Verwendung als unsauber, weil dadurch teilweise haarsträubende Konstrukte möglich sind.
    Beispiel:

    Durch den Gültigkeitsbereich der Variablen in so einem Fall ist es durchaus möglich, zwei Variablen gleichen Namens sogar mit unterschiedlichen Typen zu definieren.
    Da verliert man schnell den Überblick, was denn jetzt wo gilt und was nicht.
    Deshalb habe ich mir bereits vor Jahrzehnten angewöhnt, alle benötigten Variablen am Anfang der Funktion erst mal zu definieren. Ausnahmen sind evtl. mal Schleifenzähler, die sonst nicht weiter benötigt werden.
    Langer Rede kurzer Sinn: versuch mal die Variable einmal am Anfang zu definieren und dann probier's noch mal ...


    cheers,
    -ds-

  • Nabend,

    dreamshader: die Variable vorher zu definieren ändert leider nichts. Aber Danke für Deinen Output, da fällt mir auf: ich rufe nur gcc <sourcefile.c> auf, muss ich noch evtl. mit make was linken?

    evil: durch "/dev/ttyAMA0" wird die native Serielle des Raspi angesprochen, das hilft mir mit dem FTDI nicht weiter... oder was soll mir der Beispielcode sagen? Habe mir wirklich viele Beispiele angeschaut, alle verwenden open(). Wenn man mal von Problemen liest, dann wird der FTDI gar nicht erkannt oder so. Um einen Hardwarebug auszuschließen habe ich einen neuen Raspi und einen neuen FTDI Adapter genommen, auch den Quellcode hab ich neu eingetippt - (fast) das selbe Ergebnis. Nach dem OS-Update des Rev.2 Modells bekomme ich jetzt 258 als Descriptor, aber das Verhalten ist das gleiche.

    Grübel...

  • Hallo dp,

    ich flipp' aus - Dein Vierzeiler funktioniert! Hab Deinen Code dann sukzessive in meinen verwandelt, und der Punkt an dem der Bug auftrat, ist eine if() Bedinung, die ich noch um das open() drumrum hatte und beim Abtippen leider eine Klammerebene unterschlagen hatte. Verdammt, man muss doch einfach immer mit copy&paste "klauen" - und natürlich auch posten, sorry. Hatte bislang ohne X gearbeitet und daher am anderen Rechner gechattet, jetzt erst bin ich live am Pi. Hier nochmal kopierter Originalcode zum Geniessen:

    so funktioniert's:
    if ( (USB = open( "/dev/ttyUSB0", O_RDWR| O_NONBLOCK | O_NDELAY | O_NOCTTY )) !=1);
    ...so NICHT!
    if ( USB = open( "/dev/ttyUSB0", O_RDWR| O_NONBLOCK | O_NDELAY | O_NOCTTY ) !=1);

    Oh Mann, es musste ja so was banales sein - kommt davon, länger nicht mehr programmiert. In C geht's von rechts nach links, wenn man nicht klammert oder wie war das...au weia.

    Danke für Deine Hilfe!

  • siehste ... als hätte ich es geahnt ;)
    Prima, dass es jetzt klappt ... :thumbs1:
    Diese Klammerungen können schnell unübersichtlich werden. Ich weiss schon, warum ich Sourcen ausschliesslich mit vi editiere ( hier z.B. %-Funktion :) )...

    cu,
    -ds-


  • so funktioniert's:
    if ( (USB = open( "/dev/ttyUSB0", O_RDWR| O_NONBLOCK | O_NDELAY | O_NOCTTY )) !=1);

    Das sind ja auch zwei Befehle in einem Zug! Wie soll der Compiler bei nur einfacher Klammerung wissen, daß Du den Inhalt der USB Variablen vergleichen möchtest? Er wird das Ergebnis des 'open' Befehls auf != 1 prüfen und das Ergebnis des Vergleichs in USB speichern - was hier nicht gewünscht ist.

    Deshalb die doppelte Klammerung, aber übersichtlicher wäre jedenfalls:

    Code
    USB = open( "/dev/ttyUSB0", O_RDWR| O_NONBLOCK | O_NDELAY | O_NOCTTY );
    if (USB != 1) ...

    Und der erzeugte Code sollte dem Einzeiler entsprechen - der Effizienz wegen ... ;)

    Gruß, mmi

  • Zuweisung und Abfrage in einem ist meisten verwirrend und fehleranfällig, darum vermeide ich das auch, so wie Beispiel und auch beim verlinkten stackoverflow.com wurde das getrennt gemacht. In C kann man viel in eine Zeile schreiben, ich setze aber eher auf lesbaren Code als ob kurze schreibweise.

    Einmal editiert, zuletzt von evil (13. März 2015 um 13:30)

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!