I'm currently working on a startup file for Cortex-M.
Thanks to Johannes, I'm now able to implement almost everything I need.

While the most important part of the code code works, there are still a few things, that I would like added/changed.

Here's a cut-down version of a start.d:
---8<-----8<-----8<-----
/* file: startup.d */

import gcc.attribute;
import core.stdc.config;

//alias extern(C) const void function() VectorFunc; // currently, this won't work for me alias extern(C) const void *VectorFunc; // so I'm using a void* instead.

extern(C) extern __gshared c_ulong[0] _stack;
const SIGNATURE_VALUE = 0x5a5a5a5a;
@attribute("weak") @attribute("alias", "defaultResetHandler") extern(C) void Reset_Handler(); @attribute("weak") @attribute("alias", "defaultExceptionHandler") extern(C) void NMI_Handler();

@attribute("section",".isr_vector.ro") VectorFunc[] g_pfnVectors = [
        cast(VectorFunc)_stack,                                 // Initial 
Stack Pointer
        &Reset_Handler,                                             // Reset 
Vector
        &NMI_Handler,                                                       // 
Non Maskable Interrupt Vector
        cast(VectorFunc)SIGNATURE_VALUE,
        ];


extern(C) void main();
@attribute("weak") extern(C) void LowLevelInit();
@attribute("weak") extern(C) void SystemInit();
extern(C) void defaultResetHandler()
{
//      if(&LowLevelInit) LowLevelInit;
//      if(&SystemInit) SystemInit;

/* (snipped code to copy the DATA section to RAM and clear the BSS section) */

//      main();

        while(true){}
}

extern(C) void defaultExceptionHandler()
{
        while(true){}
}
--->8----->8----->8-----

The most important thing here is that I have not been successful in making the two subroutines LowLevelInit() and SystemInit() optional. That is: If they are not linked to startup.o, then they should simply be NULL pointers. I can do this in C, by supplying the 'weak' attribute, but so far, my attempts to do this in D have not been successful.

If I enable the two lines calling those subroutines, I get link errors...

startup.d:(.text+0x2): undefined reference to `LowLevelInit'
startup.d:(.text+0x6): undefined reference to `SystemInit'

Question number 1: How can a C subroutine be made optional, so it's called only if it linked ?

You may have noticed that the VectorFunc is not a real function, but a void*. The code will work fine this way, but I'd prefer it to be more correct (if possible).

Question number 2: Is it possible to change the VectorFunc to be a real function pointer, rather than a void* ?

I've placed an empty main function in a file called main.d, which is linked to startup.o. If I enable calling main(); then suddenly the executable file grows from TEXT=20 bytes, DATA=16 bytes, BSS=280 bytes to TEXT=10184 bytes, DATA=2132 bytes and BSS=12824 bytes. The disassembly shows that suddenly malloc & friends are added to the executable, even though they're not used at all. I've tried renaming the function I call to something different; but that did not change anything. The things that seem to trigger that the binary file grows, is that if I call the function. I've also tried just having a pointer to the function, and nothing extra is included.

Question number 3: How can I call an external function and keep the binary file size down ?

I've found out that the 'alias' keyword comes in quite handy, in order to reduce the size of the source code. In my test source, you'll find that the attribute keyword is used twice in front of each function declaration. This looks quite bulky, and I'm sure it can be much improved upon. ;) Question number 4: How can I reduce the function declaration of the Reset_Handler and NMI_Handler shown above ?

Reply via email to