割り込みについてのメモ

割り込み優先度

参考

https://os.mbed.com/users/okini3939/notebook/mbed256_interrupt/

http://www.naaon.com/modules/dblog1/index.php?page=detail&bid=570

https://os.mbed.com/forum/mbed/topic/983/?page=1#comment-4796
https://os.mbed.com/users/simon/code/Priority/file/2b952ccae54d/main.cpp/

https://os.mbed.com/users/mbed_official/code/mbed-src/file/a11c0372f0ba/targets/cmsis/TARGET_NXP/ここからターゲットのフォルダに入ってターゲット名.hのファイルを見ると書いてある。

設定

https://os.mbed.com/forum/mbed/topic/3732/
割り込みの優先度はすべて最高レベルに設定されてるっぽい。
なので、優先したい割り込み以外の優先度を下げてやればよい。
優先度は0-255で0が高く、255が低い。
設定の変更はNVIC_SetPriority(割り込みNo, 優先度)という関数で変更できる。

今回使う割り込み(GPIOとTicker)のNoは、GPIOがEINT3_IRQn、TickerがTIMER3_IRQn
優先したいのはGPIOなので、Tickerのほうの優先度を1に変更してやればよいはず。

割り込み番号

どの割り込みがどの割り込み番号に割り当てられてるか?

以下の図でどこのPIN使ってるか?TXやRXの番号は?を調べる。
ピン配置と名前

以下データシートでどの名前になっているか探す。
データシート

以下LPC1768の割り込み番号定義
ヘッダファイル

例えば、p13,p14のSerial通信の割り込み番号が知りたい。
ピン配置と名前の図から、p13,p14はTXD1,RXD1とわかる。
データシートを見ると、TXD1,RXD1はUART1のアウトプットとわかる。
ヘッダファイルの割り込み番号定義を見ると、UART1_IRQnというのがあるので、これを使う。

テストコード

#include "mbed.h"

InterruptIn gpio(p21);
Ticker tickerIrq;
Timer timer;
int i=0;

void at_irq()
{
    printf("Interrupting(#%02d, %06d[ms]) ",i , timer.read_ms());
    for(int j=0;j<1000;j++){
        printf(".");
    }
    i++;
    printf("end\n");
}

void at_gpio()
{
    printf("!!GPIO!!");
    wait(1);
}

int main()
{
    gpio.rise(&at_gpio);
    timer.start();
    tickerIrq.attach(&at_irq, 2);

    while(1) {
        if(i==5) {
            NVIC_SetPriority(TIMER3_IRQn, 1);
            printf("--------Priority changed---------\n");
        }
    }
}

実行順

タイマー割り込み処理中にGPIOが呼ばれると先に実行されて、タイマー処理に戻る。
GPIO割り込みによってタイマー割込み処理が遅れて次のタイマー割り込みが入ると、処理待ちにストックされる。このため、前のタイマー処理が終わるとすぐ次のタイマー処理が実行されてmainループは飛ばされる。(この流れに注意しないとiをフラグにした優先度の処理がスキップされてしまう)
ストックされた割り込み処理が全部終わるとメイン処理に戻り割り込みタイミングも元に戻る。

割り込みが発生しない!!!

GPIOの割り込みを2つ定義して、1つの割り込みをdisableしたら、もう一つも割り込みしなくなってた。原因を見つけるのにずいぶん時間がかかった。

プログラムから割り込みを発生させる

Timeout (ワンショットタイマー割込み)を指定時間0でattachすれば即座に割り込みを発生させることができる。


Please log in to post comments.