何故'Interrupts disabled to prevent re-entrancy'の警告が出るのですか?

PICのハードウェア・スタックが限られているためCCSコンパイラの制限は関数内で再帰を使用できないことです。
これは割り込み処理以外で呼び出される関数内で関数を呼び出そうとする場合に影響します。即ち、 割込み処理以外で割り込み処理で使用する関数を呼び出す場合に関数の再帰呼び出しが発生する可能性があります。
このためコンパイラは割込み処理以外で割込み処理で使用する関数を呼び出そうとする場合に警告メッセージを表示します。
偶発的な再帰を防ぐためにコンパイラはその割込み処理以外で関数を呼び出す場合に関数内での割り込みを無効にします。


次のコードを見て下さい:
#int_rda
void ISR_RDA(void)
{
StuffByte();
}
void SomeFunc(void)
{
StuffByte();
}
上記サンプルでの様にStuffByte()は割り込み処理中に割り込みの内側で呼び出されSomeFunc()の内部でも呼び出されます。
StuffByte()が実行され割り込みが発生した場合、StuffByte()によって修正されたスクラッチとレジスタが SomeFunc()に戻ったときに全て不正なもとなってしまいます。

ここにいくつかの回避策を示します:
  • #inlineプリ-プロセッサ・コマンドを使ってStuffByte()をインライン展開する
  • 新しい関数にStuffByte()をコピーしStuffByteISR()としてISRでこの新しい関数を呼び出す これら2つの回避策はStuffByte()のコードを別々に2つ作成するので、StuffByte()中でISR割り込みが発生した場合、 プログラムは再帰的に同じコードを呼び出しません。