SDCC global constant initialized array in a fixed position in memory

By jepmsx

Champion (281)

jepmsx さんの画像

15-01-2022, 08:57

I'm trying to define a global array with constant values. First I've tried to use const in the definition, but I think that only the pointer address is constant. So I have defined it outside the main function like

uint8_t __at(0x8200) notesFreq[12] = {
    173, 181, 192, 193, 194, 229, 242, 1, 16, 32, 39, 57 

But when I look at that memory position it does not have those values.

How can I define it?


By ToriHino

Paladin (927)

ToriHino さんの画像

15-01-2022, 09:55

Normally SDCC puts these in the data segment, not sure if the __at even works here. You can influence the location of both the code and data segment with the compiler options --code-loc ADDRESS and --data-loc ADDRESS. So for example --data 0x8200 will start your data at address 0x8200 (using 0 for address puts it right behind the code segment).

By geijoenr

Champion (392)

geijoenr さんの画像

15-01-2022, 10:55

You can use const to put an array in the data segment (note that giving the size of the array is not necessary because the initialization data is specified).

const uint8_t var[] = {1,2,3,4};

the actual memory location shouldn't matter, but you can specify where the data segment starts using the linker options.

By aoineko

Paragon (1138)

aoineko さんの画像

15-01-2022, 11:52

If you add const in front of your array, it is the pointed data that will be defined as constants (as you wanted).
This will also change the way SDCC will handle this data and where it will end up.

Your table will be include "as it" in your program binary in the _CODE area.
You can set a position by hand but be careful:
- Your _CODE area will be extend to include your table (which can increase the size of your binary)
- The compiler does not handle the overwriting of manually placed data (with the __at directive). This is probably why you cannot find your data at the indicated address.

Not const
Since without the const your table can be modified, it must end up in RAM.
SDCC will store the initial values of the array in the _INITIALIZER area (usually placed just after the _CODE area by the crt0) and will also allocate the equivalent space in RAM in the _INITIALIZED area (usually just after _DATA).
At your program start, the crt0 is required to copy the contents of the _INITIALIZER area to _INITIALIZED to initialize all variables/tables for which you have defined a default value.
When you choose an address to place your array, it is the address in RAM that you can change (not the address of the data to initialize). The same limitations apply (_INITIALIZED area expansion and risk of overwriting).

By jepmsx

Champion (281)

jepmsx さんの画像

15-01-2022, 16:03

Thanks guys for your explanation. I understand now its behaviour

By DamnedAngel

Champion (286)

DamnedAngel さんの画像

15-01-2022, 22:37

My template solves that for you:
Tip: despite its name, you can use it in other environments, including under linux and macOS.