builtin.Abi.eabi);ーのようになります。ハードウェアに合わせたリンカスクリプトを用意して指定します(17行目)。その後最後に成果物をバイナリ形式に変換させます(18行目)。ファームウェア書き込みプログラムで扱いやすくなります(ELF形式に対応しているプログラムを用いる場合は省略して良い)。ここまで準備すれば目的のハードウェアでのベアメタル開発ができるようになります。APIという面白い機能があります。LPC81xシリーズのブートROM領域にはISP用制御コードや初期化コードの他にUSART、I2C、パワーマネジメント機構の制御ルーチンが含まれていて、それらを呼び出すと簡単な通信を自分でレジスタを読み書きするコードを書くことなく行うことができます。そこで試しにUSARTの制御ルーチンを呼び出して使ってみることにしました。Manualによるとそれぞれの制御ルーチンは関数ポインタとしてROM上に位置が保持されていて、ペリフェラルごとにそれら関数ポインタをメンバにもつ構造体としてまとめられています。これらを呼び出すにはその構造体をソースコードで定義しておいてそのポインタを作り、それにROM上に示されているアドレスをセットすれば良いわけです。ABIを合わせるブートROMのルーチンはC言語のABIに合わせて作られたファームウェアから呼び出すことが想定されているように見える(実際、LPC81xのユーザマニュアルではルーチンの定義がC言語で記述されている)ので、これからZigで書くファームウェアから呼び出すときもそのルールに合わせる必要があります。型を使う必要があります。それらに気をつけながらUARTの制御プログラムを書くと次のリンクのコードのようになりました。APIがすべて準備してくれるわけではないらしいところで、このコードのうち103行目から105行目は大体の実装を終えてデバッグする中で最終的に追加したコードです。APIを呼び出す前に行う必要があるようです(それもUSART0〜2のすべてのビットを立てる必要がある)。APIについての部分に書かれていなかったので、動作しない原因がこれだとわかるまで時間がかかりました。エコーバックしてみる最後にルーチンを呼び出して実際に使えていることを確かめるためにエコーバックプログラムを実装してみました。このGitHubリポジトリに上げているので是非見てください。今後やりたいことなど次はI2Cのルーチン呼び出しを試して、それを元に目覚まし時計のファームウェアを仕上げていきたいと思っています。ビルドコードを改良してビルド時にターゲットや出力形式を指定できるようにしたいとも思っています(もっとも今回紹介したプログラムはハードウェアに依存しまくっているのであまり意味がありませんが)。おわりにエコーバックプログラムのファームウェアサイズは4.0kBだったのでROMサイズの約25%です。この調子なら載せたい機能を載せられそうな気がしてきたので良かったと思います。開発の際には今年のセキュリティキャンプで勉強させていただいた開発手法(デバッグのやり方、逆アセンブル、リンカスクリプトの意味など)が非常に役に立ちました。講師・チューターの皆さん、ありがとうございました。