phidgets-ffi
phidgets-ffi copied to clipboard
Crash with multiple Phidgets
Hi there
Awesome Phidgets is available with Ruby now! I wanted to port some of my Java code to Ruby but ran into a problem:
When I attache more than one Phidget to my machine. The following code crashes:
require 'rubygems'
require 'phidgets-ffi'
manager = Phidgets::Manager.new
manager.devices.each do |device|
puts Phidgets::Common.name(device)
end
Could we fix this or do I have to change my program structure? I'd love to help.
Thanks again
Here is a log:
Phidget Advanced Servo Controller 8-motor
/Users/jml/.rvm/gems/ruby-1.9.2-p136/gems/phidgets-ffi-0.1.0/lib/phidgets-ffi/ffi/common.rb:58: [BUG] Segmentation fault
ruby 1.9.2p136 (2010-12-25 revision 30365) [x86_64-darwin10.6.0]
-- control frame ----------
c:0010 p:---- s:0036 b:0036 l:000035 d:000035 CFUNC :CPhidget_getDeviceName
c:0009 p:0076 s:0031 b:0031 l:000030 d:000030 METHOD /Users/jml/.rvm/gems/ruby-1.9.2-p136/gems/phidgets-ffi-0.1.0/lib/phidgets-ffi/ffi/common.rb:58
c:0008 p:---- s:0024 b:0024 l:000023 d:000023 FINISH
c:0007 p:0049 s:0022 b:0022 l:000021 d:000021 METHOD /Users/jml/.rvm/gems/ruby-1.9.2-p136/gems/phidgets-ffi-0.1.0/lib/phidgets-ffi/common.rb:507
c:0006 p:0021 s:0016 b:0015 l:0017e8 d:000014 BLOCK bug.rb:7
c:0005 p:---- s:0012 b:0012 l:000011 d:000011 FINISH
c:0004 p:---- s:0010 b:0010 l:000009 d:000009 CFUNC :each
c:0003 p:0061 s:0007 b:0007 l:0017e8 d:000f60 EVAL bug.rb:6
c:0002 p:---- s:0004 b:0004 l:000003 d:000003 FINISH
c:0001 p:0000 s:0002 b:0002 l:0017e8 d:0017e8 TOP
---------------------------
-- Ruby level backtrace information ----------------------------------------
bug.rb:6:in `<main>'
bug.rb:6:in `each'
bug.rb:7:in `block in <main>'
/Users/jml/.rvm/gems/ruby-1.9.2-p136/gems/phidgets-ffi-0.1.0/lib/phidgets-ffi/common.rb:507:in `name'
/Users/jml/.rvm/gems/ruby-1.9.2-p136/gems/phidgets-ffi-0.1.0/lib/phidgets-ffi/ffi/common.rb:58:in `method_missing'
/Users/jml/.rvm/gems/ruby-1.9.2-p136/gems/phidgets-ffi-0.1.0/lib/phidgets-ffi/ffi/common.rb:58:in `CPhidget_getDeviceName'
-- C level backtrace information -------------------------------------------
[NOTE]
You may have encountered a bug in the Ruby interpreter or extension libraries.
Bug reports are welcome.
For details: http://www.ruby-lang.org/bugreport.html
Abort trap: 6
I have verified that that code works on my Mac OS X, even with multiple Phidgets attached.
I am not sure why it doesn't work on your system. The problem seems to be caused by the /lib/phidgets-ffi/manager.rb
https://github.com/kreynolds/phidgets-ffi/blob/master/lib/phidgets-ffi/manager.rb
The line that seems to be triggering the error is line 92.
def devices
devices_ptr, count = ::FFI::MemoryPointer.new(:pointer, 300), ::FFI::MemoryPointer.new(:int)
Klass.getAttachedDevices(@handle, devices_ptr, count)
devices = devices_ptr.get_array_of_pointer(0, count.get_int(0))
device_array = []
count.get_int(0).times do |i|
device_array[i] = devices[0].get_pointer(i*Phidgets::FFI::FFI_POINTER_SIZE)
end
device_array
end
On Mac OS X, the Phidgets::FFI::FFI_POINTER_SIZE is 4. But on Linux systems, it is 8. Perhaps, you can try changing this number to 8, and see if it resolves the issue?
device_array[i] = devices[0].get_pointer(i*8)
I don't have multiple phidgets available to me at the moment but that function looks like it should be quite different ... what happens if you try something more like (possibly uncommented the free line, not sure what that's about):
def devices
devices_ptr, count = ::FFI::MemoryPointer.new(:pointer, 300), ::FFI::MemoryPointer.new(:int)
Klass.getAttachedDevices(@handle, devices_ptr, count)
device_array = devices_ptr.get_array_of_pointer(0, count.get_int(0)).map { |device|
device.get_pointer(Phidgets::FFI::FFI_POINTER_SIZE)
}
Klass.freeAttachedDevicesArray(devices_ptr)
device_array
end
For anyone who reaches this thread who is having the same problems with a large number of devices on your system - consider using the phidgets_native gem. It supports the accelerometer, is much faster, stable, and supports arm architectures (in case you intend to deploy onto a raspberry pi)