PICマイコンのスタックについて
作成者:mou-mou
PICマイコンは、スタックをRAM領域に置きません。RAM領域とは別にハードウエアのスタックが用意されています。ハードウエアのスタックはデバイスの規模によって違いますが、最小で2個しか持っていないものも多くあります。
CCS Cコンパイラでのスタックの消費
ハードウエアスタックは、関数コールする毎に戻りアドレスを保存するためにスタックを1つ消費します。実際には、すべての関数コールでスタックを消費することは無く、1箇所からのみ呼び出される関数に関しては、コンパイラはジャンプ命令を使用することでスタックを消費しないようにコンパイルします。しかし、それでもスタックが2個の場合、関数を機能毎に細分化すると、すぐにスタック不足となってしまいます。その様な場合には、複数個所から呼ばれる関数でも、インライン関数にすることでスタックの消費を回避できます。しかし、インライン関数にすると、ROM消費量は当然増加してしまいます。
スタックが不足するようプログラムを作成してコンパイルしても、コンパイラは警告等を発することはありません。実際にプログラムを実行すると、スタック破壊を起こして、PICマイコンは暴走状態に陥ります。
プログラマはスタック消費量を常に意識してコーディングに取り組む必要があります。
インライン関数化する場合のテクニック
例えば50ワードの関数が10箇所からコールされる場合、単純にインライン関数にすると500ワード消費してしまいます。ROMサイズの小さなPICマイコンを使用した場合は非常に厳しいと考えます。
その様な場合は、スタックの空きの無い下位層から呼ぶ関数と、空きの有る上位層から呼ぶ関数を階層化することで最適化することをお奨め致します。
/** * スタックの空きの無い層から呼ぶ関数 */ inline static void subroutine_inline(void) { : : } /** * スタックの空きの有る層から呼ぶ関数 */ void subroutine(void) { subroutine_inline(); }
仮に、subroutine_inlineが50ワードでsubroutineが10ワードとした場合、2箇所からはsubroutine_inline、残り8箇所からはsubroutineをコールした場合、110ワードの消費で抑えることが出来ます。