2024-05-27 12:03 AM
I need to declare a 'volatile const', meaning that the value is placed in FLASH and that it is re-read every time it is referenced (as the FLASH is written to elsewhere), but am finding it very difficult to accomplish this as the compiler either places this in RAM or optimises it so that the FLASH is not read every time.
volatile const uint8_t mcau8VT_SP_Backup[] __attribute__((aligned(4))) = {0xFF, 0xFF, 0xFF, 0xFF};
The compiler gives this a 'Run Address (VMA)' of 0x20000000 (i.e. RAM) and a 'Load Address (LMA)' in FLASH.
const uint8_t mcau8VT_SP_Backup[] __attribute__((aligned(4))) = {0xFF, 0xFF, 0xFF, 0xFF};
In this case the 'Run Address (VMA)' is in FLASH but the compiler "optimises" things so that the value is not read from FLASH every time and does not update when the FLASH is written to.
I have tried every combination of suggestions which I can find online including adding an attribute trying to specify which section the const should go in (.rodata), adding additional const keywords so that the "pointer" is const as well (and not just the "data"), and placing the consts in an external file.
How can I get this to be placed in FLASH and re-read every time, so that it sees updates made to the FLASH elsewhere?
2024-05-27 12:25 AM
Surely there are better approaches to this?
Like using memcpy() or a single function to access and return content?
How often is content actually changing?
2024-05-27 12:32 AM - edited 2024-05-27 12:32 AM
I'm open to anything.
I basically need to get the compiler to reserve some memory in FLASH and make sure that it is all 0xFFs so that it can be written to. I then need to know the address of that so that I can read/write it.
It only changes once.
2024-05-27 03:33 AM
I ended up solving this by creating a linker section for the volatile consts. This is certainly not easier / cleaner / "better" - compiler which I ported this code from handled it correctly - but it's working / a solution for now. Would be great if the compiler could just be made to treat a volatile const as just that :-).
2024-09-16 04:51 PM
Hi Ddu P
Did you ever find a better solution?
Im fighting a similar problem, where I read from a FPGA using OctoSpi where the Data is Truly volatile. The CPU / MPU seems to ignore the volatile, and just stop reading from the OctoSpi after first read.
If I then access the memory area at a different address, then i might read again.
The code base that i'm trying to port does also often wait in while loop for a change, but when the memory is not read, it's not working.
how did you solve using a linker section? can you share this?
It might work for me also?
Kristian Vang
2024-09-16 11:24 PM
Hi Kvang
I didn't find any better solution, no. What I have is:
Linker File:
/* Memories definition */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 320K
...
FLASH_VOLATILE_CONSTS (rx) : ORIGIN = (0x80E0000 + ((128 * 1024) - 0x20)), LENGTH = 0x20
}
/* Sections */
SECTIONS
{
...
__volatile_consts_addr_start = ORIGIN(FLASH_VOLATILE_CONSTS);
__volatile_consts_offset = ORIGIN(FLASH_VOLATILE_CONSTS) - ORIGIN(FLASH);
...
.volatile_consts :
{
. = ALIGN(4);
__volatile_consts = .;
*(.volatile_consts)
. = ALIGN(4);
} >FLASH_VOLATILE_CONSTS
...
}
Code file:
extern uint32_t __volatile_consts[]; // From linker script
// consts which must be placed in FLASH and not optimised
static const uint32_t* mcpu32VT_SP_Backup = (uint32_t*)(__volatile_consts + 0);
static const uint32_t* mcpu32VT_RV_Backup = (uint32_t*)(__volatile_consts + 1);
static const uint8_t* mcpu8IsBlank = (uint8_t*) (__volatile_consts + 2);
2024-09-17 02:11 AM
Can't you solve the problem with a pointer cast?
// "const" data will be placed into FLASH
const uint8_t mcau8VT_SP_Backup_data[] __attribute__((aligned(4))) = {0xFF, 0xFF, 0xFF, 0xFF};
// "volatile const *" forces the compiler to read on each access
volatile const uint8_t * mcau8VT_SP_Backup = mcau8VT_SP_Backup_data;
...
if (mcau8VT_SP_Backup[0] == 0xFF)
...