arduino / arduino/ArduinoCore-avr
Casting pgm_read_byte_far address to 16-bit breaks printing strings from program memory for the stk500v2 bootloader
- Dominant language
- C
- Stars
- 1.5k
- Forks
- 1.1k
- PR merge metrics
- No merged PRs in 30d
Description
Hi @cmaglie, your changes to `stk500v2.c` in https://github.com/arduino/Arduino/commit/06ee62afc66e9917b3dc38bcf496de0e1a3d7d7d breaks the monitor as casting the PROGMEM strings such as `gTextMsg_Explorer` in devices with more than 64 kB of flash to `uint16_t`, causes the upper bits which are supposed to go into the `ZRAMP` register to go to zero, incorrectly addressing the application space instead of bootloader space.
I have verified all this in assembly, and resolved the issue by reverting this cast back to a `uint32_t`. `RunMonitor` now prints the strings correctly on the ATmega2560.
@cmaglie, @damellis, @zeveland: Please advise me how you want to proceed. I am using a cleanly built GCC version 4.8.2 with AVRLIBC 1.8.0.
The following doxygen comments from the macros confirm that `pgm_read_byte_far` should always take a 32 bit address. `pgm_read_byte_near` is more efficient but doesn't support 32 bit addressing.
```c
/** \ingroup avr_pgmspace
\def pgm_read_byte(address_short)
Read a byte from the program space with a 16-bit (near) address.
\note The address is a byte address.
The address is in the program space. */
#define pgm_read_byte(address_short) pgm_read_byte_near(address_short)
```
```c
/** \ingroup avr_pgmspace
\def pgm_read_byte_far(address_long)
Read a byte from the program space with a 32-bit (far) address.
\note The address is a byte address.
The address is in the program space. */
#define pgm_read_byte_far(address_long) __ELPM((uint32_t)(address_long))
```
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.