質問

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.

役に立ちましたか?

解決

_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 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.

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?

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top