-
-
Notifications
You must be signed in to change notification settings - Fork 1k
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
64K problems: pins_arduino.h _PGM arrays pushed out of range of pgm_read_byte() #174
Comments
(Um. Can I not attach source and diff files to an issue?) |
Probably not - I guess you could open a pullrequest, or include the diff in a comment (indent it by for spacs or put ``` before and after it to make it display as code). As for the fix you suggest, I'm wondering why it works. AFAIU, any new sections introduced have to be manually listed in the linker script? Though perhaps due to |
The linker script already has |
Grr. Removed them again. cursed markdown language! |
It seems that github/markdown is interpreting your asterisks as meaning italic text. You can probably escape them with *, or quite with `. Thanks for clarifying, I can see why your fix works. I'm wondering if "arduinocore" is the best approach though - it sorts low, but if a user declares a big "aa" PROGMEM variable, things still break. I'm not sure what the rules for section names are, but if they're the same as variable names (start with a latter, contain letters, numbers and underscores IIRC), something like |
|
I'm pretty sure that the |
Oh, right. I was assuming that variables would get Not sure I like the "MYPROGMEM" name though. Wouldn't GCCPROGMEM be better? In either case, there should be a fat comment explaining why this is needed and why this works :-) |
You must also modify these lines in Arduino.h to make it work
|
Today we spent most of the day debugging why our Arduino immediately crashed when increasing data use in PROGMEM, even when that data was not being used. Spent ages trying to find problems with 32-bit pointers, etc. What made matters worse is that at some point disabling optimisations (
Turns out the problem was the one mentioned in this thread. Disabling optimisations just resulted in different code which somehow made something work at some point. Very confusing. The patches by WestfW (needs to be done manually though) and oqibidipo appear to completely solve the problem. As of this moment these patches are not implemented in the Arduino mainline code. My Debian packages may be slightly outdated(?), but the other machine is running the (most) recent packages with AVR 1.6.18 etc. Is there any particular reason these patches have not been mainlined? Should we file a pull request? |
Hi, Any update on this? I tested the pull request. It somehow fixed the issue but some strange behaviours came up instead. I am not sure if it was caused by the change or it is from my code! |
Can you be more specific as to what issues you found? |
I have two large arrays as well as a medium array:
|
In your code I don't see any mention of |
I don't think Mega2560 or any other arduino has that much ram available (31200 + 31200 + 14400). gImage_img_header, gImage_img_cs1 and gImage_img_cs2 are defined extern because they are placed into another .c file and I mentioned that I am excluding them because they are just large arrays. To find out how they are defined have a look below: img_header.c
|
Ah, fair point. Can I ask which board you are using? Maybe I missed one (intended to patch only the files for boards that have >64K PGM available). Another possibility is that there's other things that need to be patched as well, since more things are using PROGMEM:
I'm afraid I'm not knowledgeable enough on this, though. |
I am using Mega2560 R3. |
The patch I submitted has patches for mega: |
As an alternative, is there a way I can label my arrays so that they will go after the PROGMEM arrays? Like |
I don't think that "polluting" the gcc space is a significant problem, as long as the amount of PROGMEM used by Arduino is small, and I don't even know offhand what parts of gcc or avr-libc use PROGMEM (but they're also obviously small.) Since Arduino has "matured" to the point of having custom linker scripts (eg for SAMD), a "correct" solution might involve using a linker script that defines arduino's own section of flash, in between the progmem.gcc and the progmem* segments. |
A simple program (say, Blink) that includes more than 64k of pgmspace data (for MEGA, MEGA2560, MEGA ADK, various 1284 boards) will fail to work correctly.
One of the reasons is that Arduino.h includes macro definitions like:
#define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) )
Due to link order, the digital_pin_to_port_PGM[] array will be pushed AFTER the explicitly defined pgmspace variables, and it will no longer be readable by pgm_read_byte.
Using pgm_read_byte_far() seems like overkill.
It turns out that apparently gcc has a similar problem with pgmspace variables that IT uses, because the default linker map includes two entries for progmem data:
This means that MEGA and etc can be fixed by a relative simple patch to their pins_arduino.h file, putting the pin tables in section .progmem.gcc.arduinocore instead of the normal .progmem (as per the attached diff file)
The text was updated successfully, but these errors were encountered: