I have come across following definition in an embedded C source file:
const preamble_t OAD_Preamble # ".preamble" =
{
HAL_OAD_RC_MAX, // Default program length of max if not using post-processing tool.
OAD_MANUFACTURER_ID, // Manufacturer ID
OAD_TYPE_ID, // Image Type
0x00000001 // Image Version
};
I have no idea about the # part, can you please help me with this?
Edit:
This is in IAR compiler, used with TI SoCs.
This is the way you can specify a memory address or a section in which you would like to place your variable.
".preamble" is the name of a section,
OAD_Preamble is the variable to be placed there.
You can also specify physical address after the at # sign:
const unsigned char port_bit # 0x1800 = BIT0;
More information is in this document.
Note: this is a non-portable compiler extension, not a part of the standard C syntax.
Related
I am currently writting a embedded program for a microcontroller with a splitted flash region. Something like
MEMORY {
flash1 : ORIGIN = 0x1000, LENGTH = 0x1000
/* 1K gap */
flash2 : ORIGIN = 0x3000, LENGTH = 0x1000
}
My application has grown to a point where the ".text" section is larger than the area of flash1.
Is it possible to automatically split the text section accross the two areas?
Something like:
SECTIONS {
.text0 : { *(.text) } > flash1
.text1 : { *(.text) } > flash2
}
If I am doing something like the one above. I get a error message telling me that
ld: a.out section `.text' will not fit in region `flash1'
ld: region `flash1' overflowed by 240 bytes
I know I could do something like:
SECTIONS {
.text0 : { mylargefile (.text) } > flash1
.text1 : { *(.text) } > flash2
}
but I don't have a single large file. So the question is is it possible to tell the linker to fill the first output section until the it is full and afterwards continue with the next section?
Further information:
I do not provide a full example as my actually application is much more complex as I am although using LMA and VMA section and special section for some special files. But this answer should provide me enough help to continue or ask further questions.
I am looking forward for answers. I hope my question is clear enough without a full sample
EDIT1:
The solution of the question Splitting embedded program in multiple parts in memory is not correct in my case as the solution uses wildcards to spilt the files manually. I ask if there is a automatically solution. Otherwise I would be forced to manually adjust the linker file every time I do larger changes on the code base.
EDIT2:
Changed example to make sure there is a gap as remarked by Tom V
Well, some compilers allow in their linkers (and the scripts) to overflow to another section, if the first one is full.
But also these have sometimes problems, that it depends on the order of when the section is full and when it switches, it does not come back to fill the first one up, e.g. you have in the beginning or the middle a very big part. When the linker skips now to the next section due to overflow, the first was maybe just filled to the half. It does not use smaller parts AFTER that big part, to go back to the first sections to fill in.
So, it seems, the GNU LD, the Gold-linker and also the LLVM/CLANG linker (which state at their site, that the linker script is the same as GNU LD, and the exceptions page does not state anything), do not support to overflow into another section.
So, to make it easier, maybe some hints:
Filtering by filename patterns can get tedious over time. And, it does not allow you to filter by symbol, only by filename pattern and input section names.
If you have a approach like AUTOSAR MemMap, you could split the code by placing them into new sections with a different naming than default .text, .rodata, .data, .bss. (Unfortunately, GCC + CLANG went that extra way of using attribute(( )) instead of the #pragma or _Pragma() way of the C-standard). (AUTOSAR MemMap example at the end)
you could split into fast and slow code, e.g. introducing new sections like .codefast, .codeslow (e.g. ISR code as fast, task level code as "slow")
you could split into QM vs ASIL partitions introducing sections like .code_qm, .code_asila, .code_asilb
you could split code and config / const data , where the configuration is put into a separately flashable section, e.g. sections .text, .rodata could be split into .text, .const .postbuildconfig, .calib .. with a partial different coding style, you could here keep the code the same, but project config (e.g. CAN config, filter chains etc) could use a configurable config, where you just flash a new config, without updating the code itself
.text --> flash memory sector 1
.postbuildconfig --> flash memory sector 2
.calib --> flash memory sector 3
Before starting actually to really compile and link, maybe an inbetween build phase could use tools like objdump / nm / size / readelf to first scan over the .o files to give out the object / section sizes and summarize them by a script according to certain criterias e.g. input memory layout and by above special sections or by ordering by size and .o file name patterns, which you could use to update the linker script to adapt the memory definitions. SO, the script could try to fit until the gap as much as fits, then switches to the other memory. It could even try to generate the linker script parts which is later passed to the linker. You could write such a linker preprocess script in perl or python.
Together with the memory mapping to different sections, you could filter now like this:
MEMORY {
// Maybe you have two 128k areas separate by a gap
// Put the code in the first big part, and the more
// "configurable part" in the second area might even
// allow you to flash/update the separately
CODE1 : origin = 0x10000, len = 128k
// maybe here is a gap
CODE2 : origin = 0x10000, len = 64k
CONST : origin = 0x20000, len = 4k
CALIB : origin = 0x40000, len = 4k
POSTBUILD : origin = 0x50000, len = 48k
}
SECTIONS {
.code1 : {
*(.text) // default .text
*(.code_fast) // fast/slow code split
*(.code_qm) // qm/asil code split
} > CODE1
.code2 : {
*(.code_slow) // fast/slow code split
*(.code_asila) // qm/asil code split
*(.code_asilb) // qm/asil code split
} > CODE2
.const : {
*(.const)
*(.rodata)
} > CALIB
.calib : {
*(.calib)
*_calib.o(.calib) // in case you separate them also out into xxx_Calib.c files compiled to xxx_Calib.o files
} > CALIB
.postbuild : {
*(.postbuild)
*_PBCfg.o(.postbuild) // in case you separate them also out into xxx_PBCfg.c files compiled to xxx_PBCfg.o files
} > POSTBUILD
}
This approach allows you also to prepare the layout in a header, and generate that configs and calibs by certain external tools.
Additionally, it also allows a bit better to estimate your memory resource consumptions and therefore also, how and where to place/link them to the memory sections.
Here is an AUTOSAR MemMap usage example in code
#define XXX_START_SEC_CODE_FAST
#include "MemMap.h"
void XXX_Channel0_Notification(void) {
// Channel0 Finished Notification e.g. called from ISR
}
#define XXX_STOP_SEC_CODE_FAST
#include "MemMap.h"
The MemMap.h can configure this like:
#if defined(XXX_START_SEC_CODE_FAST)
#undef XXX_START_SEC_CODE_FAST
// open section .codefast
#pragma section code ".codefast"
#elif defined(XXX_START_SEC_CODE_SLOW)
#undef XXX_START_SEC_CODE_SLOW
// open section .codeslow
#pragma section code ".codeslow"
#endif
#if defined(XXX_STOP_SEC_CODE_FAST)
#undef XXX_STOP_SEC_CODE_FAST
// back to default section
#pragma section code
#elif defined(XXX_STOP_SEC_CODE_SLOW)
#undef XXX_STOP_SEC_CODE_SLOW
// back to default section
#pragma section code
#endif
The MemMap.h file could be generated, by scanning all the start/stop section defines, and generating the pragmas by a config tool (could be even Excel).
The advantage is, that you do not spill all the pragmas possible (e.g. different compilers <-> different dialects), or if to map or not to map. So you can actually reuse the code in different projects if possible.
In a C application, I want to place a big buffer at an address after the variables, stack and dma address ranges. Of course I can define a section in the wanted location in the linker script and declare a big array in C and give a section attribute to the array. But I want to do it without actually declaring the big array because it makes the executable too big. I want to use the array address to do the same.
I'm using gcc and try to use an address I define in the linker script inside the C source file.
Here is how I tried it.
in the linker script file (which is ldabtsm.lds.S in my case),
...
. = ALIGN(16777216);
.vimbuffs : {
*(.vimbuffs)
}
vimbuffs = .;
...
I tried using vimbuffs in the C source file.
So I did (if I can print, I can use it anyway..)
extern unsigned int vimbuffs; // from linker script
printf("vimbuffs = %x\n", vimbuffs);
From the map file, I can see the vimbufs is assigned to 0x3b3f6000 which is just right, I want it to be aligned. But when run the program and print the value, I see
vimbuffs = a07f233d
What is wrong?
I am in a situation in an embedded system (an xtensa processor) where I need to manually override a symbol, but the symbol happens to be in the middle of another symbol. When I try using -Wl,--wrap=symbol it won't work, since the symbol isn't its own thing.
What I need to do is specify (preferably in a GCC .S, though .c is okay) where the code will end up. Though the actual symbol will be located somewhere random by the compiler, I will be memcpying the code into the correct place.
40101388 <replacement_user_vect>:
40101388: 13d100 wsr.excsave1 a0
4010138b: 002020 esync
4010138e: 011fc5 call0 4010258c <_UserExceptionVector_1>
My problem is GCC creates the assembly with relative jumps assuming the code will be located where it is in flash, while the eventual location will be fixed in an interrupt vector. How do I tell GCC / GNU as "put the code wherever you feel like, but, trust me it will actually execute from {here}"
Though my code is at 0x40101388 (GCC decided) it will eventually reside and execute from 0x40100050. How do I trick GCC by telling it "put the code HERE" but pretend it's located "HERE"
EDIT: I was able to get around this, as it turns out, the function I needed to modify was held in the linker script, individually. I was able to just switch it out in the linker script. Though I still would love to know the answer, I now have a work-around.
In the linker script each output section has two associated addresses: VMA and LMA -- the address for which the code is linked and the address where the code will be loaded.
Put the code that needs to be relocated into separate section, add an output section to your linker script with desired VMA and LMA and put an input section matching the name of the code section inside it.
E.g. the following C code
void f(void) __attribute__((section(".relocatable1.text")))
{
...
}
extern char _relocatable1_lma[];
extern char _relocatable1_vma_start[];
extern char _relocatable1_vma_end[];
void relocatable1_copy(void)
{
memcpy(_relocatable1_vma_start, _relocatable1_lma,
_relocatable1_vma_end - _relocatable1_vma_start);
}
Together with the following piece of ld script, with VMA substituted with the desired target code location
SECTIONS {
...
.some_section : { ... }
.relocatable1 VMA : AT(LOADADDR(.some_section) + SIZEOF(.some_section)) {
_relocatable1_vma_start = . ;
*(.relocatable1.literal .relocatable1.text) ;
_relocatable1_vma_end = . ;
}
_relocatable1_lma = LOADADDR(.relocatable1) ;
...
}
should do what you want.
I am working on startup code of micro controller 32 bit and codewarrior compiler , As we have to deal with linker script. Certain variables that used in startup code for initilization of RAM and stack come from linker script.
Linker Script initialize these variables with different address. Problem is one variable have wrong address. In linker script it initialized by following command _f_data_rom.
Could any one tell me how linker initiazed variables that provides
address for stack , RAM initialization?
What this command means _f_data_rom ?
it looks like
RC_SDATA_SRC = _f_sdata_rom;
RC_SDATA_DEST = _f_sdata;
RC_SDATA_SIZE = (SIZEOF(.sdata)+3) / 4;
RC_DATA_SRC = _f_data_rom;
RC_DATA_DEST = _f_data;
RC_DATA_SIZE = (SIZEOF(.data)+3) / 4;
Looking at this document at page 69 you have to look at __ppc_eabi_linker.h how those variable are exported, e.g: this link to file
Into the same document, at page 65 you can find the form that configure addresses for linker. Take a look at that and check those settings.
I have an unsigned long which needs to get a platform specific variable.
I do not wish to use boot parameters as this driver will go into products and vendors are reluctant to change boot parameters.
I would like to know if this variable can be initialized from Makefile or from Kconfig.
I remember that the serial port address for early printk is provided in the Kconfig when I used the menuconfig long back to set it. But I never understood how that worked.
You can pass that value from Kconfig file in that directory of the program file,
You can set the Kconfig to value of the variable which is needed.
Like for example, in the Kconfig, add below configuration for the variable
config MY_VALUE_LONG // config keyword
hex "MY VALUE IS" //What you see in the menuconfig
default 0xAB123 //unsigned long value in hex
In the above Kconfig, MY_VALUE_LONG will hold you long value in the hex format, MY VALUE IS is what that will be displayed when $ make menuconfig is called, and the default value set using the default variable will be passed to the program.
In Program (where the variable value is required), use the config variable CONFIG_MY_VALUE_LONG to obtain the value in hexadecimal
Like for example,
unsigned long value = CONFIG_MY_VALUE_LONG
Find the C file and Makefile implementation in below to meet your requirements
foo.c
main ()
{
int a = MAKE_DEFINE;
printf ("MAKE_DEFINE value:%d\n", a);
}
Makefile
all:
gcc -DMAKE_DEFINE=11 foo.c
MAKE_DEFINE is a define, which is enabled through Makefile