On Nov 30, 2013 11:40 AM, "Mike" <n...@none.com> wrote:
>
> 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.

In before the "that's not D! That's some D, a bit of some extended inline
assembly, and a custom linker script."

Congrats though.  :)

Regards
-- 
Iain Buclaw

*(p < e ? p++ : p) = (c & 0x0f) + '0';

Reply via email to