arduino / arduino/ArduinoCore-avr

Casting pgm_read_byte_far address to 16-bit breaks printing strings from program memory for the stk500v2 bootloader

Open
#173 2 comments 0 reactions 1 assignee Claimed by @cmaglie View on GitHub
bug
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.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.