Ich möchte unter Ubuntu Daten mit ruby über /dev/ttyUSB0 austauschen.
Nach viel Gemurkse und einer Quelltext-Änderung in serialport.c habe ich
es endlich geschafft, mit Serialport.new den Port zu öffnen.
Nun ist schon die nächste Klippe aufgetaucht:
Schmiert bei sp.putc mit "Uncaught exception: not opened for writing"
ab.
/dev/ttyUSB0 hat rw-Permissions für alle und kann mit GTK-Term ohne
Probleme geschrieben und gelesen werden.
Hat jemand eine Idee, was da faul ist?
Also hier:
http://ruby-serialport.rubyforge.org/
Wir zumindest der Name des Port benötigt als erster Parameter, was macht
den die 0 da? Wenn ich die Doku verstehe mappt die nämlich defaultmäßig
nach /dev/ttyS0 und nicht nach /dev/ttyUSB0
Laut Beschreibung kann der erste Parameter eine Device-Nummer (0 für
/dev/ttyS0, oder COM1:) sein oder ein String, wie z.B. "/dev/ttyUSB0"
sein. Der Code unterscheidet intern an dieser Stelle auch zwischen einem
Int-Wert und einem String. Nur funktioniert das mit dem String aus mir
im Moment undurchsichtigen Gründen nicht - er will dort keinen String
sehen.
Umschifft habe ich das, indem ich im Posix-Implementierungsmodul die
Devicenamen von /dev/ttyS* nach /dev/ttyUSB* geändert habe. Damit
funktioniert wenigstens das Serialport.new(0, 115200).
So viel zur Vorgeschichte. Jetzt darfst du dich zum eigentlichen Problem
äußern ;-)
Gleich noch eine Randfrage:
Gibts für gcc irgendwas, womit man einen Debugger-Breakpoint fest
eincodieren kann? Unter der verfluchten Windows 9x-Linie konnte man das
sehr bequem mit asm int 3 machen - zumindest mit den
Nicht-GNU-Compilern.
Uhu Uhuhu schrieb:> Gleich noch eine Randfrage:> Gibts für gcc irgendwas, womit man einen Debugger-Breakpoint fest> eincodieren kann? Unter der verfluchten Windows 9x-Linie konnte man das> sehr bequem mit asm int 3 machen
Auch unter neueren Windows-Versionen geht es z.B. mit CrtDbgBreak() mit
VC++.
Klaus Wachtler schrieb:> Auch unter neueren Windows-Versionen geht es z.B. mit CrtDbgBreak() mit> VC++.
Demgegenüber hatte der int 3 - Trick den Vorteil, daß der Debugger auch
wirklich in meinem Quelltext auf dem int 3 stand. Mit CrtDbgBreak()
findet man sich irgendwo ein paar Etagen tiefer und muß sich dort erst
wieder rauswurschteln.
Soviel ich bisher mit gdb herausgefunden habe, wird aus irgenwelchen
komischen Gründen create nicht aufgerufen, der Port ist also nicht
offen.
Irgendwo ist da der Oberwurm drin...
So etwas herauszufinden geht mit strace einfacher und zuverlässiger als
mit dem gdb.
Z.B. Debian:
apt-get install strace
strace irgendein Kommando....
Abgesehen davon, daß es nicht create heißt, sondern creat, und
vielleicht auch das nicht aufgerufen wird, sondern open (aus OS-Sicht
bzw. in der C-Lib; von ruby rede ich nicht mangels jeglichen Wissens).
Klaus Wachtler schrieb:> Abgesehen davon, daß es nicht create heißt, sondern creat, und> vielleicht auch das nicht aufgerufen wird, sondern open (aus OS-Sicht> bzw. in der C-Lib; von ruby rede ich nicht mangels jeglichen Wissens).
Der Quelltext gibt das nicht her. Dort heißt die betreffende Routine
sp_create, ein Berakpoint darauf triggert nicht und ein Kommentar
darüber sagt:
1
/*
2
* :nodoc: This method is private and will be called by SerialPort#new or SerialPort#open.
3
*/
Die Modul-Initialisierung Init_serialport kann ich per GDB fangen. Ich
werde mal versuchen, nach der Initialisierung weiter zu debuggen...
strace ergibt zwar 1,3 MB Daten, aber auch keine andere Erkenntnis.
/dev/tty* kommt darin nicht vor.
Ich bin der Ursache des Problems ein Stückchen näher gekommen:
SerialPort.new ruft nicht SerialPort#create, (die ist in ruby definiert)
sondern gleich IO#create.
Letztere akzeptiert nur eine File-Nummer als ersten Parameter.
Im Moment weiß ich leider noch nicht, wie das passieren kann. Er scheint
aus irgend welchen komischen Gründen serialport.rb zu ignorieren.
Vorher muß ich aber erst mal mein Ruby-System wieder flott kriegen. Ich
hatte mir den Quellbaum von Github geholt, 1.8.7 ausgecheckt und
installiert, nachdem ich das Ruby von Ubuntu im Paketmanager
deinstalliert hatte.
Seither scheitert Ruby schon an require 'rubygems' und require 'tk'.
Weiß der Henker, was da verbogen ist.
So, ich habs unter Ubuntu zum Laufen bekommen, und zwar so:
- SerialPort gemaket, wie es in der README beschrieben ist
- require '<vollständiger pfad zu serialport.so (das so kann man
weglassen)
- Die Definition von class SerialPort aus lib/serialport.rb in meinen
Quelltext kopieren.
Es ist mir bisher noch nicht gelungen, Ruby dazu zu bewegen, den
.rb-Text automatisch per require, oder include in mein Programm
hinein zu bekommen.
Irgend was muß da an der Extension faul sein. Ich habe noch nicht
versucht, das Teil unter Windows zu installieren - vielleicht gehts ja
dort...
Hallo,
ich setze ruby-serialport schon eine Zeitlang unter Debian und Ubuntu
ein
und hatte bisher keine großen Probleme.
Anbei ein Schnipsel von der Initialisierung der "seriellen"
Schnittstelle.
===== SCHNIPP =====
require 'serialport'
require 'thread'
require 'io/nonblock'
@device = "/dev/ttyUSB0"
@baudrate = 9600
@port = SerialPort.new( @device, @baudrate, 8, 1, SerialPort::NONE)
@port.nonblock = true
@port.sync = true
@port.flow_control = SerialPort::SOFT
===== SCHNAPP =====
Einzig der Wechsel von Ruby1.8 auf Ruby1.9 war nicht ganz
unproblematisch, dort hat sich die Schnittstelle ein wenig geändert.
Gruss
Micha
Wo und wie hast du das Teil gezogen?
Das was ich mir von github heruntergeladen habe, scheint im Quelltext
schon für 1.9 modifiziert zu sein. Ich benutze es aber mit 1.8.7
Hallo,
> Wo und wie hast du das Teil gezogen?>> Das was ich mir von github heruntergeladen habe, scheint im Quelltext> schon für 1.9 modifiziert zu sein. Ich benutze es aber mit 1.8.7
für Ruby 1.8 habe ich einfach das angebotene Paket direkt von
Debian/Ubuntu installiert. Für Ruby 1.9 habe ich das Paket aus den
Debian/Ubuntu-Quellen selbst erstellt. Beide Pakete basieren noch auf
der Version 0.7.0 von ruby-serialport.
Bei Ruby 1.8.7 sollte eigentlich das von Debian/Ubuntu angebotene Paket
tun.
Gruss
Micha
Das, was ich hier habe, hat die Version 1.0.4
Nachtrag:
Na super, bei Ubuntu heißt das Paket libserialport-ruby. Ich hab immer
brav nach ruby-serialport gesucht...
Danke für den Hinweis.
2. Nachtrag:
Mit libserialport-ruby bekomme ich wieder den alten Fehler, daß er als
ersten Parameter keinen String akzeptieren will - warum er die
class-Definition nicht findet, wenn ich sie nicht im eigenen Quelltext
habe, bleibt rätselhaft.
Mittlerweile habe ich serialport.rb in das Verzeichnis kopiert, in dem
nach der Installation des Ubuntu-Paketes serialport.so liegt und in
meinem Quelltext das require-Statement nach
require 'serialport'
geändert. Nun gehts, denn das require 'serialport.so' steht in der .rb
und lädt so die Extension. Sieht also erst mal so aus, als sei da im
Installationspaket irgendwas nicht so, wie es sein sollte.