RFC: Pay-as-you-go, Portable D Runtime for Microcontrollers (and maybe more)

Mike via Digitalmars-d digitalmars-d at puremagic.com
Mon May 4 19:26:26 PDT 2015


Read on GitHub: 
https://github.com/JinShil/minimal_druntime_experiment

There was recently a discussion about how we could create a 
portable, pay-as-you-go, D runtime to help bring the promise of D 
to free-standing platforms and devices with tight resource 
constraints (e.g. microcontrollers).  Thread started here:  
http://forum.dlang.org/post/mhrs4p$31id$1@digitalmars.com

The primary motivation is to create an arm-none-eabi GDC 
cross-compiler toolchain for programming ARM Cortex-M 
microcontrollers in D, but I think there's a way to achieve 
broader platform support by delegating implementation details 
down the "supply chain".  I hope to articulate that strategy in 
this post.

To prove the concept, provide a place to start, and discuss 
ideas, I created the most minimal D runtime I could:  
https://github.com/JinShil/minimal_druntime_experiment.  I've 
also included Phobos, so we could still have `std.stdio.write` 
and `std.stdio.writeln` for console output, as every device needs 
a console for development.

Overview
**********
d
├── phobos
│   └── std
└── runtime
     └── rt
         └── typeinfo

ports
├── arm
│   └── cortexm4
│       ├── phobosWe
│       │   └── phobosPort.d
│       └── runtime
│           └── runtimePort.d
├── posix
│   └── linux
│       ├── phobos
│       │   └── phobosPort.d
│       └── runtime
│           ├── c_types.d
│           └── runtimePort.d


There are two main folders: "d" and "ports".  "d" provides the 
patform-agnostic code, or code that is relevant to a large number 
of platforms.  The "ports" directory provides the 
platform-specific implementation.  Building simply requires 
importing "d/runtime", "d/phobos", and your platform's hierarchy 
in the "ports" folder.  At the moment, I've only implemented a 
Linux 64-bit port and an ARM Cortex-M4 port to illustrate the 
concept.  This is roughly how I wish the official runtime could 
be structured in the spirit of Issue 11666.

The official runtime includes platform-specific bindings in 
`core.sys` and `stdc`, but I think that is a design anomaly.  
While a port may find it convenient to use those bindings, they 
should not be part of the D language's public API.  Rather, they 
should be deported to Deimos, and if needed, imported privately 
by a platform's port.  For the Linux port, I chose to write the 
platform's system calls in assembly to illustrate that it is not 
even necessary to use those bindings if one wants to do the due 
diligence in D.

Porting to a New Platform
******************************
The platform-agnostic code in "d" delgates implementation details 
to the platform-specific code using `extern(C) extern 
_d_sys_name` "system calls" (for lack of a better term).  This is 
how the newlib C library delegates platform-specific 
implementations:  See 
http://wiki.osdev.org/Porting_Newlib#newlib.2Flibc.2Fsys.2Fmyos.2Fsyscalls.c

At the moment, for the sake of demonstration, only 2 system calls 
have been defined:

* `__d_sys_write` - Equivalent to C's `write` system call
* `__d_sys_exit` - Equivalent to C's `exit` system call

These two system calls allow us to create a simple Hello World.  
"runtimePort.d" implements `__d_sys_exit` and "phobosPort.d" 
implements the `__d_sys_write`.

Putting it all Together
************************
Users are not expected to use this code directly.  Rather, I 
envision toolchain, silicon, and board vendors will use this code 
as a small, but essential part of, their platform's D programming 
package.  For example, a package for the ARM Cortex-M family of 
MCUs might contain the following:
* arm-none-eabi GDC cross-compiler
* a library containing compiled code for the "d" folder in this 
repository
* a library containing the compiled code for the 
"ports/arm/cortexm" folders in this repository
* cortex-m core startup files
* the newlib C library
* the C library bindings from Deimos
* multilibs from the GNU toolchain.

A silicon vendor like ST, may then take that package and add more 
platform-specific for their family of products:
* startup files with interrupt vectors for their peripherals
* linker scripts for each of their MCUs
* flash memory programmer
* library for on-dye peripherals
* etc..

A board vendor may choose to create yet another layer on top of 
the silicon vendor's package.
* library for peripherals external to the MCU (external RAM, IO 
expanders, gyroscope, LCD, etc...)

In short, this repository just provides just the foundation to 
"get D working", and delegates to toolchain, silicon, and board 
vendors to fill in the details for their products.

RFC
*****
For those who have stake in this code base (kernel developers, 
embedded developers, toolchain and package maintainers, etc...) 
your constructive criticism and ideas are most welcome.  I am 
unsure yet how this will play out, and what roles players will 
assume, but let's give it a try.

Plea to Compiler Implementers
***********************************
We need better control over codegen.  TypeInfo and dead-code 
removal is preventing me from making progress 
(http://forum.dlang.org/post/quemhwpgijwmqtpxukiv@forum.dlang.org). 
  I've resorted to compiling to assembly, using sed to hack the 
assembly, and then compiling the assembly.  Things like that make 
me want to not use D at all.  Here are some ideas from myself and 
others:
*  Move TypeInfo to the runtime: 
https://issues.dlang.org/show_bug.cgi?id=12270
*  Move D runtime hooks out of the compiler and into *.di files 
so they can be decorated with attributes and `version`ed so the 
compiler can see what features of D are supported by the port and 
generate smarter code:  
http://forum.dlang.org/post/psssnzurlzeqeneagora@forum.dlang.org
*  Add -fno-rtti compiler switch
*  Add attribute support so programmer can choose which types to 
generate runtime-time info for.

I don't know what the right solution is.  Let's have that 
discussion.

LDC Folks:  https://github.com/ldc-developers/ldc/issues/781 is 
currently preventing me from supporting LDC with this runtime.

Mike


More information about the Digitalmars-d mailing list