Out of ROM対策


【Out of ROMエラーとは】

 CCSのCコンパイラは、最適化処理として、1回しか呼ばれない関数は
スタックを使わないように、サブルーチンでは無く、連続したプログラムとして
インラインで展開します。
 複数回呼ばれる関数は、関数を出来るだけ共用してメモリを減らそうと
するため、CALLで呼ばれるサブルーチンとしようとします。
 しかしスタックメモリのレベルを使い切ると、それ以上はサブルーチンには
展開できないので、自動的に直接その場で展開して連続のプログラムとして
作成するようになってしまいます。(INLINE展開という)
 特に、8kWを超えるような大きなサイズのプログラムになると、多くの場合
このINLINE展開が行われるようになり、展開後のプログラムサイズが大きく
なって2kWの境界を越えるようになってしまうため、ページの自動配置が
うまく機能せずエラーメッセージを出力することがあります。
このような時には、コンパイラは下記のエラーメッセージを出力します。
特にまだメモリが十分残っているのにエラーとなる場合がこれに相当します。
 
 Out of ROM, A segment or the program is too large

【エラー対策】

 このエラーが出た場合には、本来はコンパイラが出力した「Call Tree List」
を見て判断すべきなのですが、解決策は、下記のようにします。

@ 全体で1回しか使われない関数はINLINE展開されるので、この関数の
直前に#separateプリプロセッサ行を追加して、明確にSEPARATEするよう
指示します。これで、INLINE展開が減るので、ページを超える確率が減ります。
その代わりスタックメモリを使いますので最大使用スタックレベルをチェックして
おく必要があります。この推定の最大使用スタックレベルはコンパイラの展開
リストの最初に表示されています。

A INLINEで展開されている比較的大きな関数の直前に#separateを追加する。
これを追加することで、明確にサブルーチンとして展開するよう指示します。
どの関数がINLINE展開されているかは、Call Tree Listを見ると判ります。
このLISTは、拡張子が、「tre」というファイルで、プロジェクトのディレクトリ内に
生成されています。

 この2つの対策をいくつか試してみて、正常になるようにします。
注意すべきことは、関数の前に#separateを追加した時には、その関数の
プロトタイプ宣言の行の直前にも#separateを追加する必要があることです。
これを追加しないとコンパイルエラーになり下記のようなメッセージを出力します。

 Function definition different from previous definition




       目次ページへ