This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

How to propagate a value from C to a SPACE directive with armasm

Hi all,

I would like to ask help to some expert in armasm.

In my startup.s file I have the following code which reserves 0x400 bytes of RAM to the stack.

; this is the original startup.s file
Stack_Size      EQU     0x00000400

                AREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem       SPACE   Stack_Size
__initial_sp

Well, I would like to be able to initialise Stack_Size with a value which I have in a cfg.h file or with a const value which I have in a cfg.c file

// this is cfg.h file
#define STACK_SIZE  0x00000400
// this is cfg.c file
#include "cfg.h"
extern const int Stack_Size = STACK_SIZE;

The problem is that I dont know how to export the variable from C and import it into assembly.

I tried to use IMPORT, as in the following, but it does not work.

; this is the modified startup.s

                IMPORT Stack_Size
;Stack_Size      EQU     0x00000400
;               EXPORT  Stack_Size

                AREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem       SPACE   Stack_Size
__initial_sp

Any suggestion?

Thanks in advance, Marco.

  • You could consider the opposite; i.e., have the define and variable in the startup, export that and then have an extern in your C.

    This way is quite straightforward.

  • Hi,

    I already do that. However, it is not just enough to use an extern variable called Stack_Size, but you need to use some more code:

    // this is startup.s
    Stack_Size      EQU     0x00000400
                   EXPORT  Stack_Size
    
                    AREA    STACK, NOINIT, READWRITE, ALIGN=3
    Stack_Mem       SPACE   Stack_Size
    __initial_sp
    
    // this is myfile.c
    __asm int getstacksize (void) {
            IMPORT  Stack_Size
            LDR     R0,=Stack_Size
            BX      LR
    }
    

    However, it is not what I want to do.

    My aim is to hide the startup.s and use just .h and .c files for configuration.

    Thank anyway, marco.

  • Marcus,

    I'm sorry for asking in this thread, but do you know a similar trick for a scatter file? How can I run the preprocessor on a scatter file?

    Thanks

  • Thanks Marcus,

    it works and solves my problem.

    regards, marco.

  • Thanks for this link. I have seen it already (obviously I checked the linker and utilities guide) but as far as I recall I did not manage to build, even. I will try this again. Thanks again.

  • You are welcome. Alternatively, you could import the stack size information generated by the linker into C. This is a perhaps little less of a hack, but that depends on the perspective of course ;-)

    extern unsigned int Image$$STACK$ZI$$Length;
    const int Stack_Size = (int)&Image$$STACK$ZI$$Length;
    

    (untested)

    --
    Marcus
    http://www.doulos.com/arm/

  • The former solution is better, but I think I will test also this latter.

    I have implemented a hal (hardware abstraction library) for the cm3, which is usable with a hal.h, hal.lib, hal_startup.s and a hal_cfg.h.

    My aim was to have a single configuration point, the hal_cfg.h, for everything and thus also for stack and heap size without having to touch the startup file by hand.

    The use of the preprocessor w/ the assembler works for that.

    However, in runtime I also make a check of effective heap and stack sizes. Now I am using a method which I already posted in the thread with the __asm functions, but your latest suggestion seems better.

    Thanks again to you and to every member of the forum. It is a great place where to share knowledge!

    Hi, Marco.

  • Just a quick remark: The Forum seems to have swallowed some Dollar signs. Every '$' in my post should be a double dollar.

    --
    Marcus

  • Hello Marcus,

    I haven't given up yet, and now when I have a little bit of I am determined to get this thing to work (having the preprocessor parse my scatter file). I am trying this:

    #! armcc -E
    
    #include "boot_firmware.h"
    

    in order to include a definition that the scatter file needs. But then the preprocessor reports

    C:\DOCUME~1\tm\LOCALS~1\Temp\p14c8-2(2): error:  #5: cannot open source input file "boot_firmware.h": No such file or directory
    

    using the -I directive does not seem to help. How do I tell the preprocessor where to look for the file? The compiler settings already use -I option to get to the relative path "..\..\Bootloaders\src", but if that one is used in the scatter file itself, I get this error message:

    C:\DOCUME~1\tm\LOCALS~1\Temp\p200-3(103): error: L6226E: Missing base address for region typedef.
    C:\DOCUME~1\tm\LOCALS~1\Temp\p200-3(103): error: L6292E: Ignoring unknown attribute 'enum' specified for region typedef.
    C:\DOCUME~1\tm\LOCALS~1\Temp\p200-3(105): error: L6226E: Missing base address for region e_target_internal_flash.
    C:\DOCUME~1\tm\LOCALS~1\Temp\p200-3(105): error: L6292E: Ignoring unknown attribute '=' specified for region e_target_internal_flash.
    C:\DOCUME~1\tm\LOCALS~1\Temp\p200-3(105): error: L6228E: Expected '{', found ',...'.
    C:\DOCUME~1\tm\LOCALS~1\Temp\p200-3(105): error: L6228E: Expected '}', found 'EOF'.
    

    Any thoughts...?

    Thanks in advance!

  • > Any thoughts...?

    Of course. You are suffering from an issue with armld that I reported in 2008 (case #394129) and has been fixed a short while after that.

    The behavior you seem to be experiencing started in RVCT 3.1 Build 700. The include paths are relative to the temporary directory!

    Although initially not acknowledged (to me anyway) as bug, ARM reverted the change and returned to the proper behavior a few releases later.

    --
    Marcus

  • Marcus,

    Thanks for your reply. I'm using MDK-4.11 - I would have thought it is supposed to be solved in it...?