rx-elf-gccでのアプリの作成方法
昨日のrx-elf-gccを使ってアプリケーションを作る方法を紹介します。
Cのプログラムはmainで始まるというのは常識ですが、組み込み用のプログラムをGCCでコンパイルしたとき、そう簡単にいくものではありません。mainがどこから呼び出されるのかという問題と、プログラムやデータをメモリのどこに配置するかという問題があるからです。
昨日のrx-elf-gccでは、newlibに付属のデフォルトのスタートアップコードとメモリマップを使っています。このメモリマップは、/usr/local/tkdn-20110507/rx-elf/rx-elf/lib/rx.ld にあるものが使われるようで、内蔵RAM128kB、内蔵ROM768kBというありえない構成のCPUに特化されています。
したがって、rx-elf-gccでそのままコンパイルしても、決して動かないでしょう。
動くプログラムを作成するには、スタートアップコードとリンカスクリプトを作らなければなりません。
作ってみたサンプルプログラムはこちらにアップロードしました↓
■「rxsample.lzh」をダウンロード
作ったプログラムの概要を簡単に説明しますと、0.5秒周期で割り込みを発生させて、PORT8.4をカチカチ動かすというものです。特電RX62Nボードならば圧電素子が時計のようにカチカチ鳴ります。
上の圧縮ファイルに含まれているファイルは
・intprg.c
割り込みハンドラが並んでいます。
・iodefine_renesas.h
ルネサス提供のiodefine.hを修正(後述)したものです
・main.c
プログラムのメインです
・rx62n_ram_standalone.ld
RAM上にJTAG ICEを使ってロードして動くようなメモリマップにするための指令です
・start.asm
スタートアップコードです
・vect.h
割り込みハンドラのプロトタイプが並んでいます
・vecttbl.c
固定ベクタテーブルおよび再配置可能ベクタテーブルが並ぶ配列を定義しています
・testapp.elf
出来あがった実行形式ファイルです。これをJTAG ICEでダウンロードします。
・makefile
ビルドするための手順が書かれています。
上のmakefileでmakeすればGCCで動くミニマムなものが出来上がります。
これで めでたしめでたし だと面白くないので、簡単に説明します。
RX62Nで動くプログラムをGCCで作成する場合、リンクの際にGNUローダにオプションをいろいろ指定します。前述のスタートアップとメモリマップの問題を手動で解決するためです。
リンカに渡したコマンドは下記のようになります。
rx-elf-ld -Map testapp.map start.o main.o vecttbl.o intprg.o -T rx62n_ram_standalone.ld -L/usr/local/tkdn-20110507/rx-elf/rx-elf/lib/ -lc -nostartfiles -o testapp.elf
太字にしたところがミソです。-T rx62n_ram_standalone.ldで独自のリンカスクリプトを指定し、-nostartfilesでデフォルトのスタートアップを使わないことを指定し、かわりに独自のスタートアップであるstart.oを指定しています。
また、ルネサス提供のiodefine.hはそのままでは使えません。それには2つの理由があって、iodefine.h内で使われている__evenaccessという指令をGCCが解釈できないのと、構造体のビットフィールドが左詰か右詰かという順序が違うようだからです。
だから、
PORT8.DDR.BIT.B4 |= 1;
ではなく、
PORT8.DDR.BYTE |= 0x10;
と、面倒でも書いてやらねばなりません。これはすべての内蔵レジスタに当てはまります。だから、.BITとかいう方法で特定のビットを指定するのは避けなければなりません。
(※KPIT GCCではiodefine.hを右詰にして自前で作り直しているようですが、全部のレジスタが定義されているわけではく、完全ではないようです)
iodefine.hで定義されているマクロが使えないので、割り込み許可レジスタとか、割り込みプライオリティレジスタの設定が超面倒くさいですが、データシートを見れば手動で設定できないことはありません。
こうすることで、RX用GCCを使って動くプログラムが作成できます。
リンカスクリプトやスタートアップコードを変えれば、ROM上でスタンドアローンで動くものや、SDRAM上で動くバージョンなども作れるでしょう。なお、上のスタートアップコードは完璧ではなくて、BSSのクリアやROMからRAMへの転送などが行われていません。それは今後行います。
| 固定リンク
コメント