-2

MSP430 の ISR を書いています。揮発性 PxIFG レジスタを読み取り、最初の命令でスタック変数にコピーします。ISR ジャンプのオーバーヘッドはありますか、または予想できますか

__interrupt void SW_PRESSED_ISR(void)
{
  unsigned short currnet_ifg = P4IFG;
...
}

のようなものにコンパイルする

... Register saving instructions
JSR ...       // jump into ISR
LD  P4IFG ... // load volatile register P4IFG value
...

ISR ジャンプ後の最初の命令がレジスタ ロードである場合、ISR が意図したとおりに機能することはわかっています。私の理解では、MSP430 は、ジャンプ後に 1 つの命令を保証してから、再び中断することができます。ロードがジャンプ後の最初の命令でない場合、P4IFG レジスタが読み取られる前に再び中断される可能性があり、その値が別の値に変更される可能性があるという問題があります。

コンパイラがそのジャンプの直後にロード命令を配置して、別の割り込みが変更される前に常にそのレジスタのコピーを取得することを期待するのは合理的ですか?

ありがとうございました

4

1 に答える 1

1

すべての質問は、使用している MSP430 チップのユーザー ガイドに記載されています。

割り込みはコードによって呼び出されません。これらは、外部イベントによってトリガーされると、CPU によって自動的に実行されます。PC および SR レジスタをスタックに保存し、GIE ビットをクリアし、割り込みベクトルを読み取ってジャンプするには、6 サイクルが必要です。ただし、割り込みが無効になっている場合は、任意の時間だけ割り込みを遅らせることができます。

割り込みハンドラー内では、割り込みは無効になっています (明示的に再度有効にしない限り)。

P4IFG レジスタのビットはコードによって設定されないため、割り込みが有効かどうかは問題ではありません。構成された信号エッジがいずれかのピンで発生するたびに新しいビットが設定されますが (これはいつでも発生する可能性があります)、以前に設定されたビットはクリアされません。

割り込みハンドラで、割り込みフラグを読み取り、読み取ったビットをクリアする必要があります。(割り込みハンドラの実行中に新しいイベントが発生した場合、 is が返された後に新しい割り込みが発生します。)

__interrupt void SW_PRESSED_ISR(void)
{
    uint16_t ifg = P4IFG;
    P4IFG &= ~ifg;

    if (ifg & ...)
        ...
}

ポートの割り込みの 1 つをアトミックに返し、対応するフラグ ビットをリセットする割り込みベクトル レジスタを使用することをお勧めします。

__interrupt void SW_PRESSED_ISR(void)
{
    switch (P4IV) {
    case P4IV_P4IFG0:
        // event at bit 0
        break;
    case P4IV_P4IFG1:
        // event at bit 1
        break;
    ...
    }
}
于 2016-02-15T08:21:06.007 に答える