On Nov 30, 2013 11:40 AM, "Mike" <[email protected]> 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';
