arduino / ArduinoCore-avr

The Official Arduino AVR core
https://www.arduino.cc
1.22k stars 1.05k forks source link

64k problems: trampolines pushed past 64k boundry... #175

Open WestfW opened 10 years ago

WestfW commented 10 years ago

The .trampolines section is supposed to get located in the first 64k of memory, but the normal linker scripts put the section AFTER the .progmem sections, so if there is more than (about) 64 of user-defined pgmspace data, they will cease to operate properly.

This might be fixed by changing the linker scripts.

This might be fixed or different in the new avr-gcc toolchain included with the Arduino IDE 1.5.7 and later.

matthijskooijman commented 10 years ago

This sounds like it should really be fixed in upstream gcc, right? Do you know if there is a bugreport for gcc already?

matthijskooijman commented 10 years ago

Do you happen to have a test sketch that displays this problem? If so, I can see if it is still broken with the latest toolchain.

WestfW commented 10 years ago

Yes, this would be an upstream problem in gcc itself. But I'm trying to collect all the reasons that large programs might not work on MEGA/etc and document them here as well.

WestfW commented 10 years ago

(This does appear to be fixed in 4.8.1; but it doesn't look like trampolines work at all in 4.3.3. Here's a test .c program. Compile it with avr-gcc -mmcu=atmega2560 -mrelax -Wl,--relax test64k.c

#include <avr/io.h>
#include <avr/pgmspace.h>
#include <stdint.h>

#define string64  "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
#define string256 string64 string64 string64 string64 
#define string1k string256 string256 string256 string256 
#define string4k string1k string1k string1k string1k
#define string16k string4k string4k string4k string4k
#define string32k string16k string16k

const char PROGMEM bigstring[] = string16k;  //  Put a big string in pgmspace.
#if FLASHEND > 0x10000
  //  More than 64kbytes flash?
const char PROGMEM reallybigstring[] = string32k, morestring[] = string32k;
#endif
#if FLASHEND > 0x20000
// more than 128kbytes flash?
const char PROGMEM pass128k_a[] = string32k, pass128k_b[] = string32k;
#endif

uint8_t (*myportread)();
uint8_t read_c() {
  return PORTC;
}
uint8_t read_d() {
  return PORTD;
}

// the loop routine runs over and over again forever:
int main() {
  if (PORTE & 0x10) {
    myportread = read_c;
  } 
  else {
    myportread = read_d;
  }
  if ((*myportread)() > 100) {
      PORTE |= 0x80;;   // turn the LED on (HIGH is the voltage level)
  } 
  else {
      PORTE &= ~0x80;
  }
}
JohnOH commented 6 years ago

Is there any news on this @cmaglie ?

cmaglie commented 6 years ago

@JohnOH are you experiencing the issue with the latest IDE?

Since IDE 1.5.7 we updated avr-gcc many times, it would be nice if @WestfW or someone may check if this has been fixed upstream in the meantime...

JohnOH commented 6 years ago

I have not yet built the hardware. I was hoping to establish that the software issues had been addressed before investing time in the new hardware.