コンペアマッチ割り込みとシリアル通信受信割り込みの競合

SH7216を使用してシリアル通信を試みていますが、受信割り込みを何度か発生させていると

一般不当命令の例外が発生し、全ての割り込み処理が止まってしまうようです。

現状、CMT0(周期100μs)、CMT1(周期10ms)、シリアル通信の受信割り込み(RXI0)

の3種類のみ有効となっている状態です。

優先度設定レジスタの設定状態は、

RXI0 > CMT1 > CMT0

となっています。

以上の状況で、原因が思い当たればどなたかご教示頂けないでしょうか?

  • わわいです。

    どうも勘違いされてるようですが、

    一般不当例外が出る、のではなく、あなたのコードのどこかで不正アクセスが発生して、それによりプログラムが暴走して、たまたまその例外が発生した、あるいは発生したように見える、だけです。

    不正アクセスが起こっているところを探しましょう。

  • わわいです

    もうちょい補足しときますと、

    いくら割り込みが競合しようがなにが起ころうが、正常にC言語のコードが実行される限り、不当例外が発生することはありえません。

    それが起きるのは、暴走している場合、ぐらいしかありません

  • 現状、割り込み処理で実行している処理や、mainループで実行しているアイドル処理は

    不正アクセスが起きそうな処理を省いており、汎用出力への出力信号のビット操作くらいしか

    していないと思っています。

  • わわいです

    あとはスタック領域の不足(スタックエリアを増減させてみる)、想定外の割り込み/例外発生(すべてのベクタ領域にデフォルトハンドラを設定)、など、暴走しそうな事項を潰していくことです

    コードの方も、その割り込みだけを発生させるようにしといて、メインルーチンは空ループ、割り込みハンドラも最小のコードにしといて、その不当例外が出るかを確認しましょう。

    そこから本番のコードを追加していき、どの段階から例外が出るか探っていきます。

    ゼロ除算例外、とかアライメント異常例外、などコードのバグによる例外については、スタックトレースから簡単にバグの箇所を特定できますが、この不当例外の場合は、プログラムの暴走から副次的に発生する例外なため、スタックやレジスタの値は壊れてしまうため、コードの異常を特定することは簡単にはできません

    んで、注意すべきは、バグがあるから例外が出ている、のではなく、バグがあって、たまたま例外が出た結果になっている、ってことを肝に銘じましょう

    場合によっては、何もエラーは出ず、暴走からふつうにリセットエントリに飛んで行く場合もあります。

    なんかしらんけど途中でリセットかかってしまう、ってのはよくある質問ですねー