22
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

GNU Arm Embedded Toolchainとシステムコールの実装について

Posted at

GNU Arm Embedded Toolchainとnewlibとシステムコール

ARMでのCortex-M用のフリーなコンパイラとしては、GNU Arm Embedded Toolchainがよく使われています。

GNU Arm Embedded ToolchainはOSのない、bare metal環境に標準対応しています。OSがない場合、通常はOSが用意している標準Cライブラリ(libc)もないため、自前で用意する必要があります。

GNU Arm Embedded Toolchainでは、組込み環境向けの標準Cライブラリであるnewlib(+libgloss)が同梱されています。

このnewlibの特徴的なところに、システムコールの詳細を実装していない点があります。具体的に言うと、例えばメモリを確保するC標準関数であるmalloc()関数自体は実装されているのですが、この関数は空きメモリの中から使いたいメモリの確保を行うシステムコール_sbrk()を内部で呼んでいます。この_sbrk()の方が実装されていないのです。そのため、素朴にビルドするとリンク時にエラーになるので、別途_sbrk()などのシステムコール実装を用意する必要があります。

システムコールを使えるようにする

システムコールを使えるようにするには3つの方法があります。

  1. 自前で実装する
  2. libnosysを使う
  3. rdimonを使う(semihosting環境を使う)

以下、それぞれ見ていきます。

1. 自前で実装する

普通に実装すれば、個別の環境に応じた形で対応できます。ひたすら頑張る方式です。
が、そこまでしなくても対応するための選択肢が他にもあります。

2. libnosysを使う

最低限のものでよければ、libnosysを使うという方法があります。
libnosysはnewlibに同梱されているもので、その実体は以下にあります。

これを見て分かる通り、だいたいの関数はerrnoにENOSYSを設定して-1を返すだけの、とりあえずリンカのエラーを出さないようにするだけのものです。まともに使えるようになるわけではありません。とはいえ_sbrk()だけは(ないと困るからだと思いますが)まともに使えるようにちゃんと実装してあります。もっとも、これもヒープの大きさのチェックなどはなく、溢れたら突き抜けるだけの簡易な実装です。

使い方は、以下のようにgccのオプションに--specs=nosys.specsを追加します(※注 -lnosysを追加する必要があるか要確認)

$ arm-none-eabi-gcc --specs=nosys.specs $(OTHER_LINK_OPTIONS)

3. rdimonを使う(semihosting環境を使う)

もうちょっと特殊なケースとして、Semihosting環境を使う例があります。

Semihosting環境とは、ターゲット環境とホスト環境とがつながっている状態で、一部の機能をターゲット側とホスト側の両方で分担して実行するものです。

セミホスティングとは、ARMターゲット上で実行されているコードで、デバッガを実行しているホストコンピュータの入出力機能と通信し、これを使用することを可能にするメカニズムです。
これにより、ホストコンピュータのキーボード入力、画面出力、ディスクI/Oなどを使用できます。例えば、このメカニズムを使用すると、printf()scanf() などの Cライブラリ関数で、ターゲットシステム上の画面とキーボードではなく、ホストの画面とキーボードを使用することができます。

(「ARM® コンパイラ ソフトウェア開発ガイド v5.6  7.1 セミホスティングとは」http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0471c/Bgbjjgij.html より)

こうすると、ホスト・ターゲット間の通信さえできれば、細かい機能はホスト側でよろしくやってくれるので、ターゲット側の実装を頑張らなくて済むようになります。

このようなSemihosting環境の実現のために、rdimon.specsというものがあります。rdimonというのは、どうもRDI(Remote Debug Interface) MONitorの略のようです。
このシステムコールの実体は以下にあります。

これを使うには、以下のようにgccのオプションに--specs=rdimon.specsを追加します。

$ arm-none-eabi-gcc --specs=rdimon.specs $(OTHER_LINK_OPTIONS)

参考

22
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?