-
Notifications
You must be signed in to change notification settings - Fork 13.3k
PROGMEM/pgm_read cast to "normal" data types #3086
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
Comments
do you have a cast line example? |
Not drilled down to the root, but shows the error on ESP8266 (working fine with UNO): #define LUT(a) (long)(pgm_read_word(&lut[a])) const unsigned int lut[] PROGMEM = { //crash on ESP8266, ok on UNO long SIN(unsigned int angle) { void setup() { void loop() { |
I think that it's the attempt to use Try using |
You are right, the difference on ESP8266 unsigned int is 32bit and uint16_t is 16bit, on ATMega the types are both 16bit. But besides that, is this a correct behaviour of pgm_read_*? Drilled it down and it behaves really strange - there have to be a lot of things present at the same time to let it crash (compiles without any warnings):
|
To be perfectly honest I've not found a use for the That's not to say it's completely useless because it may well work for some scenarios that I'm not aware of..but I can say that I do use PROGMEM for storing an array of application strings in my code and when I was developing this, the only way I managed to get it working successfully was by way of using I believe this is related to the fact that all memory addresses on an ESP device are 32bit addresses regardless of the type of data that is actually stored at that address - in other words |
ESP is only one target in Arduino-world ;-) But that's not the thing, there is IMO a bug and I thought it is worth to publish it. |
its very important if you want to run some existing arduino sketches on ESP |
If it's a sizeof(char *) type problem, do they not encounter it on any
other Arduino targets?
What mode do they run the ARMs in?
…On Thu, Apr 6, 2017 at 11:15 AM, Rui Azevedo ***@***.***> wrote:
its very important if you want to run some existing arduino sketches on ESP
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#3086 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAN_A6ceA4XIyf_oEW9xd8HV0Cy5loMYks5rtCCjgaJpZM4MpPHx>
.
|
doh... |
Ok are Test code:
Output:
|
I hope you know what you are doing: storing 16bit in |
I modified my sketch:
Still no luck... Am I forecd to store and read my |
This seams to be another problem...
|
Swapping
|
I suggest you to open a new issue for that. |
@milkpirate I'm seeing the exact same error you're seeing. I encountered it in an encryption library that utilizes program memory to store a large array. Adding the delay after the pgm_read_byte call fixes the issue (but obviously makes the overall program run much slower. It seems that even a 1ms delay is sufficient to make the pgm_read_byte call successful. Have you made any progress finding a solution? |
@creeg2 no. But your hint is a good start I guess. Have you tried an us delay? I guess it's related to the amount of time it takes to retrieve data from flash. Since the programming paradigm is different from the normal one. It relies on callbacks when an action is done instead of sequetial instructions. The Serial.print might access the data before read is done. |
Maybe you could try changing the wrong mask in pgm_read_word macro,
(currently it is |
@igrr the offset calculation is correct, for both word and byte read functions. The ESP8266 requires flash reads to be aligned in 32bit chunks. The offset calculation makes sure that the requested read occurs on the boundry of the closest 32bit chunk. It basically rounds down to the start of the nearest 32bit chunk. The read_byte function has mask 0x00...03 to grab the last 2 bits of the address. The read_word function has mask 0x00...02 to grab just the 2nd to last bit since words are 16 bits long. An offset error also would not account for the delay work around behavior. |
You're right! Sorry, i was thinking we were trying to read an uint16_t variable which happens to be unaligned in flash. I have tried running code fragments posted in this issue. All tests on a nodemcu v1 board, not that this should matter... Running git version.
Whether the original issue (access to unsigned int array using pgm_read_word) has to be fixed somehow is debatable, because in general it is not possible to make all the code which assumes exact size of The issue raised in the last few comments (where pgm_read_byte) does not work is something i can not reproduce here. This may very well be because we are compiling with slightly different version of the core, which causes slightly different placement of data, which leads to some (?) alignment issue which doesn't happen in my setup. I'll poke around and try to make it crash somehow. |
I'm using git version a few commits older than master. I think the issue you are seeing is not related to this one. You are seeing a PhysicalLoadStoreError, load address is properly aligned, but the CPU fails to fetch data from the cache. I will check a few things and will reply in that new issue. For this one, I think it can be closed. |
Using PROGMEM/pgm_read and cast to normal types like byte, char, int, long seems not to work properly.
In my case I tried to port an Arduino-sketch that worked like a charm on UNO and derivates to ESP8266.
It compiles fine, but ESP8266 crashes at some point. In this project there are a bunch of (multidimensional) arrays put to PROGMEM with cast to byte, char, int, long.
There are warning about expanding macros for PROGMEM/pgm_read, wich led me to try if there is a difference in using casts to appropiate xintxx_t instead.
This gives no compiler warnings and sketch works like expected.
Is this behaviour known at this point?
Tested on newest Arduino IDE with ESP12E
The text was updated successfully, but these errors were encountered: