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