« RX用GCCをビルド&公開しました | トップページ | rx-elf-gccでprintf等のライブラリを使う »

2011.05.09

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で動くミニマムなものが出来上がります。
Rxsample

これで めでたしめでたし だと面白くないので、簡単に説明します。

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への転送などが行われていません。それは今後行います。

|

« RX用GCCをビルド&公開しました | トップページ | rx-elf-gccでprintf等のライブラリを使う »

コメント

コメントを書く



(ウェブ上には掲載しません)




« RX用GCCをビルド&公開しました | トップページ | rx-elf-gccでprintf等のライブラリを使う »