• This regards the new function that I added to the AT24 module (not available on the site yet), to read strings out of an eeprom without running out of memory.

    Here's the code:

    EEPROM.prototype.reads= function(add,bytes,i2ca) {
    	i2ca = (i2ca==undefined) ? this.i2ca : i2ca;
    	if (add+bytes>this.cap-1) {
    		return;
    	}
    	if (i2ca==this.i2ca) {
    		this.ca=add+bytes;
    	}
    	this.i2c.writeTo(0x50|i2ca,[add>>8&0xff,­add&0xff]);
    	var outval="";
    	while (bytes > 0) {
    		var b=64;
    		if (bytes >= 64) {
    			bytes-=64;
    		} else {
    			b=bytes;
    			bytes=0;
    		}
    		outval=outval+this.arrayToString(this.i2­c.readFrom(0x50|i2ca,b));
    	}
    	return outval;
    };
    

    It works fine with lengths up to around 3500 bytes - but after that, it crashes the espruino. I don't know what's going on internally that's killing it, and the exact limit seems to be effected by the other code around it (WTF?!), but this is a real issue for me.

    When it hangs, the busyIndicator stays lit, and I need to hit the reset button to restore responsiveness.

    That reads() function, of course, is to deal with the fact that there is no way to get a memory-efficient output from I2C.readFrom() (personally, I think I2C.readFrom should take an object as second argument, which could have property 'as', with options like "string" and "Uint8Array", ex: I2C.readFrom(100,{as:"string"}); )

    I have no idea what could be causing this crash, and I don't really know how to proceed to debug it... I mean, it's my code that's causing the crash, but I have no idea why code that is sound at 3000 bytes is not sound at 4000 bytes.

  • That is strange... It does all look fine... Can you still get it to crash if you remove the I2C code? For instance by just using an array instead of i2c.readFrom? And if you add console.log statements, where does it actually hang?

    While I'd like to fix this properly, one way around it might be to pre-allocate all the data you need in a Uint8Array - or do you specifically need a string? The following should work...

    var outval = new Uint8Array(bytes);
    var offset = 0;
    while (bytes > 0) {
            var b=64;
            if (bytes >= 64) {
                bytes-=64;
            } else {
                b=bytes;
                bytes=0;
            }
            outval.set(this.i2c.readFrom(0x50|i2ca,b­), offset);
            offset += b;
        }
    

    The return type could be handy - however trying to do a 3500 byte I2C read in one go may fail anyway, because IIRC I2C data is stored on the stack before being put into an array and there may well not be 3500 bytes of free stack space available...

  • It needs to be a string - this is code that's going to get executed.

  • WOOHOO!

    Problem does not reproduce in release version of v62!

  • Great! I wonder what that was then... There were some assert fails that I fixed, but none related to anything like that (I thought!) :)

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

AT24 module reads() method hangs Espruino for large reads!

Posted by Avatar for DrAzzy @DrAzzy

Actions