The Atmel AVR CPUs that are used in the Arduino boards aren't the familiar Von Neumann architecture machines we are all familiar with, where there is a "flat" address space that's shared between both code and data. Instead they are Harvard Architecture, where there's separate address spaces for code and data, i.e. there are two "address 0"s. In fact on the AVR there are three address 0's, one for code (Flash), one for data (SRAM) and one for non-volatile memory (EEPROM). There's also a very restricted amount of SRAM - usually less than 2K. That means that if you want to store lots of data (in my case, LED strip patterns) you need to store it in program memory (Flash) and access it with special instructions. Data is put into program memory by tagging the variable definition with the
PROGMEM macro, e.g.
static const char message PROGMEM = "Hello world";
However, there's a long-standing gcc bug that results in a warning from GCC when warnings are enabled:
error: only initialized variables can be placed into program memory area. I don't particularly want to compile with all the warnings disabled, and it turns out there's a relatively simple workaround:
// Workaround for http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34734 #undef PROGMEM #define PROGMEM __attribute__((section(".progmem.data")))
PROGMEM macro expands to
__attribute__((__progmem__)), and from looking at the GCC source, the
__progmen__ attribute puts the variable that it has been used to tag in the
.progmem.data section so the above should be directly equivalent, and it certainly works fine for me.