こんにちは。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です。ちょっと脱線しますけれども、今回のスレッドで調べ物をしていて、RXマイコンを触り始めて10年目にしてようやく気付いたRXコアのアキュムレータについての驚きの事実がありました。(以前にRL78コアのDTC保留命令というものに気付いた時と同じぐらいの驚きでした。) もっとも、10年目という数字も大雑把ですし、アキュムレータもちゃんと使ったことが無かったですし、ということでもありますけれども。(1) メイン処理側でしかアキュムレータを使っていなくても、(適切な割り込み設定をしていないと)割り込み処理の実行後にアキュムレータの値が壊れてしまっていることが有り得る(2) 特定の1つのタスクでしかアキュムレータを使っていなくても、(もしも正しいコンテキスト切り替え処理をしていないRTOSカーネルだったら)他のタスクから戻った後にアキュムレータの値が壊れてしまっていることが有り得る理由は、以下の画面コピーの説明の通りです。(以下は一例としてRX660のものです。)RX660グループ ユーザーズマニュアル ハードウェア編R01UH0937JJ0100 Rev.1.00 Pages 2302 2022.03.18www.renesas.com/jp/ja/document/mah/rx660-group-users-manual-hardware#page=118RXファミリ RXv3命令セットアーキテクチャ ユーザーズマニュアル ソフトウェア編R01US0316JJ0100 Rev.1.00 Pages 373 2018.11.20www.renesas.com/jp/ja/document/mas/rx-family-rxv3-instruction-set-architecture-users-manual-software-rev100#page=24EMUL (普通の算術演算命令)EMULU (普通の算術演算命令)FMUL (普通の単精度浮動小数点演算命令)MUL (普通の算術演算命令)RMPA (この積和演算命令はともかくとして)[関連リンク]RL78コアのDTC保留命令というものについて。RL78 FreeRTOS APIを特別なおまじない記述無しで割り込みルーチンから呼び出せるようにしてみた(CC-RL/GNURL78)community-ja.renesas.com/cafe_rene/forums-groups/tools/f/forum21/5845/rl78-freertos-api-cc-rl-gnurl78/33975#33975
こんにちは。NoMaYです。またちょっと脱線しますけれども、RL78コアにもレジスタバンクという似た名前のものがあり、それは以下の仕様になっています。ちなみに、RH850コアにはそういうものは無いようです。RL78 ファミリ ユーザーズマニュアル ソフトウェア編R01US0015JJ0230 Rev.2.30 Pages 245 2022.04.22www.renesas.com/jp/ja/document/mah/rl78-family-users-manual-software-rev230RH850G3M ユーザーズマニュアル ソフトウェア編R01US0123JJ0140 Rev.1.40 Pages 433 2016.12.22www.renesas.com/jp/ja/document/mas/rh850g3m-users-manual-software-rev140RH850G3MH ユーザーズマニュアル ソフトウェア編R01US0143JJ0130 Rev.1.30 Pages 412 2016.12.22www.renesas.com/jp/ja/document/man/rh850g3mh-users-manual-software-0RH850G3KH ユーザーズマニュアル ソフトウェア編R01US0165JJ0120 Rev.1.20 Pages 367 2016.12.22www.renesas.com/jp/ja/document/mas/rh850g3kh-users-manual-software
こんにちは。NoMaYです。割り込み関数でレジスタ一括退避機能を使用する場合の各コンパイラの構文は以下の通りです。また、割り込み関数先頭で多重割り込みを許可する場合の構文と、割り込み関数の初めと終わりでアキュムレータの値を退避/復帰させるコードを生成させるコンパイラコマンドラインオプションも書いておきます。レジスタ一括退避機能を使用する場合:
CC-RX : #pragma interrupt <関数名>(bank=バンク番号[,<他の割り込み仕様>])ICCRX : #pragma bank=バンク番号GNURX : 未サポート
割り込み関数先頭で多重割り込みを許可する場合:
CC-RX : #pragma interrupt <関数名>(enable[,<他の割り込み仕様>])ICCRX : __interrupt __nested void <関数名>(void);GNURX : 未サポート
割り込み関数の初めと終わりでアキュムレータの値を退避/復帰させる場合:
CC-RX : -save_acc (#pragma interruptでも指定可能)ICCRX : --save_accGNURX : -msave-acc-in-interrupts
以下、ドキュメントの画面コピーです。CC-RX途中省略ICCRXGNURXgcc.gnu.org/onlinedocs/gcc/RX-Options.html(参) gcc.gnu.org/onlinedocs/gcc/RX-Function-Attributes.html(参2) コマンドラインヘルプによるとオンラインドキュメントには未反映のものも残っているようです
NoMay さんこんにちは。
色々調査してくれて助かります。
なるほど、最適化した場合も、危険なコードが出る場合があるようですね。
※自分の環境で、ある程度複雑な割り込み関数で、実験してみましたが、それは大丈夫でした。
自分の最適化は「-O3」です。
※デバッグビルド(-O0)は撃沈です・・・
呼び出し先コード(github にある):
DSOS_sample/capture.hpp
アセンブラコード:
ffc080f0 <__ZN6device6tpu_ioINS_7tpu_x_tILm557328ELNS_10peripheralE27ELNS_5icu_tIvE11VECTOR_SELBE15ELS5_16ELS5_17ELS5_18ELS5_19ELS5_0EEEN4dsos7captureILm16384EE8cap_taskELNS_14port_map_order5ORDERE1EE9tpu_task_Ev>:ffc080f0: fd 76 e0 00 save #0ffc080f4: fb 5e 2e 90 08 mov.l #0x8902e, r5
...
ffc0814b: fd 76 f0 00 rstr #0ffc0814f: 7f 95 rteffc08151: 02 rts
通常の割り込み関数の場合:
ffc080f0 <__ZN6device6tpu_ioINS_7tpu_x_tILm557328ELNS_10peripheralE27ELNS_5icu_tIvE11VECTOR_SELBE15ELS5_16ELS5_17ELS5_18ELS5_19ELS5_0EEEN4dsos7captureILm16384EE8cap_taskELNS_14port_map_order5ORDERE1EE9tpu_task_Ev>:ffc080f0: 6e ef pushm r14-r15ffc080f2: 6e 15 pushm r1-r5ffc080f4: fb 5e 2e 90 08 mov.l #0x8902e, r5
ffc0814b: 6f 15 popm r1-r5ffc0814d: 6f ef popm r14-r15ffc0814f: 7f 95 rte
自分はC++17をサポートしていないコンパイラでは自分フレームワークをコンパイル出来ないので、戦力外です。
C++17 をサポートしているICCRXは選択枠としてはアリですが、コストが見合わないので、結局、GNU-RXがサポートするまで待つしかありません。
どうしても使いたい場合は、アセンブラソースを sed などで無理やり編集(又は、駄目なコードを吐いたらエラーを出出すなど)するなどの強引な方法も考えられますが・・
また、GNU-RX(C++) を使う理由として:
(1) boost が使える
(2) 最適化が C より深くより高速に動く(経験的な感触)
(3) 記憶割り当てを使っても、メモリーリークをまずしないように書ける
(4) より構造的に書けて、些細なミスを防げる
(5) コードの再利用性
(6)ヘッダーのみで全て完結するので、ソースをリンクする必要性が無く、管理も簡単
(7)昔のコードを保守する場合に「楽」だと感じる
(8)GNU-RXの特性をある程度理解しているので、デバッグがしやすく、対応がしやすい
利点を上げると沢山ありますが、今更Cでプログラム作る理由が無いので、当面は、GNU-RX一択になるのでしょうね・・・
hirakuni45さん、こんにちは。NoMaYです。情報どうもありがとうございます。それで、実は、こちら側では、RXスマートコンフィグレータ、というか、FIT/CGの事情になってしまうのですけれども、もろもろのモジュール/コンポーネントにおいて、関数先頭で多重割り込みが許可されるようになっていなくて、ユーザさんが自前で全てコーディングしているような高い割り込み優先度の割り込みの受け付けを、FIT/CGの低い優先度の割り込み処理が邪魔する/遅延させる、ような作りになっていて、ひょっとしたら、100クロックだの1000クロックだの割り込み要求の発生から受け付けまでが遅延するようなこともあるかも知れなくて、そんな構造で、高い割り込み優先度の割り込み関数の先頭処理が、5クロックとか、10クロックとか、20クロックとか、短くなっても価値のあることなのかなぁ、、、という気がしているのです。なので、このスレッドの前の方にも書いていますが、小細工を考えないと、、、とか考えていたりするのです。hirakuni45さんのように、独自フレームワークで、全ての割り込み処理において処理の早い段階で多重割り込みを許可するように出来る場合には、レジスタ一括退避機能で容易にメリットが出てくる、のですけれども。[追記]すみません、独り言ですが、ちょっと待ってくださいよ。>> 自分GNURXでは、関数先頭で多重割り込みを許可する構文が無いのだから、低い優先度の割り込み処理が、5クロックとか、10クロックとか、20クロックとか、高い優先度の割り込みの受け付けを遅延させることがある筈なのだから、FIT/CGほど酷くは無いけれども、やっぱり、ちょっと、それはもったいないかも、とも思わなくも無いような気もしてきた、かな、、、
こんにちは。NoMaYです。そういえば、EWRXは、まだ、RX660に対応していませんでしたね。(有償製品版購入ユーザ(保守契約ユーザ?)は、問い合わせすれば、サポートして貰えると思いますけれども。)Release notes for the Renesas RX IAR Embedded Workbench product package version 4.20.1netstorage.iar.com/SuppDB/Public/UPDINFO/014936/ew/doc/infocenter/ewrx.ENU.htmlRX72NとRX66Nが最後ですね (インストールフォルダを覗くとRX66TはありますがRX671やRX660やRX140が無いですね)「4.14.1 2020-02-05New features・RX72N and RX66N supported The RX72N and RX66N groups of microcontrollers are now supported.」Renesas RX IAR Embedded Workbench製品パッケージバージョン4.20.1のリリースノートnetstorage.iar.com/SuppDB/Public/UPDINFO/014936/ew/doc/infocenter/ewrx.JPN.html同上以下、e2 studioの画面コピーです。[関連リンク]IAR Embedded Workbench for Renesas RX製品ページwww.iar.com/jp/products/architectures/renesas/iar-embedded-workbench-for-renesas-rx/サポートされているデバイス一覧 (こちらにはRX66TもRX671もRX140もありますね(ですがRX660は無いですね))www.iar.com/jp/products/architectures/renesas/iar-embedded-workbench-for-renesas-rx/supported-rx-devices/無償の評価版www.iar.com/jp/products/architectures/renesas/iar-embedded-workbench-for-renesas-rx/#productdownloadpage_3064
こんにちは。NoMaYです。割り込み関数の先頭/末尾でのPUSH/POPが大量になるよう意図的にソースの記述やコンパイルオプションの設定を行い、CC-RXとICCRXとGNURXで生成されたコードを見てみました。e2 studio 2022-07のプロジェクトのファイル一式を以下のzipファイルに固めました。issue_RXv3_RegBankSave_20221002.zip今回、困惑していることが1つあって、ICCRXで--save_accを指定してもアキュムレータの値を退避/復帰させるコードが生成されませんでした。半日悩んでみましたが、結構深刻なバグ、なのでは?、という考えを解消出来ませんでした。以下、生成されたコードの例です。(抜粋です。可能なら割り込み関数先頭で多重割り込み許可にしています。)CC-RX : RXv3_RegBankSave_CCRX/HardwareDebug/src/RXv3_RegBankSave_CCRX_ex4.lst
.SECTION P,CODE00000000 __$i_hdr_4_1:00000000 7FA8 SETPSW I00000002 6E4F PUSHM R4-R1500000004 7EA3 PUSH.L R300000006 FD1FB3 MVFACGU #00H, A1, R300000009 7EA2 PUSH.L R20000000B FD1F82 MVFACHI #00H, A1, R20000000E 7EA1 PUSH.L R100000010 FD1F91 MVFACLO #00H, A1, R100000013 7EA3 PUSH.L R300000015 FD1F33 MVFACGU #00H, A0, R300000018 7EA2 PUSH.L R20000001A FD1F02 MVFACHI #00H, A0, R20000001D 7EA1 PUSH.L R10000001F FD1F11 MVFACLO #00H, A0, R100000022 6E13 PUSHM R1-R3…1行省略…0000002A 7100A8 ADD #0FFFFFFA8H, R0…2行省略…00000033 6240 ADD #04H, R0…途中省略…00000169 710054 ADD #54H, R00000016C 7EB1 POP R10000016E 7EB2 POP R200000170 7EB3 POP R300000172 FD1711 MVTACLO R1, A000000175 FD1702 MVTACHI R2, A000000178 7EB1 POP R10000017A FD1733 MVTACGU R3, A00000017D 7EB2 POP R20000017F 7EB3 POP R300000181 FD1791 MVTACLO R1, A100000184 FD1782 MVTACHI R2, A100000187 FD17B3 MVTACGU R3, A10000018A 6F1F POPM R1-R150000018C 7F95 RTE
ICCRX : RXv3_RegBankSave_IAR/HardwareDebug/RXv3_RegBankSave_IAR_ex4.lst
\ In section .text, align 8, keep-with-next \ _i_hdr_4_1: \ 000000 7F A8 SETPSW I \ 000002 6E EF PUSHM R14-R15 \ 000004 6E 1B PUSHM R1-R11 \ 000006 71 00 C8 ADD #-0x38,SP,SP…途中省略… \ 00011E 71 00 38 ADD #0x38,SP,SP \ 000121 6F 1B POPM R1-R11 \ 000123 6F EF POPM R14-R15 \ 000125 7F 95 RTE
GNURX : RXv3_RegBankSave_GCC/HardwareDebug/RXv3_RegBankSave_GCC_ex4.lst
136 .section .text.i_hdr_4_1,"ax",@progbits 138 _i_hdr_4_1: 141 ; Note: Interrupt Handler 142 0000 6E 1F pushm r1-r15 144 0002 FD 1F 11 mvfaclo #0, A0, r1 145 0005 FD 1F 02 mvfachi r2 146 0008 6E 12 pushm r1-r2 147 000a FD 1F 31 mvfacgu #0, A0, r1 148 000d FD 1F 92 mvfaclo #0, A1, r2 149 0010 6E 12 pushm r1-r2 150 0012 FD 1F 81 mvfachi #0, A1, r1 151 0015 FD 1F B2 mvfacgu #0, A1, r2 152 0018 6E 12 pushm r1-r2 153 001a 71 00 C0 add #-64, r0…途中省略… 452 0165 71 00 40 add #0x40, r0 453 0168 6F 12 popm r1-r2 454 016a FD 17 81 mvtachi r1, A1 455 016d FD 17 B2 mvtacgu r2, A1 456 0170 6F 12 popm r1-r2 457 0172 FD 17 31 mvtacgu r1, A0 458 0175 FD 17 92 mvtaclo r2, A1 459 0178 6F 12 popm r1-r2 460 017a FD 17 11 mvtaclo r1 461 017d FD 17 02 mvtachi r2 462 0180 6F 1F popm r1-r15 465 0182 7F 95 rte
こんにちは。NoMaYです。割り込み関数でレジスタ一括退避機能を使用してみました。e2 studio 2022-07のプロジェクトのファイル一式を以下のzipファイルに固めました。issue_RXv3_RegBankSave_20221003.zipちなみに、レジスタ一括退避先バンク数は、RXv3命令セット上は、最大256バンク持てるようになっていますが、実際の製品では、今のところ、16バンクとなっていますけれども、割り込み優先順位とレジスタ一括退避先バンク番号を常にソースコード上で正しく整合させていれば、16バンクあれば、以下の理由により、全ての割り込みでレジスタ一括退避機能を使用出来るような気がします。(1) 割り込み優先順位は16レベルである(ただし最低優先順位にすると割り込み不可となるので実質は15レベルである)(2) 多重割り込みを許可しても同一優先順位の割り込みは許可されない(優先順位が高い割り込みのみ許可される)(3) レジスタ一括退避先バンク数は16バンクなので割り込み優先順位毎に1つ割り当てることが出来る(4) 多重割り込みを許可しても優先順位が高い割り込みのみ許可されるので使用中のバンクを上書きしてしまうことは無い以下、生成されたコードの例です。(抜粋です。可能なら割り込み関数先頭で多重割り込み許可にしています。)CC-RX : RXv3_RegBankSave_CCRX/HardwareDebug/src/RXv3_RegBankSave_CCRX_ex5.lst
.SECTION P,CODE00000000 __$i_hdr_5_1:00000000 7FA8 SETPSW I00000002 FD76E000 SAVE #00H00000006 7100A8 ADD #0FFFFFFA8H, R0…3行省略…00000015 6240 ADD #04H, R0…途中省略…0000014E 710054 ADD #54H, R000000151 FD76F000 RSTR #00H00000155 7F95 RTE
ICCRX : RXv3_RegBankSave_IAR/HardwareDebug/RXv3_RegBankSave_IAR_ex5.lst
\ In section .text, align 8, keep-with-next \ _i_hdr_5_1: \ 000000 7F A8 SETPSW I \ 000002 FD 76 E0 00 SAVE #0x0 \ 000006 71 00 C8 ADD #-0x38,SP,SP…途中省略… \ 00011E 71 00 38 ADD #0x38,SP,SP \ 000121 FD 76 F0 00 RSTR #0x0 \ 000125 7F 95 RTE
GNURX : 未サポート
こんにちは。NoMaYです。この際ですので、アキュムレータACC0の値が、EMUL、EMULU、FMUL、MULといった命令の実行後に、壊れるのかどうかを実際に見てみました。確かに壊れました。以下、CS+の画面コピーです。(以前にe2 studioで困惑する事態があったので、私は今回はCS+です。ひとそれぞれですが。)くだんの命令群の実行前くだんの命令群の実行後試したコード
#pragma inline_asm code1, code2void code1(void){ MOV.L #12121212H, R6 MOV.L #34343434H, R7 MVTACLO R6, A0 MVTACHI R6, A0 MVTACGU R6, A0 MVTACLO R7, A1 MVTACHI R7, A1 MVTACGU R7, A1}void code2(void){ MOV.L #12121212H, R6 MOV.L #34343434H, R7 EMUL R6, R7 MOV.L #12121212H, R6 MOV.L #34343434H, R7 EMULU R6, R7 MOV.L #0, R6 MOV.L #0, R7 FMUL R6, R7 MOV.L #12121212H, R6 MOV.L #34343434H, R7 MUL R6, R7, R8}int main(void){ code1(); __nop(); code2(); __nop(); for(;;);}
こんにちは。NoMaYです。FIT/CGの割り込み処理は割り込み関数先頭での多重割り込み許可を設定出来ませんが、そのことが、高い優先度の割り込み処理にて、5クロックとか、10クロックとか、20クロックとか、レジスタ一括退避機能を使用して割り込み応答性を改善したとしても、低い優先度の割り込み処理が実行中かつ多重割り込み不可だった場合には、高い優先度の割り込みが、ひょっとしたら、100クロックとか、1000クロックとか、要求の発生から受け付けまでが遅延するようなこともあるかも知れなくて、そのせいで、数時間はエラー無く動くけれども1日動き続けることは出来ないとか、2,3日は大丈夫だけれども1週間は無理だとか、2,3週間動き続けることも少なく無いけれど1日で止まってしまうこともあるとか、そういう問題に至ってしまう原因の1つになってしまわないかと気掛かりだったりします。そこで、FIT/CGの割り込み処理で割り込み関数先頭での多重割り込み許可を設定する手はないかと小細工を考えようとしているのですが、取っ掛かりの候補として以下の2つが思い浮かんでいるところです。(1) 以前に、μITRON系RTOSのNORTiで、おまじない処理をFIT/CGの割り込み処理の前に強引に実行させるようにしたやり方の応用デメリット:・ FIT/CGの割り込み応答性が数十クロック悪化する (もちろん高い優先度の割り込みの多重割り込みの発生によるものとは別物です)メリット:・ 割り込み関数先頭での多重割り込み許可の構文が(今のところ)存在しないGNURXでもそのまま対応可能なはずである・ BSPモジュールのソースに手を入れなくてもよいスレッド:スマートコンフィグレータの自動生成をカスタマイズしたいcommunity-ja.renesas.com/cafe_rene/forums-groups/mcu-mpu/rx/f/forum5/8248/thread/42690#42690MISPOさんのNORTiをRX SmartConfiguratorと一緒に使いたい場合の課題と対策を考察してみるスレッドcommunity-ja.renesas.com/cafe_rene/forums-groups/tools/f/forum21/8266/mispo-norti-rx-smartconfigurator/42873#42873(2) RXスマートコンフィグレータ(というかFIT)のBSPモジュールの3種類コンパイラ対応の為のマクロ定義部に手を入れるやり方デメリット:・ 割り込み関数先頭での多重割り込み許可の構文が(今のところ)存在しないGNURXには対応不可能である・ BSPモジュールのソースに手を入れることになるメリット:・FIT/CGの割り込み応答性は1クロック遅くなるのみです (もちろん高い優先度の割り込みの多重割り込みの発生によるものは別物です)ソース:現状のBSPモジュールのV7.20のr_bsp/mcu/all/r_rx_compiler.hから抜粋したままのもの
#if defined(__CCRX__)/* Standard */#if BSP_CFG_RTOS_USED == 4 /* Renesas RI600V4 & RI600PX */#define R_BSP_PRAGMA_INTERRUPT(function_name, vector) extern void function_name(void);#define R_BSP_PRAGMA_STATIC_INTERRUPT(function_name, vector) void function_name(void);#define R_BSP_PRAGMA_INTERRUPT_FUNCTION(function_name) extern void function_name(void);#else /* BSP_CFG_RTOS_USED != 4*/#define R_BSP_PRAGMA_INTERRUPT(function_name, vector) R_BSP_PRAGMA(interrupt function_name(vect=vector))\ extern void function_name(void);#define R_BSP_PRAGMA_STATIC_INTERRUPT(function_name, vector) R_BSP_PRAGMA(interrupt function_name(vect=vector))\ static void function_name(void);#define R_BSP_PRAGMA_INTERRUPT_FUNCTION(function_name) R_BSP_PRAGMA(interrupt function_name)\ extern void function_name(void);#endif /* BSP_CFG_RTOS_USED */#define R_BSP_PRAGMA_STATIC_INTERRUPT_FUNCTION(function_name) R_BSP_PRAGMA(interrupt function_name)\ static void function_name(void);#define R_BSP_ATTRIB_INTERRUPT extern /* only this one because of no corresponding keyword */#if BSP_CFG_RTOS_USED == 4 /* Renesas RI600V4 & RI600PX */#define R_BSP_ATTRIB_STATIC_INTERRUPT #else /* BSP_CFG_RTOS_USED !=4 */#define R_BSP_ATTRIB_STATIC_INTERRUPT static /* only this one because of no corresponding keyword */#endif /* BSP_CFG_RTOS_USED *//* Fast */#define R_BSP_PRAGMA_FAST_INTERRUPT(function_name, vector) R_BSP_PRAGMA(interrupt function_name(vect=vector, fint))\ extern void function_name(void);#define R_BSP_PRAGMA_STATIC_FAST_INTERRUPT(function_name, vector) R_BSP_PRAGMA(interrupt function_name(vect=vector, fint))\ static void function_name(void);#define R_BSP_PRAGMA_FAST_INTERRUPT_FUNCTION(function_name) R_BSP_PRAGMA(interrupt function_name(fint))\ extern void function_name(void);#define R_BSP_PRAGMA_STATIC_FAST_INTERRUPT_FUNCTION(function_name) R_BSP_PRAGMA(interrupt function_name(fint))\ static void function_name(void);#define R_BSP_ATTRIB_FAST_INTERRUPT extern /* only this one because of no corresponding keyword */#define R_BSP_ATTRIB_STATIC_FAST_INTERRUPT static /* only this one because of no corresponding keyword *//* Default */#if BSP_CFG_RTOS_USED == 4 /* Renesas RI600V4 & RI600PX */#define R_BSP_PRAGMA_INTERRUPT_DEFAULT(function_name) extern void function_name(void);#define R_BSP_PRAGMA_STATIC_INTERRUPT_DEFAULT(function_name) void function_name(void);#else /* BSP_CFG_RTOS_USED != 4 */#define R_BSP_PRAGMA_INTERRUPT_DEFAULT(function_name) R_BSP_PRAGMA(interrupt function_name)\ extern void function_name(void);#define R_BSP_PRAGMA_STATIC_INTERRUPT_DEFAULT(function_name) R_BSP_PRAGMA(interrupt function_name)\ static void function_name(void);#endif /* BSP_CFG_RTOS_USED */
#elif defined(__GNUC__)/* Standard */#define R_BSP_PRAGMA_INTERRUPT(function_name, vector) extern void function_name(void) __attribute__((interrupt(R_BSP_SECNAME_INTVECTTBL, vector)));#define R_BSP_PRAGMA_STATIC_INTERRUPT(function_name, vector) static void function_name(void) __attribute__((interrupt(R_BSP_SECNAME_INTVECTTBL, vector), used));#define R_BSP_PRAGMA_INTERRUPT_FUNCTION(function_name) extern void function_name(void) __attribute__((interrupt));#define R_BSP_PRAGMA_STATIC_INTERRUPT_FUNCTION(function_name) static void function_name(void) __attribute__((interrupt, used));#define R_BSP_ATTRIB_INTERRUPT extern /* only this one because __attribute__((interrupt)) prevents GNURX from generating vector */#define R_BSP_ATTRIB_STATIC_INTERRUPT static /* only this one because __attribute__((interrupt, used)) prevents GNURX from generating vector *//* Fast */#define R_BSP_PRAGMA_FAST_INTERRUPT(function_name, vector) extern void function_name(void) __attribute__((interrupt(R_BSP_SECNAME_INTVECTTBL, vector))) \ __attribute__((fast_interrupt));#define R_BSP_PRAGMA_STATIC_FAST_INTERRUPT(function_name, vector) static void function_name(void) __attribute__((interrupt(R_BSP_SECNAME_INTVECTTBL, vector), used)) \ __attribute__((fast_interrupt, used));#define R_BSP_PRAGMA_FAST_INTERRUPT_FUNCTION(function_name) extern void function_name(void) __attribute__((fast_interrupt));#define R_BSP_PRAGMA_STATIC_FAST_INTERRUPT_FUNCTION(function_name) static void function_name(void) __attribute__((fast_interrupt, used));#define R_BSP_ATTRIB_FAST_INTERRUPT extern /* __attribute__((interrupt(fast))) Not necessary, but Don't forget a R_BSP_PRAGMA_FAST_INTERRUPT() declaration */#define R_BSP_ATTRIB_STATIC_FAST_INTERRUPT static /* __attribute__((interrupt(fast)), used) Not necessary, but Don't forget a R_BSP_PRAGMA_STATIC_FAST_INTERRUPT() declaration *//* Default */#define R_BSP_PRAGMA_INTERRUPT_DEFAULT(function_name) extern void function_name(void) __attribute__((interrupt(R_BSP_SECNAME_INTVECTTBL, "$default")));#define R_BSP_PRAGMA_STATIC_INTERRUPT_DEFAULT(function_name) static void function_name(void) __attribute__((interrupt(R_BSP_SECNAME_INTVECTTBL, "$default"), used));
#elif defined(__ICCRX__)/* Standard */#define R_BSP_PRAGMA_INTERRUPT(function_name, vect) R_BSP_PRAGMA(vector=vect)\ extern __interrupt void function_name(void);#define R_BSP_PRAGMA_STATIC_INTERRUPT(function_name, vect) R_BSP_PRAGMA(vector=vect)\ static __interrupt void function_name(void);#define R_BSP_PRAGMA_INTERRUPT_FUNCTION(function_name) extern __interrupt void function_name(void);#define R_BSP_PRAGMA_STATIC_INTERRUPT_FUNCTION(function_name) static __interrupt void function_name(void);#define R_BSP_ATTRIB_INTERRUPT extern __interrupt /* ICCRX requires __interrupt not only at a function declaration but also at a function definition */#define R_BSP_ATTRIB_STATIC_INTERRUPT static __interrupt /* ICCRX requires __interrupt not only at a function declaration but also at a function definition *//* Fast */#define R_BSP_PRAGMA_FAST_INTERRUPT(function_name, vect) R_BSP_PRAGMA(vector=vect)\ extern __fast_interrupt void function_name(void);#define R_BSP_PRAGMA_STATIC_FAST_INTERRUPT(function_name, vect) R_BSP_PRAGMA(vector=vect)\ static __fast_interrupt void function_name(void);#define R_BSP_PRAGMA_FAST_INTERRUPT_FUNCTION(function_name) extern __fast_interrupt void function_name(void);#define R_BSP_PRAGMA_STATIC_FAST_INTERRUPT_FUNCTION(function_name) static __fast_interrupt void function_name(void);#define R_BSP_ATTRIB_FAST_INTERRUPT extern __fast_interrupt /* ICCRX requires __interrupt not only at a function declaration but also at a function definition */#define R_BSP_ATTRIB_STATIC_FAST_INTERRUPT static __fast_interrupt /* ICCRX requires __interrupt not only at a function declaration but also at a function definition *//* Default */#define R_BSP_PRAGMA_INTERRUPT_DEFAULT(function_name) extern __interrupt void function_name(void);#define R_BSP_PRAGMA_STATIC_INTERRUPT_DEFAULT(function_name) static __interrupt void function_name(void);#endif