kelly / node-i2c

Node.js native bindings for i2c-dev. Plays well with Raspberry Pi and Beaglebone.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Signal pipe overflow

discreetmayor opened this issue · comments

Not sure you can do anything about this, but using readBytes() in a loop (even with a timeout) will eventually result in a signal pipe overflow.

In versions of node prior to 0.10.8, this will result in an unexplained crash because of a bug in node.js itself (fixed here joyent/libuv@c5d570d).

But the fact remains that the signal pipe can overflow. My test code is essentially something like:

function read() {
wire.readBytes( someAddress, someLength, function( err, res ) {
console.log( err );
console.log( res );
setTimeout( read, 25 );
} );
}

so I'm even waiting for a successful read before reading again.

Also, the code for i2c doesn't compile on the latest node.js version (0.11.4)

Have you tried extending the timeout to a duration a little longer, like 100ms? I'll look into why it doesn't compile on 0.11.4. Thanks!

Hi there,

yeah, I actually had a fairly long timeout (that's the first thing I tested when I got the unexpected crashes prior to 0.10.8) during a series of tests.

Right now, what looks to be happening post 0.10.8 is after a signal pipe overflow (no longer crashes), CPU spikes to almost 100% from the ~8% it normally uses on my RPi with the 25ms timeout.

Here's something you can (almost) run. This is test code for sparkfun's mpr121 breakout board (default address). I suspect any i2c device with this code will eventually get the overflow, and subsequent crash.

var i2c = require('i2c');
var mpr121 = new i2c(0x5a,{device:'/dev/i2c-1'});

//uncomment to get 100% cpu usage instead of a crash!
/*
process.on( 'SIGSEGV', function() {
});
*/

test();

function test() {
mpr121.readBytes(0x5a,2,function(err,res) {
//console.log( res );
setTimeout( test, 1 ); //speed up time it takes to get sig pipe overflow
});
}

Thank you discreetmayor. Your example on how not to crash has helped me in my code working around this same problem.

It was a real odd one for me. My reading was via a MCP23017 GPIO expander and then I put a MAX31855 off of the GPIO expander. So I was intermixing reads and writes, but had to read 32 times to get a single result out of the MAX31855. So sometimes I could trigger the segfault after as low as a few iterations of reading that chip, and sometimes it would go a few thousand before triggering.

I'm still a very noob at the node environment, so thank you for the pointer here.

@critch : given that nothing has been changed in this library, I have since worked around by using an interrupt instead of polling. If your device can trigger an interrupt, the node.js onoff library handles it very nicely. This allows you to only read using this i2c library once, when necessary.

Feedback welcome at:
#97