Import a character from a C file into a script builder

I created a section called .co_stack in my C file and created an array called pulStack to define the area.

#define STACK_SIZE 0x00003000 /*!< Stack size (in Words) */ __attribute__ ((section(".co_stack"))) unsigned long pulStack[STACK_SIZE]; 

My gcc linker script defining the stack section looks like this

 .co_stack : { _fstackptr = ORIGIN(ram) + LENGTH(ram) - 4; _fstacksize = 0x00003000 * 4; . = (_fstackptr - _fstacksize); *(.co_stack .co_stack.*) } 

As you can see, I determine the size of the stack in 2 places. One of them is STACK_SIZE in my .c file and _fstacksize in my .ld file.

How can I determine this in only one place?

For example, I want to create a pulStackSize variable as follows.

 const unsigned long pulStackSize = sizeof(pulStack); 

I want to define _fstacksize in the .ld file as

 _fstacksize = STACK_SIZE * 4; 

If I do this, I get an error when the stack overflows with 48 Kbytes.

How to import a character from .c into my .ld file?

+6
source share
1 answer

Some solutions (to the more general question "how to share values โ€‹โ€‹between C and LD script?"):

1) (NOTE: for this solution, I assume that you are using the latest version of GNU ld, docs here: http://www.math.utah.edu/docs/info/ld_3.html )

You can associate an absolute value with a character inside a script by specifying it outside the section connections (for example, at the very beginning of the script). Than you can import a character in C, specifying it as extern. Remember that the value you need in C is the ADDRESS character:

Script:

 StackSize = 0x00003000 * 4; /* the size */ .co_stack : { _fstackptr = ORIGIN(ram) + LENGTH(ram) - 4; _fstacksize = StackSize; . = (_fstackptr - _fstacksize); *(.co_stack .co_stack.*) } 

WITH

 extern long StackSize; #define STACK_SIZE (((size_t)&StackSize)/sizeof(long)) 

This decision may impose limitations when using the resulting value, for example. most compilers do not accept this line:

 long my_stack[STACK_SIZE]; 

but you donโ€™t need it anymore, because you can define the symbol "my_stack" inside the script and import it as "extern long my_stack [];". I think this is an acceptable limitation anyway.

2) Another way is to define two characters in the script located at the beginning and in the section and, and import them as an "extern char" in C. The size of the section in bytes is the difference between their two addresses. This solution has the same restriction (1)

3) If your linker is not smart enough, you can use the C preprocessor to create a suitable script at compile time by expanding the STACK_SIZE macro, as in C. You should

a) create a file "stacksize.h" containing

 #define STACK_SIZE 0x3000 

b) Add the line #include "stacksize.h" at the beginning of the script and use STACK_SIZE whenever you need. Save the script as "ldscript.c".

c) a preprocessor is called in your makefile (or equivalent compilation procedure). If you have a GCC team:

 gcc -P -E ldscript.c -o ldscript.ld 

Note that some versions of gcc emphasize the extension of the input file. Therefore, I suggest using ".c", this is the safest way.

d) Use the "ldscript.ld" file created by the C preprocessor as a script link

+10
source

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


All Articles