Fri 20 Nov 2009 10:32:06 AM UTC, original submission:
The pgm_read_xxx() functions in <avr/pgmspace.h> are currently implemented as macros, casting the parameter to (uint16_t).
While the parameter is supposed to be a pointer, this enables to use any garbage (read: non-pointer expression used by error) quietly.
Opposed to this are the similar accessing functions in eeprom.h.
It is therefore suggested, that these macros to be replaced by the following constructions:
// #define pgm_read_byte(address_short) pgm_read_byte_near(address_short)
_attribute_((_always_inline_)) static uint8_t pgm_read_byte(const PROGMEM uint8_t *);
static uint8_t pgm_read_byte(const PROGMEM uint8_t *addr) {
return __LPM((uint16_t)(addr));
}
// #define pgm_read_word(address_short) pgm_read_word_near(address_short)
_attribute_((_always_inline_)) static uint16_t pgm_read_word(const PROGMEM uint16_t *);
static uint16_t pgm_read_word(const PROGMEM uint16_t *addr) {
return __LPM_word((uint16_t)(addr));
}
// #define pgm_read_dword(address_short) pgm_read_dword_near(address_short)
_attribute_((_always_inline_)) static uint32_t pgm_read_dword(const PROGMEM uint32_t *);
static uint32_t pgm_read_dword(const PROGMEM uint32_t *addr) {
return __LPM_dword((uint16_t)(addr));
}
I am not expert enough to judge whether the functions may be tagged also with the _pure_ attribute.
A discussion on the topic is on http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=85490 .
Jan Waclawek
|