AVR PROGMEM is such a HACK!
It really makes we want to leave AVR behind for micro-controllers with better architectures....
Like ARM and PIC32.
Currently the Teensyduino for Teensy3 has some AVR progmem compatibility macros
in hardware/teensy/cores/teensy3/avr/pgmspace.h
that allow compiling AVR code that used PROGMEM on teensy3
Depending on how people declared their data, it may end up putting the data in RAM
vs in the flash.
People are sloppy about whether they use "const" on progmem data/variables
because it didn't' matter on AVR since the AVR pgmspace.h used PROGMEM to put the data
into a section that got linked into flash.
The issue with Teensy3 is that the compatibility file avr/pgmspace.h
file changes PROGMEM to nothing.
While that makes the code compile, there is an issue with that.
When users don't explicitly use "const" on their PROGMEM data/variables, the variable data
ends up in RAM vs flash because initialized variables end up in
section .data which ends up being linked into region 'RAM'.
I ran into this issue on the openGLCD code as I was adding teensy3 support.
It was not immediately obvious since there is so much more RAM on Teensy3 than the AVR chips,
but eventually if there is enough progmem data, you get a RAM overflow error from the linker.
Of course I can fix my library code,
but I've seen lots of user code floating around out there that doesn't use const when using PROGMEM.
If you look at the Arduino progmem page:
http://arduino.cc/en/Reference/PROGMEM
it uses lots of prog_xxx typedefs but none of the examples use const, so arduino progmem users
will not use const, if they go by those examples.
This will cause all their PROGMEM data to end up in RAM instead of flash
when the code is compiled for Teensy3.
The fonts and bitmaps shipped with the openGLCD library can be fixed but it's
more difficult to get all the other generation tools fixed.
Because of this, users may have applications that work on AVR
that won't work on the ARM because the RAM gets blown out.
I think this issue will need to be resolved anyway since it isn't an issue just related
to the openGLCD library. It is a generic Teensy3 PROGMEM issue.
The real solution is make PROGMEM on teensy3 work the way it worked on AVR.
(put the variable data into a section that gets linked into flash)
For the time being I am using this definition for PROGMEM:
#define PROGMEM __attribute__((section(".rodata")))
I'm not sure what the ARM linker script does but from reading about sections for the ARM,
.rodata seems to be the section name for read only data.
The above definition seems to put the data into the flash when const is not used.
however, it does create a warning:
420: Warning: setting incorrect section attributes for .rodata
So it isn't really a proper solution.
I haven't dug any deeper to find a proper solution.
I'm sure it is trivial, I just don't know much about gcc sections or linker scripts.
--- bill
It really makes we want to leave AVR behind for micro-controllers with better architectures....
Like ARM and PIC32.
Currently the Teensyduino for Teensy3 has some AVR progmem compatibility macros
in hardware/teensy/cores/teensy3/avr/pgmspace.h
that allow compiling AVR code that used PROGMEM on teensy3
Depending on how people declared their data, it may end up putting the data in RAM
vs in the flash.
People are sloppy about whether they use "const" on progmem data/variables
because it didn't' matter on AVR since the AVR pgmspace.h used PROGMEM to put the data
into a section that got linked into flash.
The issue with Teensy3 is that the compatibility file avr/pgmspace.h
file changes PROGMEM to nothing.
While that makes the code compile, there is an issue with that.
When users don't explicitly use "const" on their PROGMEM data/variables, the variable data
ends up in RAM vs flash because initialized variables end up in
section .data which ends up being linked into region 'RAM'.
I ran into this issue on the openGLCD code as I was adding teensy3 support.
It was not immediately obvious since there is so much more RAM on Teensy3 than the AVR chips,
but eventually if there is enough progmem data, you get a RAM overflow error from the linker.
Of course I can fix my library code,
but I've seen lots of user code floating around out there that doesn't use const when using PROGMEM.
If you look at the Arduino progmem page:
http://arduino.cc/en/Reference/PROGMEM
it uses lots of prog_xxx typedefs but none of the examples use const, so arduino progmem users
will not use const, if they go by those examples.
This will cause all their PROGMEM data to end up in RAM instead of flash
when the code is compiled for Teensy3.
The fonts and bitmaps shipped with the openGLCD library can be fixed but it's
more difficult to get all the other generation tools fixed.
Because of this, users may have applications that work on AVR
that won't work on the ARM because the RAM gets blown out.
I think this issue will need to be resolved anyway since it isn't an issue just related
to the openGLCD library. It is a generic Teensy3 PROGMEM issue.
The real solution is make PROGMEM on teensy3 work the way it worked on AVR.
(put the variable data into a section that gets linked into flash)
For the time being I am using this definition for PROGMEM:
#define PROGMEM __attribute__((section(".rodata")))
I'm not sure what the ARM linker script does but from reading about sections for the ARM,
.rodata seems to be the section name for read only data.
The above definition seems to put the data into the flash when const is not used.
however, it does create a warning:
420: Warning: setting incorrect section attributes for .rodata
So it isn't really a proper solution.
I haven't dug any deeper to find a proper solution.
I'm sure it is trivial, I just don't know much about gcc sections or linker scripts.
--- bill
Last edited: