I am running node.js on a raspberry pi 3 (debian).
I have a little prototype project which gathers data from an ANT+ transmitter on my turbo trainer, which is being sent via a Suunto Movestick USB dongle.
I am using the Ant-Plus
node module to manage the ANT+ protocol and a script which outputs the data to the console and sends via REST API to cloud storage.
Anyhow, cutting to the chase, it was all working fine, multiple process start and stops with no problems, until I inadvertently killed the process by hitting ctrl + z
instead of ctrl + c
Now I just get the following error, when trying to run my script:
/home/pi/ant-plus/node_modules/usb/usb.js:168 this.device.__claimInterface(this.id) ^
Error: LIBUSB_ERROR_BUSY
at Error (native)
at Interface.claim (/home/pi/ant-plus/node_modules/usb/usb.js:168:14)
at GarminStick2.USBDriver.open (/home/pi/ant-plus/build/ant.js:287:20)
at Object.<anonymous> (/home/pi/ant-plus/sample/cadence-sensor.js:39:12)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Function.Module.runMain (module.js:441:10)
at startup (node.js:139:18)
It would appear, having searched around, that due to the node process not being shut down gracefully, that some process is still connected to the USB.
I have tried all sorts of ways to kill the process:
ps | grep <something>
kill <somepid>
killall node
Somehow though, I don't think it's the node process I need to kill, I "feel" like I need to somehow clean the USB interface, but I don't have a clue how I would do that.
The project uses the node-usb library, but I'm not sure if can use that in some way to clean things up.
I did some research into this: The reason is that the Raspberry Pi
attaches a kernel driver to connected devices. You need to check for a kernel driver and detach it before claiming the interface.
Seeing as you are using node-usb
, here is some pseudo code:
device.open()
const deviceInterface = device.interfaces[0]
let driverAttached = false
if (printerInterface.isKernelDriverActive()) {
driverAttached = true
deviceInterface.detachKernelDriver()
}
deviceInterface.claim()
// ... use the device interface
deviceInterface.release(() => {
if (driverAttached) {
deviceInterface.attachKernelDriver()
}
device.close()
})