Edited at
stm32Day 17

D言語でSTM32F407DISCOVERYを動かした話

More than 1 year has passed since last update.


D言語で動くのか

D言語は複数のコンパイラ実装が存在しており、リファレンスコンパイラであるDMDではできないのですが、コンパイラバックエンドがGCCのGDCやLLVMのLDCではCortex M4向けにバイナリを吐くことが可能です。今回はLDCを使って開発しました。

理屈の上ではできることはわかるのですが、実際に動くものを作るというのは大きな違いがあり、なかなか簡単にいかなかったりします。とはいえLDCはすでにThumb2 targetをサポートしていたので、特にコンパイラをいじるようなこともなくLチカまではすんなり書くことができた記憶があります。

ソースコードはGitHubで公開しています。


D言語だとなにが嬉しいのか・辛いのか

組み込みでよく使われる言語というとAssemblyやC言語になります。これらの言語と比較してという話でいうと、


  • より強力な型チェックが存在すること

  • テンプレートによる柔軟なメタプログラミングが可能

  • UFCSでメソッドチェーンっぽく記述できる

といったあたりが個人的に嬉しいです。またffiがあるので(今回はしていないのですが)C言語のライブラリをD側から呼び出すことも可能です。

反面、エコシステムが充実していないこと(そもそも今回はスタートアップルーチンから全て自作しています)、組み込みプログラミングにおけるDの作法を意識せずに書いてしまうとかなりの確率でエラーになってしまうことなどがあります。

例えばD言語は全てのグローバル変数が普通に書いてしまうとTLS領域に置かれるのですが、これはLibcの __tls_get_addr 関数を使うようにコンパイラがコード生成するのでリンカエラーに遭遇してしまうでしょう。スタブを置いてもよいのですが、そもそも組み込みプログラミングでTLS領域を用意する必要は今の所ないので __gshared というキーワードを使って明示的に .data あるいは .bss 領域に配置されるようにしたほうがよいでしょう。こういった知識を暗黙に要求する場面が多々あるので、初心者からするとすこし敷居が高くなってしまうかもしれません。


どのくらいできるのか

現状だとLチカ、割り込み、タイマー制御、arm semihostingでホスト側に書き込むといったことはできます。Lチカのプログラムは以下のように記述できます。そこそこシンプルに記述できているのではないでしょうか。

import stm32f407discovery;

import stm32f407discovery.led;
import stm32f407discovery.timer;

@nogc:
nothrow:

extern (C) void main()
{
pragma(LDC_never_inline);

auto tim2 = powerOn!"TIM2"();
initLED();

tim2.pause();
tim2.setPrescaler(7999);

while (true)
{
auto ticks = 1000;
foreach (led; LEDS)
{
led.on();
tim2.delay(ticks);
led.off();
tim2.delay(ticks);
}
}
}

void delay(Tim* tim, uint ticks)
{
tim.setAutoreload(ticks);
tim.resume();

while (!tim.isUpdated())
{
}
tim.clearUpdateFlag();
}


他の言語の選択肢

もちろん、AssemblyとC言語以外の選択肢がD言語以外にないわけではありません。MicroPythonは有名ですし、Rustも http://blog.japaric.io/ のように活動的な人がいます。

マイナー言語でも 今回のアドベントカレンダーで紹介された Nimや、 さらにAdaで 書いている 人もいたりします。

個人的にはコンパイル型の静的型付き言語が好みなので、D言語・Rust・Nimあたりに頑張ってもらえたらなあ。。といった感じです。この中だとRustがユーザコミュニティやライブラリの充実度で一歩リードしているのではないでしょうか。


宣伝

C93にサークル参加して、今回の話をチュートリアル形式で進めるようなものを書いてます。興味があれば是非。

https://twitter.com/henteko07/status/930971088351141888