Skip to content

Fix #2226 for boards that have >64K of PROGMEM available #6317

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

geez0x1
Copy link

@geez0x1 geez0x1 commented May 23, 2017

Defined GCCPROGMEM for boards with ATmega 1280 and 2560 that have >64K of PROGMEM available, to fix arduino/ArduinoCore-avr#174

@mastrolinux mastrolinux added the in progress Work on this item is in progress label May 23, 2017
@geez0x1 geez0x1 changed the title Fix #2226 for that have >64K of PROGMEM available Fix #2226 for boards that have >64K of PROGMEM available May 23, 2017
@geez0x1
Copy link
Author

geez0x1 commented Nov 1, 2017

Any progress on getting this merged?

@matthijskooijman
Copy link
Collaborator

I'm not so sure if this is really a proper fix for this issue. Because:

  • Hardcoding section names relies on specifics of the linker script, which isn't really pretty (using PROGMEM bypasses this since that is a macro interface offered by avr-libc).
  • This gcc section sounds internal to gcc, not sure if it's a good idea to use that one (though it probably works, of course).
  • To really fix this, all PROGMEM variables that are not accessed using the _far functions should be converted to GCCPROGMEM, I think (in the core, but also libraries), while this approach only fixes some.

I guess that the problem is that PROGMEM does not guarantee anything about near/far. I believe that means there would be two proper solutions:

  • Convert all PROGMEM access to use _far functions, since that's the only way that's guaranteed to work with all PROGMEM variables. This has a performance impact, so it's not favorable (unless LTO can manage to optimize this, but I don't expect it will).
  • Add a PROGMEM_FAR or something like that, for variables that are ok with ending up in the far area and will be accessed using the _far functions. In practice, this means PROGMEM variables are sorted before PROGMEM_FAR variables. This also means that PROGMEM variables are guaranteed to be in the near area (provided that they all fit in the near area, of course) and can be safely accessed without the _far accessors. This is a change that needs to happen in avr-libc, since it requires changing avr-libc.

Neither of these approaches are really practical right now, unfortunately.

@facchinm facchinm added the Architecture: AVR Applies only to the AVR microcontrollers (Uno, etc.) label Nov 13, 2017
@geez0x1
Copy link
Author

geez0x1 commented Nov 17, 2017

@matthijskooijman: Thanks for the write-up. That indeed sounds reasonable, although this is probably the most common case. Perhaps a good middle ground solution (until this gets fixed properly) would be to at least update the Arduino PROGMEM documentation to make clear note of this, since the symptoms are quite puzzling indeed.

@themobydisk
Copy link

I agree that using the _far functions is undesirable because the performance change might break existing code.

Some alternatives:

  • Support a #define named USE_FAR_ACCESS or SUPPORT_64K_FLASH. When set, this would cause the library to use the _far functions. This keeps the existing code, but allows developers to enable the slower functions. I'm not sure how to code that though.
  • Add a macro that produces an error or warning if the address has moved beyond the first 64k, so at least the developer gets a compiler error.

Realistically though, while the proposed GCCPROGMEM approach is inelegant, it is better than leaving the Arduino Mega broken. The Arduino foundation to advertises and sells a device with 256k of Flash but only 64k of it is accessible. If we don't fix this, is their a workaround?

@geez0x1
Copy link
Author

geez0x1 commented Dec 3, 2018

Since after 1.5 years nobody has fixed this properly I would like to echo @themobydisk in that an (this) inelegant fix is better than no fix, for an issue that completely(?) undoes the RAM benefits of the Mega.

@themobydisk
Copy link

I manually applied the patch and I confirm that pinMode() and digitalWrite() now work. I meant to test Tone() this weekend, I'll do that and post the results.

@themobydisk
Copy link

I confirm that tone() also works. I still use this PR by merging it in manually whenever I need to use an Arduino Mega.

@geez0x1
Copy link
Author

geez0x1 commented May 17, 2020

Happy to see this PR was at least of some use ;)

@mastrolinux since we're now 3 years on, and over 5.5 years beyond the original bug #2226; perhaps it is worthwhile merging this (kind of) solution? Even though it may not be the 'best' solution, having basic functionality broken cannot possibly be better.

@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@zzqzzqzzq
Copy link

(As a work around for anyone who manages to find this in the future.)

I stumbled across this problem while trying to stick a 150K binary blob (an image of course) into PROGMEM, on a Mega2560.

While the patch works as far as it goes, (eg: pins & ports variables) I was still running into the problem with other assorted PROGMEM variables stored in sundry libraries.

So, I cheated and moved the blob into the text section, and not progmem. I don't claim to be a GCC/ARM/LD Linker Script/Arduino expert, but my object creation now doesn't conflict, with "just about everything else".

eg: I use this to convert a binary blob into an object module.
avr-objcopy -I binary -O elf32-avr -B avr:6 --rename-section .data=.text.image_data image_data.bin image_data.o

I believe a similar '#define FARPROGMEM attribute((section(".text.image_data")))' would work in header files (but must admit I've not tried it.)

Hope this helps someone in the future, it was driving me buggy....

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Architecture: AVR Applies only to the AVR microcontrollers (Uno, etc.) in progress Work on this item is in progress
Projects
None yet
Development

Successfully merging this pull request may close these issues.

64K problems: pins_arduino.h _PGM arrays pushed out of range of pgm_read_byte()
7 participants