Need help making minimal bare metal ARM Cortex-M D program
Mike
none at none.com
Sat Nov 30 03:37:23 PST 2013
I finally succeeded in doing what I set out to do: Write a
simple hello world program for an ARM Cortex-M processor using
ONLY D.
/*************************
* The D Program (start.d)
*************************/
module start;
import ldc.llvmasm;
extern(C) __gshared void * _Dmodule_ref;
//Must be stored as second 32-bit word in .text section
immutable void function() ResetHandler = &OnReset;
void SendCommand(int command, void* message)
{
__asm
(
"mov r0, $0;
mov r1, $1;
bkpt #0xAB",
"r,r,~{r0},~{r1}",
command, message
);
}
void OnReset()
{
while(true)
{
// Create semihosting message message
uint[3] message =
[
2, //stderr
cast(uint)"hello\r\n".ptr, //ptr to string
7 //size of string
];
//Send semihosting command
SendCommand(0x05, &message);
}
}
/*****************************
* The Linker Script (link.ld)
*****************************/
MEMORY
{
CCRAM (rxw) : ORIGIN = 0x10000000, LENGTH = 64k
SRAM (rxw) : ORIGIN = 0x20000000, LENGTH = 128k
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024k
}
_stackStart = ORIGIN(CCRAM) + LENGTH(CCRAM);
SECTIONS
{
.text :
{
LONG(_stackStart); /* Initial stack pointer */
KEEP(start.o(.data.rel.ro)) /* Internet vector table */
/* the code */
*(.text)
*(.text*)
/* for "hello\r\n" string constant */
. = ALIGN(4);
*(.rodata)
*(.rodata*)
}>FLASH
/* Need .data, .bss, .ctors and probably more as program becomes
More complex */
}
Tools used:
Operating System: Arch Linux 64-bit
Compiler: LDC (2063b4)
Linker & Binary Utilities & Debugger: GNU Tools for ARM Embedded
Processors (https://launchpad.net/gcc-arm-embedded)
JTAG Emulator: JTAG-lock-pick Tiny 2 w/ OpenOCD 0.7.0
To compile:
ldc2 -march=thumb -mcpu=cortex-m4 -noruntime -nodefaultlib -c
start.d
To link:
arm-none-eabi-ld -T link.ld --gc-sections start.o -o start.elf
To execute:
openocd -f interface/jtag-lock-pick_tiny_2.cfg -f
target/stm32f4x.cfg
arm-none-eabi-gdb start.elf
.. in GDB:
target remote localhost:3333
monitor arm semihosting enable
monitor reset halt
load
monitor reset init
continue
Output:
hello
hello
...
Code Size: 148 bytes (not bad)
Why I think this is significant:
1. It shows D can write the most low level of programs and does
not require an operating system
2. It shows that the D runtime and D standard library are not
mandatory and do not need to be fully ported to one's platform to
begin programming ARM Cortex-M bare metal hardware in D (although
this is not the first to do so:
https://bitbucket.org/timosi/minlibd)
3. It shows linking to C code and assembly files are optional
4. It shows the tools are capable (although they have not been
well exercised in this example) and more specifically MY
toolchain is working.
5. It's a great start to writing very embedded systems in D, or
more importantly, not C/C++ (good riddance!)
What's next for me:
1. Get a GDC toolchain working, although I'll probably switch to
LDC when LDC matures.
2. Learn more about D.
3. Study minlibd and the d runtime and program the bare
essentials to make D a productive language for the ARM Cortex-M.
4. Help the D community help me, by testing the toolchains for
the ARM Cortex-M platform and file bug reports.
Thanks to those who commented on my previous posts. I'm quite
excited about this language.
More information about the Digitalmars-d
mailing list