PDG2で提供していない周辺機能を使ったとき割込み設定処理は?

RX63N cs+ PDG2を使用しています。

PDG2で提供していない周辺機能を使ったとき割込み設定処理はどのように組み込んだらよろしいでしょうか。

例えばcanを使いたい時など?

ちなみに割込みを使わなければ、勝手に追加すればよいことはわかりました。

しかし、割込み設定はPDG2にしっかり組み込まれているため、悩んでいます。

  • わわいです
    まあ、生成されたソースの該当箇所は修正し、追加部分は追加していく、ということになります。
    修正箇所は(おそらく)以下の2点ですね
    ・割り込みベクタ
    ・割り込みサービスルーチン
    あとは、CANの実装のコードを追加していくというはなしになります
  • sakuraisanさん、こんにちは。NoMaYと申します。

    > 割込み設定はPDG2にしっかり組み込まれている

    これはどういうことを指していますか? PDG2(というかRPDL)のソースの割り込み設定は、以下のように#pragma interruptで行われていて、通常の割り込みベクタテーブル(通常の割り込みベクタ配列)はソース上に存在していません(通常の割り込みでは無く、例外なら、例外ベクタテーブルが存在しますが)ので、上の話と噛み合わないような気がするのです。他方で、グループ割り込みに関しては、以下のようになっていて、ここら辺に何か追加しなければならない場合は、確かに少し面倒ですけれども。

    通常の割り込みの例1

    Interrupt_SCI.c

    #if FAST_INTC_VECTOR == VECT_SCI0_RXI0
    #pragma interrupt Interrupt_SCI0_RXI0(vect=VECT_SCI0_RXI0, fint)
    #else
    #pragma interrupt Interrupt_SCI0_RXI0(vect=VECT_SCI0_RXI0)
    #endif
    void Interrupt_SCI0_RXI0(void)
    {
    以下省略

    通常の割り込みの例2

    Interrupt_SPI.c

    #if FAST_INTC_VECTOR == VECT_RSPI0_SPRI0
    #pragma interrupt Interrupt_RSPI0_SPRI0(vect=VECT_RSPI0_SPRI0, fint)
    #else
    #pragma interrupt Interrupt_RSPI0_SPRI0(vect=VECT_RSPI0_SPRI0)
    #endif
    void Interrupt_RSPI0_SPRI0(void)
    {
    以下省略

    グループ割り込みの例

    Interrupt_INTC.c


    #if FAST_INTC_VECTOR == VECT_ICU_GROUP12
    #pragma interrupt Interrupt_Group_12(vect=VECT_ICU_GROUP12, fint)
    #else
    #pragma interrupt Interrupt_Group_12(vect=VECT_ICU_GROUP12)
    #endif
    void Interrupt_Group_12(void)
    {
        do
        {
            /* RSPI0 error interrupt */
            if (ICU.GRP[GRP_RSPI0_SPEI0].BIT.IS_RSPI0_SPEI0 == 1)
            {       
                /* Call the user function */
                if (rpdl_SPI_error_callback_func[0] != PDL_NO_FUNC)
                {
                    rpdl_SPI_error_callback_func[0]();
                }
            }

    途中省略

            /* SCI12 error interrupt */
            else if (ICU.GRP[GRP_SCI12_ERI12].BIT.IS_SCI12_ERI12 == 1)
            {
                if (sci_global[12].RX_Error_callback_func != PDL_NO_FUNC)
                {
                    /* Call the error handler */
                    sci_global[12].RX_Error_callback_func();
                }
                else
                {
                    /* Clear the SSR error flags;
                    Preserve MPBT(b0) and write 1 to reserved bits (b6 and b7)*/
                    SCI12.SSR.BYTE = (uint8_t)((BIT_7 | BIT_6) | (SCI12.SSR.BYTE & (uint8_t)BIT_0));
                }
            }

            /* Call the user function */
            if (rpdl_INTC_group_callback_func[7] != PDL_NO_FUNC)
            {
                rpdl_INTC_group_callback_func[7]();
            }
        }while(ICU.IR[IR_ICU_GROUP12].BYTE != 0x00u);
    }
  • わわいさん NoMaYさん ご回答ありがとうございます。sakuraisanです。最初のご挨拶忘れてました。すみません。

    ご回答をいただいたのですが、まだよく理解していません。

    PDG2を使ったプロジェクトですと、AddFormPDG内にio/cmt/sci/等のフォルダーが作成
    されます。
    さらにi_srcの中にInterrupt_CMT.c等があります。
    ここにInterrupt_CAN.cを作成できればよいのですが、
    Interrupt_CAN.cのソースプログラムの作成方法がわかりません。

    PDG2を使用しないときはintprg.cに追加すればよかったようですが。
    PDG2を使用するとintprg.cが入っていません。

    すみませんが、再度、具体的な方法をお教え願えませんでしょうか。
    よろしくお願いいたします。
  • sakuraisanさん、こんにちは。NoMaYです。

    >PDG2を使用しないときはintprg.cに追加すればよかったようですが。

    この文面をしばらく見ていて、ふと感じたのですが、PDG2を使わずに割り込みを使った経験というもの自体がそもそも無かったりしますか?

  • NoMayさん 返信ありがとうございます。
    たしかにCS+ではPDG2を使いますので使っていませんが、HEWでは使っています。
    この程度の経験では大変なことでしょうか。
    よろしくお願いします。
  • sakuraisanさん、こんにちは。NoMaYです。

    HEWでPDG2を使わずに割り込みを使った経験があれば出来ると思います。その経験があれば、ICUのIERレジスタやIPRレジスタ、CPUのRTE命令、CC-RXの#pragma interruptディレクティブ、といった話は省いても大丈夫そうですね。

    それで、CANの割り込みプログラムの作成方法ですが、HEWでPDG2を使わずに割り込みを使った時と同様に、割り込み関数を書き、#pragma interruptでその関数をベクタ番号と共に指定する、だけで良い筈です。今思うに、PDG2(というかRPDL)が提供している周辺機能の割り込み関数と共存させる為に従うべき約束事のような割り込み関数の書き方があるのでは?と考えての質問だったのかも?という気がしていますが、そういった共存させる為に従うべき約束事は存在していないようです。ただし、RX63Nのハードウェアマニュアルを見たところ、CANのエラー割り込みがCANだけで纏まっているとは言え、グループ0に割り当てられていましたので、このグループ割り込み処理に関してはR_INTC_CreateGroup()関数で割り込み処理関数をPDG2(というかRPDL)に登録することになります。

    あと、intprg.cが無くなったことで困惑されているようですので、以下、それについて書きます。intprg.cは、vect.hに羅列されている#pragma interrupt指定の関数の実体(とは言っても、実際の割り込み処理が記述された関数を呼び出す為の器というか入れ物というか、そういう役割の関数)が羅列されているソースですが、vect.hの対となる箇所と合わせて切り出して別ソースに分離しても構わないものです。CANに関してならば、vect.hとintprg.cの以下の部分を両方合わせて別ソースに貼り付けて、後は割り込み処理の中身を書けば良いです。なお、そのソースはInterrupt_CAN.cという名前である必要は特に無いです(その名前でも構わないです)。また、AddFromPDG内やi_src内である必要も無いです(というか、そうしようとすると、厄介なことになってしまいます)。

    vect.h



    // CAN0 RXF0
    #pragma interrupt (Excep_CAN0_RXF0(vect=48))
    void Excep_CAN0_RXF0(void);

    // CAN0 TXF0
    #pragma interrupt (Excep_CAN0_TXF0(vect=49))
    void Excep_CAN0_TXF0(void);

    // CAN0 RXM0
    #pragma interrupt (Excep_CAN0_RXM0(vect=50))
    void Excep_CAN0_RXM0(void);

    // CAN0 TXM0
    #pragma interrupt (Excep_CAN0_TXM0(vect=51))
    void Excep_CAN0_TXM0(void);

    // CAN1 RXF1
    #pragma interrupt (Excep_CAN1_RXF1(vect=52))
    void Excep_CAN1_RXF1(void);

    // CAN1 TXF1
    #pragma interrupt (Excep_CAN1_TXF1(vect=53))
    void Excep_CAN1_TXF1(void);

    // CAN1 RXM1
    #pragma interrupt (Excep_CAN1_RXM1(vect=54))
    void Excep_CAN1_RXM1(void);

    // CAN1 TXM1
    #pragma interrupt (Excep_CAN1_TXM1(vect=55))
    void Excep_CAN1_TXM1(void);

    // CAN2 RXF2
    #pragma interrupt (Excep_CAN2_RXF2(vect=56))
    void Excep_CAN2_RXF2(void);

    // CAN2 TXF2
    #pragma interrupt (Excep_CAN2_TXF2(vect=57))
    void Excep_CAN2_TXF2(void);

    // CAN2 RXM2
    #pragma interrupt (Excep_CAN2_RXM2(vect=58))
    void Excep_CAN2_RXM2(void);

    // CAN2 TXM2
    #pragma interrupt (Excep_CAN2_TXM2(vect=59))
    void Excep_CAN2_TXM2(void);

    intprg.c



    // CAN0 RXF0
    void Excep_CAN0_RXF0(void){ }

    // CAN0 TXF0
    void Excep_CAN0_TXF0(void){ }

    // CAN0 RXM0
    void Excep_CAN0_RXM0(void){ }

    // CAN0 TXM0
    void Excep_CAN0_TXM0(void){ }

    // CAN1 RXF1
    void Excep_CAN1_RXF1(void){ }

    // CAN1 TXF1
    void Excep_CAN1_TXF1(void){ }

    // CAN1 RXM1
    void Excep_CAN1_RXM1(void){ }

    // CAN1 TXM1
    void Excep_CAN1_TXM1(void){ }

    // CAN2 RXF2
    void Excep_CAN2_RXF2(void){ }

    // CAN2 TXF2
    void Excep_CAN2_TXF2(void){ }

    // CAN2 RXM2
    void Excep_CAN2_RXM2(void){ }

    // CAN2 TXM2
    void Excep_CAN2_TXM2(void){ }

     

  • NoMaYさん 早々のご返信 ありがとうございます。
    NoMaYさんがおっしゃるように下手に追加するとPDG2(というかRPDL)が提供している周辺機能の割り込み関数を邪魔するか、壊してしまうのではないかと思っていました。心配しなくていいんですね。
    通常の#pragma interruptでその関数をベクタ番号と共に指定するで追加できるようです。
    トライせずに質問してしまいました。試してみます。
    また、グループ割り込みに関しては、ハードウェアーマニュアルをよく読んで理解したいと思います。
    ありがとうございました。