RXマイコンでの割込み禁止区間の作り方

割込みの禁止区間の作り方について質問させてください。

現在の環境は、
RX64Mマイコン
CC-RX V3.000 コンパイラ
e2studio
スマートコンフィグレータ
を使用しています。

外部とスマートコンフィグレータで生成したコンポーネント(Config_SCIFx)を使用して通信のやり取りをしています。
生成した「R_Config_SCIF9_Serial_Receive」関数を無限ループ内で利用してデータの受信を行っているのですが、
割込みタイミングによっては、データ受信直後に「R_Config_SCIF9_Serial_Receive」が再び呼び出されることで、取得したデータが損失する危険性があるかなと思っています。
下記のコード内で示した位置で割込み禁止にするには具体的にどうすれば良いのでしょうか。

while(1) {

uint8_t array[DATA];        

//この位置か

if(0 == Flag)                 //割込みのコールバック関数にて立てているフラグが立っていないときに実行
{
    
         R_Config_SCIFx_Serial_Receive(array, DATA);

//この位置まで割込み禁止


}
else 
{
        Flag = 0;                //受信が完了し割込みがかかるとフラグが立つので、次のデータ受信をするためにフラグをもどす
}

    //後続の受信データ処理

    }

   

Parents
  • setpsw_i()とclrpsw_i()と言うマクロが用意されています。PSWのIビットの操作をします。

    質問とは直接関係ないですが、このコメントで指定された箇所ですとFlag=1で割り込み禁止解除ができないです。

  • Yamamoto様

    PSWのIビット操作で可能なのですね。マクロという事は、何かヘッダファイルが必要なのでしょうか。
    すいません。割込み禁止解除ができないとはどういう意味でしょうか。

  • //この位置まで割込み禁止
    この場所でsetpsw_i()を書いて割り込みを有効化すると

    clrpsw_i()で割り込み禁止にしたあとelseブロックに入ると解除されないと言うことです。

    マクロはmachine.hで宣言されています。

  • シリアル通信以外の割り込みは友好のままが良い場合は

    IEN(x, y) = 0 or 1;

    これが使えます。例えばSCI5のRXI5、受信割り込みを一時的に止めたいなら

    IEN(SCI5, RXI5) = 0U;

    割り込みを再開なら

    IEN(SCI5, RXI5) = 1U;

    スマートコンフィギュレータの生成コードを読むと参考になると思います。

  • Yamamoto様
    void __clrpsw_i(void) 【V2.05.00以降】
    void __setpsw_i(void) 【V2.05.00以降】
    検索しましたら、私のCCRXV3.00では上記の表記になるようでした。
    どこに書いてあるか何とかわかりました。

    理解しました。条件分岐内に書くとまずいですね。

    __clrpsw_i();
    if(0 == Flag)                 //割込みのコールバック関数にて立てているフラグが立っていないときに実行
    {  
             R_Config_SCIFx_Serial_Receive(array, DATA);
    }
    __setpsw_i();

    else 
    {
            Flag = 0;             
    }

    であれば、良いという事でしょうか。

    宣言を教えていただきありがとうございます。

  • それだと文法エラーです。

    __clrpsw_i();
    if(0 == Flag)                 //割込みのコールバック関数にて立てているフラグが立っていないときに実行
    {  
             R_Config_SCIFx_Serial_Receive(array, DATA);
    }

    else 
    {
            Flag = 0;             
    }

    __setpsw_i();

    こうです。

  • 生成コード内で見つけました。シリアル通信のスタート関数内及びストップ関数内で操作されていました。こういった機能だったのですね。通信だけ割込み禁止できるのはありがたいです。大変勉強になりました。

  • マクロの前にある__は要りません。

  • 文法についてもありがとうございます。

    https://tool-support.renesas.com/autoupdate/support/onlinehelp/ja-JP/csp/V4.01.00/CS+.chm/Compiler-CCRX.chm/Output/ccrx04c0206y.html

    内に、下記のような記述があるので、あえて__が必要なのかなと思いました。

  • 割り込みの優先度設定通りに多重割り込みを実現したい場合は割り込みハンドラの中で自分でsetpsw_i()を書いてやる必要があります。これはマイコンの仕様によって割り込みハンドラに入った直後はIフラグがクリアされた状態になるためです。直近のリリースバージョンではコンポーネント設定に多重割り込み設定が入っているものもあるのでそれをチェックするとsetpsw_i()を生成してくれます。すべてのコンポーネントが対応しているわけではないので注意です。その時は自分でset_psw_i()を書いてあげる必要があります。その際ですが、特別なコメント行でくくることでコード生成時に追加したコードが消されないようにできます。バッファリング処理などが入っているものはこれが役に立ちます。SPIマスターとかです。そのうち対応すると思いますけどね。

    /* Start user code */

    /* End user code */

  • Yamamoto様
    つまり非対応になっているものについては、
    #pragma interrupt r_Config_SCIF9_txif_interrupt(vect=VECT(SCIFAx,TXIFx))

    で割込み関数が指定されているものについては、

    static void r_Config_SCIFx_txif_interrupt(void)
    {

       /* Start user code */
        set_psw_i();
       /* End user code */


      ~割込み処理内容~

    }

    のように関数内に割込み許可をしておかなければ、割込みのネストがされないという事でしょうか。

  • そうなんです。マイコン自体の仕様です。Iフラグセットしないとダメなんです。他のマイコンから来た人はもしかしたら知らないかもしれないところですね。私は知らなかったです。

Reply
  • そうなんです。マイコン自体の仕様です。Iフラグセットしないとダメなんです。他のマイコンから来た人はもしかしたら知らないかもしれないところですね。私は知らなかったです。

Children
  • Yamamoto様

    詳細にありがとうございます。この仕様を理解していなかったので、危うく割込みを逃すところでした。今回使用しているコンポーネントは非対応だったので、記述の必要がありました。
    割込みについて知らないことばかりでしたが、理解が進みました。ありがとうございました。