I want to get the address of the end of my program and check at compilation/linker time if I have enough space, after the code, to place some random data in execution time.
But as the symbols provided by PROVIDE keyword are like normal variables in C code, I can not verify it in compilation time.
In the linker script I have the symbol :
PROVIDE (__data_end_rom = _etext + SIZEOF (.data));
So I can use this symbol to get the address of the end of my code :
extern u16 __data_end_rom;
I can calculate the available memory if I suppose the end address to be 0xffff:
#define AVAILABLE_MEM (0Xffff - &__data_end_rom)
And I was thinking to check the available memory with _Static_assert(cond, message) provided in gcc 4.6
_Static_assert(SIZE_I_WANT_TO_ASSURE <= AVAILABLE_MEM, "NOT ENOUGH MEMORY!!!");
My problem is : The macro AVAILABLE_MEM is not calculated at compilation time, so I get the error:
error: expression in static assertion is not constant
Is there any way to provide the __data_end_rom address directly in a label or in another way ?
I know that I can't get it in compilation time because the symbol will just be linked in the linker time, so there is some way to make the linker fails ?
I could check this directly in the linker script but I prefer not doing so because the SIZE_I_WANT_TO_ASSURE is another macro calculated from others macros in a configuration header.
A linker script is a file that tells the linker which sections to include in the output file, as well as which order to put them in, what type of file is to be produced, and what is to be the address of the first instruction.
The main purpose of the linker script is to describe how the sections in the input files should be mapped into the output file, and to control the memory layout of the output file.
Linker command files allow you to put linker options and directives in a file; this is useful when you invoke the linker often with the same options and directives. Linker command files are also useful because they allow you to use the MEMORY and SECTIONS directives to customize your application.
The linker script makes a memory map of this memory allocation which is important to embedded systems because, having no OS, you have the ability then to manage the behavior of the chip. For G++, sets up the constructor and destructor tables. The actual section names vary depending on your object file format.
_Static_assert(SIZE_I_WANT_TO_ASSURE <= AVAILABLE_MEM, "NOT ENOUGH MEMORY!!!");
error: expression in static assertion is not constant
The problem here is that you are trying to compare a "constant" generated during the linking phase of the build, in an expression that requires a compile time constant (that is, something the COMPILER knows during compilation).
#define AVAILABLE_MEM (0Xffff - &__data_end_rom)
The compiler won't know the address of __data_end_rom
, only the linker knows that.
Unfortunately, I don't think there is any way to do this at compile time, make the compiler tell you the data is too large. On the other hand, an additional script reading the binary file (e.g. using size yourprog
in conjunction with a little bit of awk
or something) should be able to provide the relevant information in the makefile
or something similar.
You can do it in the link script itself, something like this:
/* minimum amount of data required at end of .text */
_Min_Data_Left 0Xffff;
.text :
{
... all the usual stuff ...
PROVIDE (__data_end_rom = . );
. = . + _Min_Data_Left;
. = ALIGN(4);
} >FLASH
The linker will now tell you that FLASH has overflowed if you go over the limit - and compilation will fail, which I understand is what you want.
It's a commonly used method to ensure a minimum amount of stack and heap is available. Here's one version - look for _Min_Heap_Size and _Min_Stack_Size: https://github.com/pingdynasty/OwlWare/blob/master/Source/flash.ld
Out of curiosity, what will you do with the extra space in .text - I'm assuming this is in Flash?
You can create a custom linker script that has assertions in it. see here
http://sourceware.org/binutils/docs/ld/Miscellaneous-Commands.html
you want to use the 'ASSERT' mechanism.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With