RXv3コアのレジスタ一括退避機能の使い方(Register Bank Save Function Usage)を調べてみるスレッド

こんにちは。NoMaYです。

RXv3コア搭載の120MH動作のRXマイコンも、RX66T以降、RX671、RX66N、RX660と品種が増えてきましたが、RXv3コアのセールスポイントの1つであるレジスタ一括退避機能の使い方が今ひとつピンと来ません。そこで、いつものように、ちょっと好奇心からスレッドを立ててみました。(注: RX66Tは、160MHz動作、レジスタ一括退避機能未搭載、です。) いつものように、ぼちぼちと続きます。

ホワイトペーパー
卓越したMCU性能と電力効率を実現するRXv3コア
2019年10月
www.renesas.com/jp/ja/document/whp/introducing-rxv3-core-superior-performance-excellent-power-efficiency#page=6

割り込み応答時間の改善

モータ制御システムなどは、高速な割り込み処理によるリアルタイム性能が必要となってきます。

RXv3コアには、割り込み処理時にレジスタを高速退避/復帰するために、オプション機能として、レジスタ退避バンクと呼ばれる専用メモリを実装しています。図6に示すように、レジスタ退避バンクを使用することで割り込み応答時間を短縮でき、割り込み処理全体の時間を短縮することができます。 割り込み処理ルーチンの中で、SAVE命令を使用すると汎用レジスタとアキュムレータを1クロックで専用メモリに保存できます。RSTR命令は、保存されたレジスタを3~6cycleで復元します。レジスタ退避バンクは専用メモリを複数面持っており、多重割り込みにも対応することが可能です。

図6.割り込み応答時間の改善

レジスタ退避バンクは、割り込みハンドラだけでなく、RTOSコンテキスト切り替えにも使用できます。 RTOSコンテキスト切り替え時間は、レジスタバンク保存機能により最大20%高速化します。


  • こんにちは。NoMaYです。

    またちょっと脱線しますけれども、RA6T2の先日のアプリケーションノートのサンプルプログラムの最適化オプションが-O0でしたので、ふとした思い付きですけれども、ちょっと好奇心から1つ前の投稿と同じ関数を最適化レベルを最低にしてCC-RX/ICCRX/GNURX/GNUARMでコンパイルしてリストファイルを出力させてみました。興味深いことに、ICCRX以外は(デバッガのウォッチ機能にとって都合が良いので)レジスタ渡しされた引数をスタック上に置き直しているのですが、ICCRXだけは置き直すことをしていませんでしたね。また、ICCRXでは、そのことに加え、実行速度優先最適化をしないことにしたことで、CISC命令セットとしてRXコアはコードサイズがコンパクトになるという性質が優勢に立ったのか、1つ前の投稿の時よりも関数のサイズが小さくなっていましたね。ちょっと珍しいことではないかなぁ、と思われます。(ICCRXのコード生成の指針が実際にそうなのであれば、目から鱗が落ちた、ような思いです。それでもデバッガのウォッチ機能にとって不都合が無いですので。[追記] 置き直すことをせずに済むのはリーフ関数の場合だけかも知れないかな。それ以外の関数においてはデバッガのスタックトレース機能の変数/引数の内容表示機能に支障が出そうだからです。)

    各コンパイラでの関数のサイズです。

     CC-RX  -optimize=0   82bytes (10進数)
     ICCRX  -On --no_cse --no_unroll --no_inline --no_code_motion --no_tbaa --no_cross_call --no_clustering   52bytes (10進数)
     GNURX  -O0  124bytes (10進数)
     GNUARM  -O0  152bytes (10進数)


    (参) 1つ前の投稿の時の各コンパイラでの関数のサイズです。

     CC-RX  -optimize=max -speed  38bytes (10進数)
     ICCRX  -Ohs --no_size_constraints --no_cross_call  59bytes (10進数)
     GNURX  -O3  74bytes (10進数)
     GNUARM  -O3  64bytes (10進数)


    試したソースは省略します。(1つ前の投稿と同じです。)

    CC-RXでのリストファイル

    00000000                         _rot_2:
    00000000 7100E0                         ADD #0FFFFFFE0H, R0
    00000003 A101                           MOV.L R1, 10H[R0]
    00000005 A08A                           MOV.L R2, 0CH[R0]
    00000007 A083                           MOV.L R3, 08H[R0]
    00000009 E5000407                       MOV.L 10H[R0], 1CH[R0]
    0000000D 710104                         ADD #04H, R0, R1
    00000010 A181                           MOV.L R1, 18H[R0]
    00000012 EF01                           MOV.L R0, R1
    00000014 A109                           MOV.L R1, 14H[R0]
    00000016 FB1E101408                     MOV.L #00081410H, R1
    0000001B A90A                           MOV.L 14H[R0], R2
    0000001D A983                           MOV.L 18H[R0], R3
    0000001F E5010701                       MOV.L 1CH[R0], 04H[R1]
    00000023 E11301                         MOV.L 04H[R1], [R3]
    00000026 E012                           MOV.L [R1], [R2]
    00000028 A889                           MOV.L 0CH[R0], R1
    0000002A EC1E                           MOV.L [R1], R14
    0000002C FC8C0E                         FMUL [R0].L, R14
    0000002F A819                           MOV.L 04H[R1], R1
    00000031 FC8D0101                       FMUL 04H[R0].L, R1
    00000035 FC831E                         FSUB R1, R14
    00000038 A881                           MOV.L 08H[R0], R1
    0000003A E31E                           MOV.L R14, [R1]
    0000003C A889                           MOV.L 0CH[R0], R1
    0000003E EC12                           MOV.L [R1], R2
    00000040 FC8D0201                       FMUL 04H[R0].L, R2
    00000044 A819                           MOV.L 04H[R1], R1
    00000046 FC8C01                         FMUL [R0].L, R1
    00000049 FC8B12                         FADD R1, R2
    0000004C A881                           MOV.L 08H[R0], R1
    0000004E A01A                           MOV.L R2, 04H[R1]
    00000050 6708                           RTSD #20H
    00000052

     
    ICCRXでのリストファイル

       \                     _rot_2:
       \   000000 60 80        SUB       #0x8,SP
       \   000002 FB 4E 10 14  MOV.L     #0x81410,R4
       \          08
       \   000007 A0 49        MOV.L     R1,0x4[R4]
       \   000009 E5 40 01 01  MOV.L     0x4[R4],0x4[SP]
       \   00000D E0 40        MOV.L     [R4],[SP]
       \   00000F A8 0C        MOV.L     0x4[SP],R4
       \   000011 FD FF F4     BNOT      #0x1f,R4
       \   000014 FC 8D 24 01  FMUL      0x4[R2].L,R4
       \   000018 EC 05        MOV.L     [SP],R5
       \   00001A FC 8C 25     FMUL      [R2].L,R5
       \   00001D FC 8B 54     FADD      R5,R4
       \   000020 E3 34        MOV.L     R4,[R3]
       \   000022 A8 0C        MOV.L     0x4[SP],R4
       \   000024 FC 8C 24     FMUL      [R2].L,R4
       \   000027 EC 05        MOV.L     [SP],R5
       \   000029 FC 8D 25 01  FMUL      0x4[R2].L,R5
       \   00002D FC 8B 54     FADD      R5,R4
       \   000030 A0 3C        MOV.L     R4,0x4[R3]
       \   000032 67 02        RTSD      #0x8
           000034

     
    GNURXでのリストファイル
    (RXv3のDPFPUを有効にしているとDPFPUのレジスタを使う変なクセがありますね)

     791                                _rot_2:
     794 0000 7E AA                         push.l  r10
     796 0002 75 B0 01                      dpushm.d    dr0-dr1
     798 0005 71 0A EC                      add #-20, r0, r10
     800 0008 EF A0                         mov.L   r10, r0
     801 000a E7 A1 02                      mov.L   r1, 8[r10]
     802 000d E7 A2 03                      mov.L   r2, 12[r10]
     803 0010 E7 A3 04                      mov.L   r3, 16[r10]
     805 0013 71 A4 04                      add #4, r10, r4
     806 0016 ED A3 02                      mov.L   8[r10], r3
     807 0019 FB 5E 10 14 08                mov.L   #0x81410, r5
     808 001e A0 5B                         mov.L   r3, 4[r5]
     809 0020 A8 5B                         mov.L   4[r5], r3
     810 0022 E3 A3                         mov.L   r3, [r10]
     811 0024 EC 55                         mov.L   [r5], r5
     812 0026 E3 45                         mov.L   r5, [r4]
     814 0028 EC A5                         mov.L   [r10], r5
     815 002a FD 77 85 0A                   ftod    r5, dr0
     816 002e 76 90 0C 02                   dneg    dr0, dr0
     817 0032 76 90 0D 1C                   dtof    dr0, dr1
     818 0036 FD 75 85 10                   dmov.L  drl1, r5
     820 003a ED A4 03                      mov.L   12[r10], r4
     821 003d A8 4C                         mov.L   4[r4], r4
     823 003f FC 8F 54                      fmul    r5, r4
     825 0042 ED A5 03                      mov.L   12[r10], r5
     826 0045 EC 53                         mov.L   [r5], r3
     828 0047 ED A5 01                      mov.L   4[r10], r5
     829 004a FC 8F 35                      fmul    r3, r5
     831 004d FC 8B 54                      fadd    r5, r4
     833 0050 ED A5 04                      mov.L   16[r10], r5
     834 0053 E3 54                         mov.L   r4, [r5]
     836 0055 ED A5 03                      mov.L   12[r10], r5
     837 0058 EC 54                         mov.L   [r5], r4
     839 005a EC A5                         mov.L   [r10], r5
     840 005c FC 8F 54                      fmul    r5, r4
     842 005f ED A5 03                      mov.L   12[r10], r5
     843 0062 A8 5B                         mov.L   4[r5], r3
     845 0064 ED A5 01                      mov.L   4[r10], r5
     846 0067 FC 8F 35                      fmul    r3, r5
     848 006a FC 8B 54                      fadd    r5, r4
     850 006d ED A5 04                      mov.L   16[r10], r5
     851 0070 A0 5C                         mov.L   r4, 4[r5]
     853 0072 03                            nop
     854 0073 71 00 14                      add #20, r0
     855 0076 75 B8 01                      dpopm.d dr0-dr1
     856 0079 7E BA                         pop r10
     857 007b 02                            rts
         007c

     
    GNUARMでのリストファイル

     159                rot_2:
     166 0000 80B4          push        {r7}
     169 0002 8BB0          sub         sp, sp, #44
     171 0004 00AF          add         r7, sp, #0
     173 0006 87ED030A      vstr.32     s0, [r7, #12]
     174 000a B860          str         r0, [r7, #8]
     175 000c 7960          str         r1, [r7, #4]
     176 000e FB68          ldr         r3, [r7, #12]   @ float
     177 0010 7B62          str         r3, [r7, #36]   @ float
     178 0012 07F11803      add         r3, r7, #24
     179 0016 3B62          str         r3, [r7, #32]
     180 0018 07F11403      add         r3, r7, #20
     181 001c FB61          str         r3, [r7, #28]
     185 001e 1D4A          ldr         r2, .L9
     187 0020 7B6A          ldr         r3, [r7, #36]   @ float
     188 0022 5361          str         r3, [r2, #20]   @ float
     190 0024 1B4B          ldr         r3, .L9
     191 0026 5A69          ldr         r2, [r3, #20]   @ float
     193 0028 3B6A          ldr         r3, [r7, #32]
     194 002a 1A60          str         r2, [r3]    @ float
     196 002c 194B          ldr         r3, .L9
     197 002e 1A69          ldr         r2, [r3, #16]   @ float
     199 0030 FB69          ldr         r3, [r7, #28]
     200 0032 1A60          str         r2, [r3]    @ float
     202 0034 00BF          nop
     206 0036 D7ED067A      vldr.32     s15, [r7, #24]
     207 003a B1EE677A      vneg.f32    s14, s15
     209 003e BB68          ldr         r3, [r7, #8]
     210 0040 D3ED017A      vldr.32     s15, [r3, #4]
     212 0044 27EE277A      vmul.f32    s14, s14, s15
     214 0048 BB68          ldr         r3, [r7, #8]
     215 004a D3ED006A      vldr.32     s13, [r3]
     217 004e D7ED057A      vldr.32     s15, [r7, #20]
     218 0052 66EEA77A      vmul.f32    s15, s13, s15
     220 0056 77EE277A      vadd.f32    s15, s14, s15
     222 005a 7B68          ldr         r3, [r7, #4]
     223 005c C3ED007A      vstr.32     s15, [r3]
     225 0060 BB68          ldr         r3, [r7, #8]
     226 0062 93ED007A      vldr.32     s14, [r3]
     228 0066 D7ED067A      vldr.32     s15, [r7, #24]
     229 006a 27EE277A      vmul.f32    s14, s14, s15
     231 006e BB68          ldr         r3, [r7, #8]
     232 0070 D3ED016A      vldr.32     s13, [r3, #4]
     234 0074 D7ED057A      vldr.32     s15, [r7, #20]
     235 0078 66EEA77A      vmul.f32    s15, s13, s15
     237 007c 77EE277A      vadd.f32    s15, s14, s15
     239 0080 7B68          ldr         r3, [r7, #4]
     240 0082 C3ED017A      vstr.32     s15, [r3, #4]
     242 0086 00BF          nop
     243 0088 2C37          adds        r7, r7, #44
     245 008a BD46          mov         sp, r7
     248 008c 5DF8047B      ldr         r7, [sp], #4
     251 0090 7047          bx          lr
     252                .L10:
     253 0092 00BF          .align  2
     254                .L9:
     255 0094 00100240      .word   1073876992 ⇒ 0x40021000
         0098

     

  • こんにちは。NoMaYです。

    ちょっと話を戻しますが、三角関数演算器での演算時間が14クロックほどだと知ってからは、もう気にしても仕方無いかな、と考えるようになりましたけれども、それより以前、CC-RXに -nouse_div_inst というコンパイルオプションがあったことを知ってから暫くの間は、昔に私がFreeRTOSカーネルのRXv3のDPFPU対応をした時に入れた以下の命令とか、そもそもそれ以前から入っていた以下の命令とか、それらを割り込み応答時間の改善の観点から3~4命令ぐらいに分割しておいた方が良かったのかな、とか考えていました。

    現状:

    DPUSHM.D DR0-DR15

    DPOPM.D  DR0-DR15

    PUSHM R1-R14

    POPM  R1-R15

     
    暫くの間だけ考えていた分割案:

    DPUSHM.D DR12-DR15
    DPUSHM.D DR8-DR11
    DPUSHM.D DR4-DR7
    DPUSHM.D DR0-DR3

    DPOPM.D  DR0-DR3
    DPOPM.D  DR4-DR7
    DPOPM.D  DR8-DR11
    DPOPM.D  DR12-DR15

    PUSHM R11-R14
    PUSHM R6-R10
    PUSHM R1-R5

    POPM  R1-R5
    POPM  R6-R10
    POPM  R11-R15

     
    それと、CC-RXのC言語拡張文法の事情で以下のようにアセンブラソースとCソースに分割している箇所でのSETPSW Iは分岐命令の後では無くて分岐命令の前で実行するようにしておいた方が良かったのかな、とかも考えていました。

    現状:

            .SECTION   P,CODE

    _vSoftwareInterruptEntry:

        BRA _vSoftwareInterruptISR

            .RVECTOR    27, _vSoftwareInterruptEntry

     

    void vSoftwareInterruptISR( void )
    {
        prvYieldHandler();
    }

    #pragma inline_asm prvYieldHandler
    static void prvYieldHandler( void )
    {
        #ifndef __CDT_PARSER__
    /* *INDENT-OFF* */

            /* Re-enable interrupts. */
            SETPSW     I


            /* Move the data that was automatically pushed onto the interrupt stack when
             * the interrupt occurred from the interrupt stack to the user stack.
             *
             * R15 is saved before it is clobbered. */
            PUSH.L     R15

     
    暫くの間だけ考えていた変更案:

            .SECTION   P,CODE

    _vSoftwareInterruptEntry:

        ; Re-enable interrupts.
        SETPSW I

        BRA _vSoftwareInterruptISR

            .RVECTOR    27, _vSoftwareInterruptEntry

     

    void vSoftwareInterruptISR( void )
    {
        prvYieldHandler();
    }

    #pragma inline_asm prvYieldHandler
    static void prvYieldHandler( void )
    {
        #ifndef __CDT_PARSER__
    /* *INDENT-OFF* */

            /* Move the data that was automatically pushed onto the interrupt stack when
             * the interrupt occurred from the interrupt stack to the user stack.
             *
             * R15 is saved before it is clobbered. */
            PUSH.L     R15

     

  • こんにちは。NoMaYです。

    そういえば、RH850(というか元々はV850)に、割り込み応答時間の改善の為の、ちょっと風変わりな命令動作があったことを思い出して、RH850のドキュメントをちょっと見てみました。

    (1) 複数レジスタのPUSH中に割り込み要求があったらPUSH動作を途中で中止して割り込みへ飛ぶ
    (2) 複数レジスタのPOP中に割り込み要求があったらPOP動作を途中で中止して割り込みへ飛ぶ
    (3) 除算命令の実行中に割り込み要求があったら除算動作を途中で中止して割り込みへ飛ぶ

    ※ PUSH命令、POP命令、除算命令、などは、もちろん命令のバリエーションが幾つかあります。以下の画面コピーは、そのうちの幾つかの例です。

    RH850G3KH ユーザーズマニュアル ソフトウェア編
    R01US0165JJ0120 Rev.1.20 Pages 367 2016.12.22
    www.renesas.com/jp/ja/document/mas/rh850g3kh-users-manual-software









     
    [追記]

    浮動小数点演算命令(単精度)にも以下の画面コピーの通り命令実行時間が長いものがあるのですけれども、演算動作を途中で中止して割り込みへ飛ぶ、ということはしないようです。(少なくともドキュメントには記載が無かったです。)


     

  • こんにちは。NoMaYです。

    以下の画面コピーの警告で気付いたのですけれども、CGコンポーネントにコンポーネント内で違う割り込み優先順位を指定しなければならないものがあったのですね。こういうコンポーネントは気安く多重割り込みを許可してしまうのは危なそうです、、、(他方、同じ内蔵周辺機能でも、以下の画面コピーのとおり、FITモジュールでは同じ割り込み優先順位を指定しても構わないようでした、、、実装の詳細に依存することだと思いますので、どちらかがおかしいのではないか?、とまでは何とも言えないのですけれども、でも直感として何だか怪しい気はしているのですけれども、、、)

    以下、e2 studioのRXスマートコンフィグレータの画面コピーです。

    CG


    FIT

     

  • こんにちは。NoMaYです。

    FITもCGも多重割り込み許可にはしていないのに、RXスマートコンフィグレータで割り込み優先順位を指定させることに何の意味があるかというと、たぶん以下の4つではないだろうか、と思われます。ただ、以下の(1)を本当にしても良いのかと問われると、FITモジュールやCGコンポーネントの個々の実装次第だろう、と思われます、といった逃げた返事を私はするだろう、と思います、、、

    (1) コールバック関数内でユーザが多重割り込み許可にした場合のため

    (2) まさに同時に2つ以上の割り込みが発生した時のため
    (3) 他の割り込みの処理中にトータルで2つ以上の割り込みが発生していて、他の割り込みが終了して次の割り込みがまさに受け付けられる時のため

    (4) FreeRTOSやNORTiなどカーネル内の割り込み禁止区間でも高優先度割り込みを許可するようになっているRTOSを使う場合のため
    (4') ちなみに、FreeRTOSでも、RXコア向けやCortexコア向けには該当機能があるが、(少なくとも数年前は)78K/RL78/V850コア向けには無いです
    (4'') それから、AzureRTOSでは、RXコア向けには該当機能が無いが、Cortexコア向けには該当機能があるようです

  • こんにちは。NoMaYです。

    FITの割り込み処理で割り込み関数先頭での多重割り込み許可を設定する手はないかと小細工を考えていて、ひとつ思い浮かんだのですけれども、以前の投稿に書いていた、FITのBSPモジュールの3種類コンパイラ対応の為のマクロ定義部に手を入れるやり方なのですけれども、マクロ定義部を以下のようにしてみるというのがあります。各コンパイラが生成した割り込み関数のコード(アキュムレータの退避/復帰を行うオプションを指定しています)は以下のリストファイルのようになりました。(なお、昨日の夜に気付いたことに関しては、どうしたものかなぁ、とは思っているところです。)

    思い浮かんだ小細工:

    r_bsp/mcu/all/r_rx_compiler.h (もちろん無条件に置き換えるのではなく必要に応じて切り替えるのですけれども)

    #if defined(__CCRX__)

    #define R_BSP_PRAGMA_STATIC_INTERRUPT(function_name, vector)          static void function_name(void);\
                                                                          R_BSP_PRAGMA(interrupt _##function_name(vect=vector, enable))\
                                                                          static void _##function_name(void);\
                                                                          static void _##function_name(void)\
                                                                          {\
                                                                              if(BSP_CFG_FIT_IPL_MAX > (((R_BSP_GET_PSW()) >> 24) & 0xF))\
                                                                              {\
                                                                                  R_BSP_SET_IPL(BSP_CFG_FIT_IPL_MAX);\
                                                                              }\
                                                                              function_name();\
                                                                          }

    #define R_BSP_ATTRIB_STATIC_INTERRUPT                                 static

     

    #elif defined(__GNUC__)

    #define R_BSP_PRAGMA_STATIC_INTERRUPT(function_name, vector)          static void function_name(void);\
                                                                          static void _##function_name(void)  __attribute__((interrupt, section(".text." #function_name), used));\
                                                                          static void __##function_name(void) __attribute__((interrupt(R_BSP_SECNAME_INTVECTTBL, vector), naked, section(".text." #function_name), used));\
                                                                          static void __##function_name(void)\
                                                                          {\
                                                                              __asm__ volatile ("SETPSW I");\
                                                                              __asm__ volatile ("BRA.W __" #function_name);\
                                                                          }\
                                                                          static void _##function_name(void)\
                                                                          {\
                                                                              if(BSP_CFG_FIT_IPL_MAX > (((R_BSP_GET_PSW()) >> 24) & 0xF))\
                                                                              {\
                                                                                  R_BSP_SET_IPL(BSP_CFG_FIT_IPL_MAX);\
                                                                              }\
                                                                              function_name();\
                                                                          }

    #define R_BSP_ATTRIB_STATIC_INTERRUPT                                 static

     

    #elif defined(__ICCRX__)

    #define R_BSP_PRAGMA_STATIC_INTERRUPT(function_name, vect)            static void function_name(void);\
                                                                          R_BSP_PRAGMA(vector=vect)\
                                                                          static __interrupt __nested void _##function_name(void);\
                                                                          static __interrupt __nested void _##function_name(void)\
                                                                          {\
                                                                              if(BSP_CFG_FIT_IPL_MAX > (((R_BSP_GET_PSW()) >> 24) & 0xF))\
                                                                              {\
                                                                                  R_BSP_SET_IPL(BSP_CFG_FIT_IPL_MAX);\
                                                                              }\
                                                                              function_name();\
                                                                          }

    #define R_BSP_ATTRIB_STATIC_INTERRUPT                                 static

    #endif

     
    r_config/r_bsp_config.h (既存のマクロ定義を以下の値にしています(この値のみに限られているわけではありません))

    /* For some BSP functions, it is necessary to ensure that, while these functions are executing, interrupts from other 
       FIT modules do not occur. By controlling the IPL, these functions disable interrupts that are at or below the
       specified interrupt priority level.
       This macro sets the IPL. Range is 0x0 - 0xF.
       Please set this macro more than IPR for other FIT module interrupts.
       The default value is 0xF (maximum value).
       Don't change if there is no special processing with higher priority than all fit modules.
    */
    #define BSP_CFG_FIT_IPL_MAX                         (0xB)

     
    ソース例:

    src\smc_gen\r_riic_rx\src\targets\rx66n/r_iic_rx66n.cから抜粋したもの

    /*******************************************************************************
     * Function Name: riic1_txi_isr
     * Description  : Interrupt TXI handler for channel 1.
     *                Types of interrupt requests transmission data empty.
     * Arguments    : None
     * Return Value : None
    *******************************************************************************/
    R_BSP_PRAGMA_STATIC_INTERRUPT(riic1_txi_isr, VECT(RIIC1,TXI1))
    R_BSP_ATTRIB_STATIC_INTERRUPT void riic1_txi_isr (void)
    {
        riic1_txi_sub();
    } /* End of function riic1_txi_isr() */

     
    リストファイル:

    CC-RX : コンパイルオプションに -save_acc (割り込み関数でのアキュムレータの退避/復帰を行う)を指定

    000002E4                         __$_riic1_txi_isr:
                                            .RVECTOR    51,__$_riic1_txi_isr
    000002E4 7FA8                           SETPSW I ⇒ 多重割り込み許可
    000002E6 6EEF                           PUSHM R14-R15
    000002E8 6E45                           PUSHM R4-R5
    000002EA 7EA3                           PUSH.L R3
    000002EC FD1FB3                         MVFACGU #00H, A1, R3
    000002EF 7EA2                           PUSH.L R2
    000002F1 FD1F82                         MVFACHI #00H, A1, R2
    000002F4 7EA1                           PUSH.L R1
    000002F6 FD1F91                         MVFACLO #00H, A1, R1
    000002F9 7EA3                           PUSH.L R3
    000002FB FD1F33                         MVFACGU #00H, A0, R3
    000002FE 7EA2                           PUSH.L R2
    00000300 FD1F02                         MVFACHI #00H, A0, R2
    00000303 7EA1                           PUSH.L R1
    00000305 FD1F11                         MVFACLO #00H, A0, R1
    00000308 6E13                           PUSHM R1-R3
    0000030A FD6A01                         MVFC PSW, R1
    0000030D FC5A110810                     BFMOVZ #18H, #00H, #04H, R1, R1
    00000312 61A1                           CMP #0AH, R1
    00000314 24rr                           BGTU L64
    00000316                         L63:   ; if_then_bb
    00000316 75700B                         MVTIPL #0BH
    00000319                         L64:   ; if_break_bb
    00000319 39rrrr               W         BSR __$riic1_txi_isr
    0000031C 7EB1                           POP R1
    0000031E 7EB2                           POP R2
    00000320 7EB3                           POP R3
    00000322 FD1711                         MVTACLO R1, A0
    00000325 FD1702                         MVTACHI R2, A0
    00000328 7EB1                           POP R1
    0000032A FD1733                         MVTACGU R3, A0
    0000032D 7EB2                           POP R2
    0000032F 7EB3                           POP R3
    00000331 FD1791                         MVTACLO R1, A1
    00000334 FD1782                         MVTACHI R2, A1
    00000337 FD17B3                         MVTACGU R3, A1
    0000033A 6F15                           POPM R1-R5
    0000033C 6FEF                           POPM R14-R15
    0000033E 7F95                           RTE

     
    ICCRX : コンパイルオプションに --save_acc (割り込み関数でアキュムレータの退避/復帰を行う)を指定
    (しかしながらバグによりアキュムレータの退避/復帰を行うコードが生成されないみたいですね)

       \                     __riic1_txi_isr:
       \                     ___interrupt_51:
       \   000000 7F A8        SETPSW    I ⇒ 多重割り込み許可
       \   000002 6E EF        PUSHM     R14-R15
       \   000004 6E 15        PUSHM     R1-R5
       \   000006 FD 6A 01     MVFC      PSW,R1
       \   000009 FC 5A 11 08  BFMOVZ    #0x18,#0x0,#0x4,R1,R1
       \          10
       \   00000E 61 B1        CMP       #0xb,R1
       \   000010 22 05        BGEU      ??_riic1_txi_isr_0
       \   000012 75 70 0B     MVTIPL    #0xb
       \                     ??_riic1_txi_isr_0:
       \   000015 05 ..'....   BSR.A     _riic1_txi_sub
       \   000019 6F 15        POPM      R1-R5
       \   00001B 6F EF        POPM      R14-R15
       \   00001D 7F 95        RTE

     
    GNURX : コンパイルオプションに -msave-acc-in-interrupts (割り込み関数でアキュムレータの退避/復帰を行う)を指定

     936                                __riic1_txi_isr:
     939                                    ; Note: Interrupt Handler
     940 0000 6E EF                         pushm   r14-r15
     942 0002 6E 15                         pushm   r1-r5
     944 0004 FD 1F 11                      mvfaclo #0, A0, r1
     945 0007 FD 1F 02                      mvfachi r2
     946 000a 7E A1                         push.l  r1
     947 000c 7E A2                         push.l  r2
     948 000e FD 1F 31                      mvfacgu #0, A0, r1
     949 0011 FD 1F 92                      mvfaclo #0, A1, r2
     950 0014 7E A1                         push.l  r1
     951 0016 7E A2                         push.l  r2
     952 0018 FD 1F 81                      mvfachi #0, A1, r1
     953 001b FD 1F B2                      mvfacgu #0, A1, r2
     954 001e 7E A1                         push.l  r1
     955 0020 7E A2                         push.l  r2
     957 0022 FD 6A 05                      mvfc    psw, r5
     958 0025 69 85                         shlr    #24, r5
     959 0027 64 F5                         and #15, r5
     960 0029 61 A5                         cmp #10, r5
     961 002b 24 05                         bgtu    .L65
     963 002d 75 70 0B                      mvtipl  #11
     964                                     .balign 8,3,3
     965                                 .L65:
     972 0030 05 00 00 00                   bsr _riic1_txi_sub
     977 0034 7E B2                         pop r2
     978 0036 7E B1                         pop r1
     979 0038 FD 17 81                      mvtachi r1, A1
     980 003b FD 17 B2                      mvtacgu r2, A1
     981 003e 7E B2                         pop r2
     982 0040 7E B1                         pop r1
     983 0042 FD 17 31                      mvtacgu r1, A0
     984 0045 FD 17 92                      mvtaclo r2, A1
     985 0048 7E B2                         pop r2
     986 004a 7E B1                         pop r1
     987 004c FD 17 11                      mvtaclo r1
     988 004f FD 17 02                      mvtachi r2
     989 0052 6F 15                         popm    r1-r5
     990 0054 6F EF                         popm    r14-r15
     991 0056 7F 95                         rte
     995                                ___riic1_txi_isr:
     998                                    .global $tableentry$51$.rvectors
     999                                $tableentry$51$.rvectors:
     1000                                   ; Note: Interrupt Handler
     1001                                   ; Note: Naked Function
     1004 0058 7F A8                        SETPSW I ⇒ 多重割り込み許可
     1008 005a 38 A6 FF                     BRA.W __riic1_txi_isr

     

  • 割り込みハンドラには最低限の処理しか入れないように作っている限り多重割り込みが必要な場面はほとんどないはず
    (受信割り込みとか自分の努力だけではどうにもならない場合はありますが)、
    というのが昔の非力なマイコンを使っていた世代には当たり前の認識だったのですが今は違うみたいですね。

  • ほや さん、こんにちは。NoMaYです。

    リプライありがとうございます。ほやさんも以下のhirakuni45さんのリプライと同じ勘違いをされていると思うのです、、、(たぶん、ほやさんもhirakuni45さんも、脊髄反射的に`多重割り込み`というキーワードに反応されたのかなぁ、と思うのですけれども、、、)

    hirakuni45さんのリプライ
    community-ja.renesas.com/cafe_rene/forums-groups/mcu-mpu/rx/f/forum5/9572/rxv3-register-bank-save-function-usage/46854#46854

    hirakuni45さんのリプライへの私のリプライ
    community-ja.renesas.com/cafe_rene/forums-groups/mcu-mpu/rx/f/forum5/9572/rxv3-register-bank-save-function-usage/46861#46861

    今のところの本スレッドの話の流れは、以下のようなものなのです、、、

    メイン:

    ● RXv3コアのレジスタ一括退避機能を使わないといけないほど割り込み応答性にシビアなプログラムで最大限の効果を発揮させるには?
    (1) この機能を使う割り込み処理に着目するだけでは駄目で、そもそも他の割り込み処理が全て多重割り込み許可になってないと効果が無いのでは?
    (2) しかし、そもそもRXマイコン向けソフトウェア開発フレームワーク(RXスマートコンフィグレータ)で現状は(将来も?)多重割り込みを効率的に使えない
    (3) そんな状況だから(そんな状況だからこそ)、セールスポイントの1つであるレジスタ一括退避機能の使い方が今ひとつピンと来ません
    (4) どう使うのが良いのかなぁ?、、、(恐らく小細工を考えないといけないのだろうなぁ?、、、)

    あと、(うすうす感付かれている人もおられると思いますけれども、) もうひとつの話の流れもあります、、、

    サブ:

    ● RXv3コアのレジスタ一括退避機能って大して役に立たないのかなぁ?(シリコンというかトランジスタというかの無駄遣いなのかなぁ?)
    (1) RXマイコン向けソフトウェア開発フレームワーク(RXスマートコンフィグレータ)で現状は(将来も?)多重割り込みを効率的に使えないのだから
    (2) もしかしたら、CPUコアを開発している人達は、自分達の会社のソフトウェア開発フレームワークが多重割り込みを効率的に使えないものだった、とは思ってなかった?
    (3) その他にも、そもそもRXマイコンの命令の中に命令実行クロック数が有意に長いものが幾つか存在していて割り込み応答性の悪化(ゆらぎ)要因になってますよね
    (4) あとそれから、CPUコアを開発している人達は、Cコンパイラが割り込み応答性の向上の為に既にかなり工夫していた、ことに気付いてなかった?

    と書いたものの、実は、そこまで割り込み応答性にシビアなプログラムの開発をしたことがありませんけれども、、、

    [追記]

    > 今は違うみたいですね。

    思うに、「今は」ということでなくて、ほやさんも私同様に「そこまで割り込み応答性にシビアなプログラムの開発をしたことが無かった」だけではないかなぁ、とも思います。RXマイコンには昔から高速割り込みなる機能がありますが、この機能の場合も、「この機能を使う割り込み処理に着目するだけでは駄目で、そもそも他の割り込み処理が全て多重割り込み許可になってないと効果が無いのでは?」と思われるのです。そして、この機能の起源は、RXマイコンよりも昔のM16CやM32CやR32Cの高速割り込み機能ですかね。

    以下、M16CやM32CやR32Cのアプリケーションノートの画面コピーです。

    M16C/80、M16C/64Aグループ M16C/80とM16C/64Aとの相違点
    www.renesas.com/us/ja/document/apn/917626?language=ja#page=24


    M32C/87B、R32C/116グループ M32C/87BとR32C/116との相違点(144pin版)
    www.renesas.com/us/ja/document/apn/815361?language=ja#page=8

     

  • > 「そこまで割り込み応答性にシビアなプログラムの開発をしたことが無かった」だけではないかなぁ、
    それは本来の使い方なので問題ないのですが、
    「どうすれば多重割り込みを有効にできますか」と聞いて来られる方の中で例えば「受信割り込みの中で応答送信待ちをした結果オーバーランエラーを食らった」みたいな、根本的な設計に問題があるのに多重割り込みで逃げを打とうとするケースを見かけることが以前より多い気がするのでちょっとグチってみただけです。気にしないでください。

  • ほや さん、こんにちは。NoMaYです。

    リプライありがとうございます。ナルホド! RXスマートコンフィグレータで、FITにしろCGにしろ、ユーザさんが多重割り込みを自前で使用している事例として、割り込み応答性にシビアなプログラムでは無いものでは、そういうことは可能性が高そうですね。hirakuni45さんが仰っていた話もそういう事例についてだったのかな、と今になってようやく気付いたのでした。

    コールバック関数が呼ばれるのは、スーパーループの通常のmainのコンテキストでは無くて、割り込みコンテキストである、ということがうまく認識出来ていなかった結末として多重割り込みに手を出す、という感じなのでしょうかね。

    どうなんでしょう。古くからのマイコンユーザとしては、コールバック関数が割り込みコンテキストであることは当然という感覚ですけれども、インターネット時代の、若くして汎用OS上での色々なフレームワークに触れることも少なく無い、今の若いユーザさんには、何でコールバック関数でそんなことも出来ないのさ?という感覚だったりして、、、

    ふと思い出したのですけれども、私はといえば、若かりし頃、ごちゃごちゃスタックを操作して、コールバック関数をスーパーループのmainのコンテキストで呼び出す小技を考えようとしたことがあったような気がします。(記憶の捏造では無くて、そんなことを考えようとしたことがあったような記憶が確かにある、といったところですけれども、、、)

    [追記]

    FreeRTOSでも、FreeRTOS上に構築された何かのフレームワークにおいて、何かのコールバック関数が、通常のタスクのコンテキストでは無くて、タイマタスクという最高優先度のタスクのコンテキストで呼ばれていたことから、その中で他タスクからの反応を待つも、いつまで経っても反応が無い、という事例があるかも知れないとか思い浮かびました。