Projectitis
Well-known member
Hi all,
I'm getting a very weird bug on T_3.6 trying to copy a byte from an array in PROGMEM to a struct in ram.
My program just simply stops executing at a certain point (at least, my Serial debug commands stop coming).
The code is relatively big, so I'll explain what I can below. You can grab the code from the repo here: https://github.com/projectitis/libxm_t3
Some background:
This macro reads one uint8_t from the module in flash (moddata is a const char* pointing to the module in flash mem), with overflow protection:
The other thing you need to know is that the 'sample' struct contains volume as a float.
Here is the code in question (load.c, line 393):
There are 7 samples in the module.
Changing the code to this has the exact same result (broken):
Changing the code to this (just for testing) works (but doesn't set the actual volume value):
Changing it to this breaks it again, even though I can verify that the value of temp_float is 1.0f;
It's important to highlight that when the code dies on sample 1 it has already run exactly the same code with exactly the same values on sample 0.
I thought maybe it had something to do with memory alignment, but we're only reading a single byte here, so that shouldn't be an issue?
In my case the actual memory addresses are as follows:
There are two places in the code where this program fails during execution, and both of them involve reading a byte, converting it to a float (with a division) and assigning it to a struct member.
Any help appreciated!
I'm getting a very weird bug on T_3.6 trying to copy a byte from an array in PROGMEM to a struct in ram.
My program just simply stops executing at a certain point (at least, my Serial debug commands stop coming).
The code is relatively big, so I'll explain what I can below. You can grab the code from the repo here: https://github.com/projectitis/libxm_t3
- Add libxm_t3 as a library
- Run the sketch in the examples folder
Some background:
This macro reads one uint8_t from the module in flash (moddata is a const char* pointing to the module in flash mem), with overflow protection:
Code:
#define READ_U8(offset) (((offset) < moddata_length) ? (*(uint8_t*)(moddata + (offset))) : 0)
The other thing you need to know is that the 'sample' struct contains volume as a float.
Code:
float volume;
Here is the code in question (load.c, line 393):
Code:
sample->volume = (float)READ_U8(offset + 12) / (float)0x40;
There are 7 samples in the module.
- For sample 0, the uint8_t is 64, the float is 1.0f, and the code works fine
- For sample 1, the unit8_t is 64, the float is 1.0f, and the code dies trying to assign the float to sample->volume;
Changing the code to this has the exact same result (broken):
Code:
temp_uint8 = READ_U8(offset + 12); // This works ok
temp_float = temp_uint8 / 64.0f; // This works ok
sample->volume = temp_float; // This is where it dies
Changing the code to this (just for testing) works (but doesn't set the actual volume value):
Code:
temp_uint8 = READ_U8(offset + 12);
temp_float = temp_uint8 / 64.0f;
sample->volume = 1.0f;
Changing it to this breaks it again, even though I can verify that the value of temp_float is 1.0f;
Code:
temp_uint8 = READ_U8(offset + 12);
temp_float = temp_uint8 / 64.0f;
sample->volume = 1.0f;
sample->volume = temp_float;
It's important to highlight that when the code dies on sample 1 it has already run exactly the same code with exactly the same values on sample 0.
I thought maybe it had something to do with memory alignment, but we're only reading a single byte here, so that shouldn't be an issue?
In my case the actual memory addresses are as follows:
- For sample 0, the volume byte is at 56943 in flash mem. This is the one that works
- For sample 1, the volume byte is at 60180 in flash mem. This is the one that doesn't work
There are two places in the code where this program fails during execution, and both of them involve reading a byte, converting it to a float (with a division) and assigning it to a struct member.
Any help appreciated!