mikrocontroller.net

Forum: PC-Programmierung Ubuntu - serielle schnittstelle / rs232 schliessen


Autor: phreak (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, weis zufällig jemand wie ich bei Ubuntu die Serielle 
schnittstelle wieder schliessen kann??
Habe ein Programm dass manchmal abschmiert und die schnittstelle ist 
dann noch offen..

Danke schon mal..

Autor: Niklas Gürtler (erlkoenig)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Fange das Signal SIGSEGV ab, welches an das Programm gesendet wird, wenn 
es durch ungültige Pointer abstürzt, und schließe das Datei-Handle:
#include <signal.h>

// Datei-Handle auf Schnittstelle.
int fd_rs232 = -1;

void on_segv(int sig);

int main () {
 // RS232 -Schnittstelle öffnen
 fd_rs232 = open ....
 
 // Signal SEGFAULT (=Absturz) abfangen
 signal(SIGSEGV, on_segv);
 
 // Irgendwas tuen...
}

// Signal-Handler
void on_segv(int sig) {
 // Schnittstelle offen?
 if(fd_rs232 != -1)
   // Schließen
   close(fd_rs232);
}
Siehe
man 2 signal
PS: Die Schnittstelle ist nach einem Absturz nur kurze Zeit noch offen, 
danach schließt der Kernel sie automatisch.

Autor: phreak (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hmm irgdnwie schiesst es mir den Port immer ab, wenn ich dann vom System 
darauf zugreifen will bekomme ich einen "Input/Output Error" und von 
alleine schliesst er sich auch nicht.. ??

Autor: phreak (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
irgendwas stimmt da nicht. der port wird nicht mal geschlossen wenn ich 
alle prozesse kille ( strg + alt + <---- )

Autor: Niklas Gürtler (erlkoenig)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
phreak schrieb:
> irgendwas stimmt da nicht. der port wird nicht mal geschlossen wenn ich
> alle prozesse kille ( strg + alt + <---- )
Ähm, das killt nur den X-Server. Grafische Programme können darauf 
reagieren und sich beenden, müssen sie aber nicht und können fröhlich 
weiter laufen.
Versuch mal "lsof | grep /dev/ttyXX" um herauszufinden welche Prozesse 
noch auf die Schnittstelle zugreifen. Hast du mal meinen Code oben 
eingebaut, und die Schnittstelle wird trotzdem nicht geschlossen oder 
was?

Autor: phreak (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
habe es eingebaut, aber das programm hat wohl noch andere Porbleme.. :(
lsof | grep /dev/ttyUSB0
lsof: WARNING: can't stat() fuse.gvfs-fuse-daemon file system /home/user/.gvfs
      Output information may be incomplete.

versuche es jetz mal mit der libserial

btw: Danke für die Unterstützung :)

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was machsten da fürn Kram? :-)

Beim Beenden sollte eigentlich automatisch aufgeräumt werden. Oder was 
meinst du mit 'schließen'?

Autor: phreak (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hehe ja sollte, aber das klappt noch nicht...
folgendes. Vielleicht hilft das hier ja noch weiter:

...
...
#include <SerialStream.h>
using namespace LibSerial ;
SerialStream rs232 ;
...
...
// Port öffnen
void plot232Dialog::OnOpen(wxCommandEvent& event)
{

    rs232.Open( "/dev/ttyUSB0" );
    rs232.SetBaudRate( SerialStreamBuf::BAUD_115200 );
    rs232.SetCharSize( SerialStreamBuf::CHAR_SIZE_8 );
    rs232.SetNumOfStopBits(1);
    rs232.SetParity( SerialStreamBuf::PARITY_ODD );
    rs232.SetFlowControl( SerialStreamBuf::FLOW_CONTROL_HARD );
    StaticText1->SetLabel(_("port open"));

}
...
...
// port schliessen
void plot232Dialog::OnClose(wxCommandEvent& event)
{
    rs232.Close();
}
...
...
// zum testen ein byte lesen.. 
void plot232Dialog::OnTest(wxCommandEvent& event)
{

    char next_char;
    rs232.get(next_char);
    wxString str;
    str<<next_char;
    StaticText1->SetLabel(str);
}


wenn ich jetzt den Port öffne scheint er irgdnwie offen zu sein, 
zumindest ist er danach blockiert :/ wenn ich ihn wieder schliesse 
rs232.close() ist er trotzdem noch blockiert...
und beim Lesen kommt immer nur 0 raus ... damit ich nicht nach jedem 
build neustarten muss wollt ich fragen wie ich den Port abwürgen kann, 
oder alternativ warum das Programm so ein Blödsinn macht ;)

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Einfach aus- und wieder einstecken? Ist doch nach dem Namen zu urteilen, 
ein USB-seriell-Wandler.

Autor: phreak (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
aus und einstecken hilft auch nicht :(

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, ich hab exakt dasselbe Problem. Ich verwende ebenfalls die 
libserial und muss jedes mal, wenn die Verbindung mit meinem ftdi-device 
(serial2USB-Converter /dev/ttyUSB0) unsanft beendet wird, den PC neu 
starten.

Der Kernel erkennt zwar, wann das device eingesteckt/abgezogen wird 
(dmesg), allerdings meldet er scheinbar nicht den socket ab.

lsusb -v
 spuckt folgendes aus...
Bus 004 Device 002: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial (UART) IC
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0         8
  idVendor           0x0403 Future Technology Devices International, Ltd
  idProduct          0x6001 FT232 USB-Serial (UART) IC
  bcdDevice            6.00
  iManufacturer           1 
  iProduct                2 
  iSerial                 3 
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           32
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0xa0
      (Bus Powered)
      Remote Wakeup
    MaxPower               90mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass    255 Vendor Specific Subclass
      bInterfaceProtocol    255 Vendor Specific Protocol
      iInterface              2 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
can't get device qualifier: Operation not permitted
can't get debug descriptor: Operation not permitted
cannot read device status, Operation not permitted (1)



...und dmesg nach Abziehen/anstecken folgendes...
[15583.748052] usb 4-2: USB disconnect, address 2
[15583.749092] ftdi_sio ttyUSB0: FTDI USB Serial Device converter now disconnected from ttyUSB0
[15583.749128] ftdi_sio 4-2:1.0: device disconnected
[15588.160069] usb 4-2: new full speed USB device using uhci_hcd and address 3
[15588.363085] usb 4-2: configuration #1 chosen from 1 choice
[15588.365160] ftdi_sio 4-2:1.0: FTDI USB Serial Device converter detected
[15588.365232] usb 4-2: Detected FT232RL
[15588.365795] usb 4-2: FTDI USB Serial Device converter now attached to ttyUSB0


Also falls es einen Befehl gibt, wie man das Problem beheben kann, ohne 
jedes mal den Rechner neu zu starten, bitte bitte posten.

Autor: Micky (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich kann eigentlich jedem nur raten, bei Funktionsaufrufen auch die 
Rückgabewerte zu überprüfen, auszuwerten und angemessen darauf zu 
reagieren. Dafür sind die da!

Wenn ich diese Codesequenz lese:
// Port öffnen
void plot232Dialog::OnOpen(wxCommandEvent& event)
{

    rs232.Open( "/dev/ttyUSB0" );
    rs232.SetBaudRate( SerialStreamBuf::BAUD_115200 );
    rs232.SetCharSize( SerialStreamBuf::CHAR_SIZE_8 );
    rs232.SetNumOfStopBits(1);
    rs232.SetParity( SerialStreamBuf::PARITY_ODD );
    rs232.SetFlowControl( SerialStreamBuf::FLOW_CONTROL_HARD );
    StaticText1->SetLabel(_("port open"));

}

dann ist da ein gutes Stück Hoffnung drin, das aber laut Murphy, na Ihr 
wisst schon...

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hatte den Effekt auch schon, dass bei einem Fehler in einem 
USB/seriell-Wandler dieser und alle anderen(!) nicht mehr ansprechbar 
waren.  Statt Reboot tut's dann auch ein modprobe -r usbserial 
(natürlich nachdem alle USB/seriell-Prozesse beendet wurden).

Mit neueren Kernels (ab ca. 2.6.29) scheint das Problem weg zu sein; es 
trat jedenfalls nicht mehr auf.

----
(Übrigens, weiter oben: Ein SIGSEGV kann vom verursachenden Prozess 
nicht abgefangen werden - der Prozess bekommt vom Kernel keine Chance 
dazu mehr, denn er wird sofort beendet und hört mit dem SEGV auf zu 
laufen.  Es wird kein Signalhandler im Prozess aufgerufen.  Sein I/O 
wird geschlossen (auch vom Kernel).)

Autor: Micky (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der mizch mag ja Recht haben, aber wer Returncodes von Libc-Aufrufen, 
auch wenn sie in C++ verpackt sind, ignoriert, der soll hiermit gewarnt 
werden: Irgendwann geht das in die Hose!

Unter Linux ist es ja doch so, dass wenn ein Prozess endet, alle von ihm 
belegten Dateien (dazu zählen auch die seriellen Schnittstellen) 
freigegeben werden.
Aber darum geht es doch hier nicht!
Das laufende Programm soll bemerken, dass ihm die Schnittstelle abhanden 
gekommen ist. Wie soll das denn gehen, wenn sich keiner darum kümmert?

Autor: Niklas Gürtler (erlkoenig)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hazeh Zimmerer schrieb:
> (Übrigens, weiter oben: Ein SIGSEGV kann vom verursachenden Prozess
> nicht abgefangen werden - der Prozess bekommt vom Kernel keine Chance
> dazu mehr, denn er wird sofort beendet und hört mit dem SEGV auf zu
> laufen.  Es wird kein Signalhandler im Prozess aufgerufen.  Sein I/O
> wird geschlossen (auch vom Kernel).)
Ganz sicher? Bei mir funktioniert's:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

void onsegv(int sig) {
  printf("Programm abgeschmiert\n");
  exit (0);
}

int main () {
  signal(SIGSEGV, onsegv);
  int* i = 0;
  printf("%d\n", *i);
}
Müsste der Gnome Bug Buddy nicht auch so funktionieren?

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da passiert kein SEGV, sondern es wird über den normalen Mechanismus ein 
Signal gesendet.  Greif mal spaßeshalber auf einen Nullpointer zu und 
aus ist's damit.

Autor: Niklas Gürtler (erlkoenig)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hazeh Zimmerer schrieb:
> Da passiert kein SEGV, sondern es wird über den normalen Mechanismus ein
> Signal gesendet.  Greif mal spaßeshalber auf einen Nullpointer zu und
> aus ist's damit.
Was, wenn nicht ein Null-Pointer-Zugriff, ist denn das:
int* i = 0;
printf("%d\n", *i);
Edit: Okay, int* i = NULL wäre vermutlich sauberer, wie hier auch 
irgendwo im Forum durchdiskutiert wurde.

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich denke, ich muss mich korrigieren.  SEGV ist nicht zwingend fatal und 
kann von einem Handler abgefangen werden.  Man lernt nie aus.

Autor: Frank Lorenzen (florenzen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
POSIX schreibt das sogar vor.


gruß
f

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.