Creating a microcontroller startup file
Jens Bauer via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Tue Apr 7 13:33:24 PDT 2015
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 ?
More information about the Digitalmars-d-learn
mailing list