ESP8266 EEPROM Address Overflows

So I’ve finally been getting some time into using the ESP8266 chips I bought (variously, and many of) over the past month. I had some serious trouble getting them to work initially, due to a problem which I’ll be explaining in depth on another blog post. Hint: The problem wasn’t what I thought it was (or most people think it is, for that matter.)

This post is about what happens when you try to write a program (larger than 256kB) designed for the 1024kB version of the ESP-01 module to a 512kB version of the ESP-01 module.

This is what happens:

 ets Jan  8 2013,rst cause:1, boot mode:(3,6)

load 0x4010f000, len 1264, room 16 
tail 0
chksum 0x42
csum 0x42
~ld
"@ªrjrA(!‹SËq‹Ðšv›X%.ù+Ðyêeh©."8át.ÍɪNøêI*A¬1‚-...)DЪ.B!ûþA¬!.þNé*E"HHIîA.T[MºöA,T[ͯQá"@ªRjRA(!‹SËu‹ÐšÖ›X%(ý«ÐYêeH).".át.íͪNøêÉ*E¬1‚-.1.©ÄЪ.Â!ûþA¬!.þNé*A"HhiîA.T[MºöA,T[ͯQá

This is what is supposed to happen:

.
 ets Jan  8 2013,rst cause:1, boot mode:(3,7)

load 0x4010f000, len 1264, room 16 
tail 0
chksum 0x42
csum 0x42
~ld
Reset reason: REASON_DEFAULT_RST
Normal, first power-on bootup.
Flash real   id: 001340C8
Flash real size: 524288

Flash IDE  size: 524288
Flash IDE speed: 40000000
Flash IDE  mode: QIO
Flash Chip configuration ok.

Mounting SPIFFS. (Attempt: 00)
Configuration file exists.
Config file size: 118
Created buffer.
Read the config file.
Created DynamicJsonBuffer.
JSON parsed correctly.
gps
1351824120
48.76
2.30

The problem, as far as I can understand it, is that the EEPROM chip is programmed incorrectly. I suspect maybe the addresses are wrapping around somehow, or the SPIFFS area is marked as being too large. In the 1024kB memory map, the 256kB SPIFFS image gets written starting at 0xbb000, which is at the 748kB boundary. But if you try to burn this same image to a 512kB EEPROM chip, I think the addresses wrap around, and overwrite the code you are trying to run, which starts at 0x00000.

Either way, garbage input = garbage output.

The problem is that the problem behaves inconsistently as well, and for novice programmers, it may not be apparent that the cause is not software-based, but hardware-based. Keep in mind, as well, that a minimal firmware that pulls in all of the Arduino code starts at nearly 240kB code size. The only reason I thought more heavily about EEPROM size as a potential source of problems, was that by adding the ArduinoJson library, the final code size started crossing over the 256kB boundary, which was when the garbage output and chip hangs started to happen.

One other note, there’s an example called CheckFlashConfig, located in the esp8266 library examples for Arduino. I would highly recommend people to use this code to check whether you have a flash size mismatch at runtime. The ESP8266 modules don’t have consistent specs, so two ESP-01 modules could have different EEPROM chip sizes, and cause identical code to potentially error out on one of them.

Final note, there seem to be some potential problems with the SPIFFS implementation hanging if it is unable to finish running the SPIFFS.begin() call. I tried using the .begin() in a loop, generating Attempt: xx strings along the way, but the implementation would always hang if it failed to mount the SPIFFS block the first time.

sprintf / snprintf Problem on Arduino.

What a day. Spent the day hunting a bug in my code, only to find out that it wasn’t in my code. (Update: Turns out my code was wrong in two ways, more below the original entry.) (Update 2: There are options to set this in the Arduino IDE Preferences)

There’s an error in the sprintf and snprintf implementation on Arduino that occurs when more than 8 varargs are passed in after the format specifier.

Continue reading sprintf / snprintf Problem on Arduino.

Interview Problem: One LED for Status

So there’s a real-world problem I’ve run into on the Arduino that I realized could be a reasonable interview question. I’ve been thinking through some of the answers. The question goes something like this:

You have an Arduino development board, and you have a state machine that could be in one of sixteen states at any given moment. How would you design a method for indicating the current state to someone looking at the board?

That’s version one of the question. And the person might answer something like:

I’d hook up two seven-segment LEDs to the board to display the status.

But that would chew up 14 pins on an Arduino, which is quite a lot of digital I/O just for status. So the follow-up question could be something like:

Would there be a way to cut the number of seven-segment LED modules you’d need in half?

And after thinking, the answer would come to mind:

Yes, you could use a single seven-segment LED module. Since you’re only displaying a value up to 16, you could display the value as hexadecimal 0 – F, instead.

But let’s constrain the problem further. That’s still 7 pins on an Arduino, which is a mighty waste on the smaller Atmel chips (like on the Arduino Nano).

Would there be a way to cut the number of pins you’d need, to drive the seven-segment display, to a single pin?

And the person might think a bit, and answer something like:

Well, you could use something like a serial-in-parallel-out integrated circuit, like the 74HC595, and some logic in the software, to control the 8-output-pins in a way that generate the values 0 – F.

And that would be another correct answer. But then, let’s say we really want to constrain things.

How about if you wanted to do this with zero external components, just what is on the Arduino board itself, how would you do it?

Keep in mind that most Arduino boards, as long as they follow the reference design, have a controllable LED tied to Pin 13. This would be something an interviewee might or might not know, but at some point you could tell them this, and see what they do with the info.

The idea that’s been forming in my mind, to do this, and I think could be the right answer, is to light the LED in a way that corresponds to one of sixteen values. I considered using on-and-off as two possible binary states, to convey the 0 and 1 bits of a 4-bit value. But then I realized that there’d need to be a way of marking the start boundary of the value. This is an issue you see with all normal serial protocols, RS232 can use 1 or 2 stop bits, if I remember right. Which basically means the protocol waits two bit times, then proceeds with the next byte.

The problem with just using a simple on-off coding is also the question of what happens when multiple identical bit values happen back-to-back. As in, let’s say you wanted to blink the value 11 to the LED, which would be 1011 in binary. The last two bits would smear together, and it would be tricky for a human to tell what the value was. It would look like:

ON-OFF-ON (longer)

Visually, the answer I came up with is to use a short blink (say, 250ms) and a long blink (say, 750ms) to represent 0 and 1. Between blinks, there would be a pause of 50ms or so (or this is up for tweaking, as I haven’t written the system yet). Then there would be a pause of one second, and the sequence would repeat.

It’s nothing too special, but this might be a workable system. The real challenge, then, is how to implement this using just a millisecond timer and a few C functions.