こんにちは。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です。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