Can I get links to the linker script as compile-time constant values ​​in C code?

I want to get the address of the end of my program and check the compilation / linker time, if I have enough space, after the code to post some random data at runtime.

But since the characters provided by the PROVIDE keyword are similar to regular variables in C code, I cannot verify it at compile time.

In the script builder, I have a symbol:

PROVIDE (__data_end_rom = _etext + SIZEOF (.data)); 

Therefore, I can use this character to get the address of the end of my code:

 extern u16 __data_end_rom; 

I can calculate the available memory if I assume that the end address is 0xffff:

 #define AVAILABLE_MEM (0Xffff - &__data_end_rom) 

And I thought 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: the macro AVAILABLE_MEM is not calculated at compile time, so I get the error:

 error: expression in static assertion is not constant 

Is it possible to specify the address __data_end_rom directly on the label or in another way?

I know that I cannot get it at compile time, because the character will just be bound at the time of the linker, so is there a way to make the linker fail?

I could check this directly in the script linker, but I don't want to do this because SIZE_I_WANT_TO_ASSURE is another macro computed from other macros in the configuration header.

+6
source share
3 answers
 _Static_assert(SIZE_I_WANT_TO_ASSURE <= AVAILABLE_MEM, "NOT ENOUGH MEMORY!!!"); error: expression in static assertion is not constant 

The problem is that you are trying to compare the “constant” generated during the assembly build phase in an expression that requires a compile-time constant (that is, what the compiler knows at compile time).

 #define AVAILABLE_MEM (0Xffff - &__data_end_rom) 

The compiler does not recognize the address __data_end_rom , only the linker knows about this.

Unfortunately, I don’t think there is a way to do this at compile time so that the compiler tells you that the data is too large. On the other hand, an additional script that reads the binary (for example, using size yourprog combined with a little awk or something else) should be able to provide the relevant information in a makefile or something similar.

+4
source

You can create your own script builder that has statements in it. see here

http://sourceware.org/binutils/docs/ld/Miscellaneous-Commands.html

you want to use the ASSERT mechanism.

+6
source

You can do this in the script link 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 component will now tell you that FLASH is full if you go over the limit - and the compilation will fail, and I understand what you want.

This is a commonly used method to ensure the minimum amount of stack and heap. Here is 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 extra space in .text - I assume it is in Flash?

+1
source

Source: https://habr.com/ru/post/946177/


All Articles