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