Reputation: 21
I want to initialize local (const) array:
void foo() {
const uint8_t arr[] = {1, 2, 3, 4, 5};
}
And for that initialization I pay 5 bytes of global RAM: those 5 constants are being copied to RAM at the start of the program and stay there forever.
The question is why? Couldn't the compiler just initialize the array directly from the FLASH when I call the function?
I can't use that right-hand temporary array anywhere else anyway, it must be destroyd right after ;
and yet it persists in RAM at all times after the startup.
Now I have to do something like
void foo() {
static const uint8_t init_arr[] PROGMEM = {1, 2, 3, 4, 5};
uint8_t arr[5];
copy_from_prog_function(arr, init_arr, 5);
}
And on top of that, now I can't even have my arr
to be const
!
Is there more elegant solution to this problem?
Upvotes: 0
Views: 2266
Reputation:
As you probably know, AVR is a harvard architecture -- the program resides in a different address space than the data and instructions to access it are different. C doesn't have means for different address spaces, so you have to use compiler extensions (like this PROGMEM
macro) here.
As program memory can only be read byte-wise (and is a bit slower than RAM because it's backed by flash), the compiler will never put data there automatically. See also Data in Program Space of the avr-libc documentation, especially the "Note on const".
That said, if the array is const
anyways, why don't you declare it static
? Then the compiler wouldn't create code to copy it on the stack, you'd access it directly, but still in RAM.
If you want it to reside in program memory, just declare it like in your second example and access the individual elements using the pgm_read_byte()
macro, no need to copy the whole array yourself.
As suggested by PeterJ_01, with newer AVR toolchains, you can even use a simpler syntax for direct flash accesses, so the code looks "nicer".
Upvotes: 1