pgm_read_byte()
Abstract
The pgm_read_byte()
is a macro that reads a byte of data stored in a specified address(PROGMEM area).
Source Code
The pgm_read_byte()
is defined in hardware/tools/avr/avr/include/avr/pgmspace.h
as below.
#define pgm_read_byte(address_short) pgm_read_byte_near(address_short)
The input is address_short
and calls the pgm_read_byte_near()
macro.
pgm_read_byte_near()
Abstract
The pgm_read_byte_near()
is a macro that reads a byte of data stored in a specified address(PROGMEM area).
Source Code
The pgm_read_byte_near()
is defined in hardware/tools/avr/avr/include/avr/pgmspace.h
as below.
#define pgm_read_byte_near(address_short) __LPM((uint16_t)(address_short))
The input is address_short
and the macro converts the address_short
to uint16_t
, then calls __LPM()
macro.
__LPM()
Abstract
The __LPM()
is a macro that reads a byte of data stored in a specified address(PROGMEM area).
Source Code
The __LPM()
is defined in hardware/tools/avr/avr/include/avr/pgmspace.h
as below.
#define __LPM(addr) __LPM_enhanced__(addr)
The input is addr
and just calls __LPM_enhanced__()
.
See Intrinsic Functions
__LPM_enhanced__()
Abstract
The __LPM_enhanced()
is an assembler code that reads a byte of data stored in a specified address(PROGMEM area).
Source Code
The __LPM_enhanced()
is defined in hardware/tools/avr/avr/include/avr/pgmspace.h
as below.
#define __LPM_enhanced__(addr) \
(__extension__({ \
uint16_t __addr16 = (uint16_t)(addr); \
uint8_t __result; \
__asm__ \
( \
"lpm %0, Z" "\n\t" \
: "=r" (__result) \
: "z" (__addr16) \
); \
__result; \
}))
or newer avr-libc
#define __LPM_classic__(addr) \
(__extension__({ \
uint16_t __addr16 = (uint16_t)(addr); \
uint8_t __result; \
__asm__ \
( \
"lpm" "\n\t" \
"mov %0, r0" "\n\t" \
: "=r" (__result) \
: "z" (__addr16) \
: "r0" \
); \
__result; \
}))
The lpm
, short for Load Program Memory, is a instruction that reads a byte of data from PROGMEM area. It substitue a data at addr
for __result
, then returns the __result
.
Sources:
pgm_read_byte() marco
pgm_read_byte_near() marco
__LPM() marco
__LPM_enhanced__() marco