こんにちは。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です。すみません、ちょっと話が逆向きに飛ぶのですけれども、以前に投稿したようにCGコンポーネントの割り込み関数は以下の小細工により関数先頭で多重割り込み許可にすることが出来るのですが、小細工の形を1つ前の投稿(および2つ前の投稿)と同じような形にしてみたくて、以下のような小細工にしてみました。なお、以前に投稿した時(のその1つ前の投稿)に書いたことの繰り返しですけれども、関数先頭で多重割り込み許可を設定される、ということを想定されて設計とか設計レビューとかされていないと思いますので、無理矢理そういうことをすると誤動作するリスクはもちろんあると思っています。(他方では、IPLを操作する方のやり方ならば誤動作するリスクが大幅に低下するような気がしています。)以前に投稿した小細工:
#undef VECT#define VECT( x , y ) _VECT( _ ## x ## _ ## y ), enable
1つ前の投稿(および2つ前の投稿)と同じような形にした今回の小細工 (前半は独立したヘッダファイルへ切り分け可能)
#define _R_CG_ATTRIB_INTERRUPT_EI_vect(...) enable, vect __VA_ARGS__)#define R_CG_ATTRIB_INTERRUPT_EI_vect _R_CG_ATTRIB_INTERRUPT_EI_vect(#define R_CG_ATTRIB_INTERRUPT_EI_void void#define R_CG_ATTRIB_INTERRUPT_EI(function_name, ...) function_name(R_CG_ATTRIB_INTERRUPT_EI_##__VA_ARGS__)#define r_Config_RIIC0_transmit_interrupt(...) R_CG_ATTRIB_INTERRUPT_EI(r_Config_RIIC0_transmit_interrupt, __VA_ARGS__)#define r_Config_RIIC0_receive_interrupt(...) R_CG_ATTRIB_INTERRUPT_EI(r_Config_RIIC0_receive_interrupt, __VA_ARGS__)
CC-RXソース例: Config_RIIC0_user.c (ユーザ記述部以外は今までの繰り返し(ユーザ記述部は上の今回の小細工なので省略))
/* Start user code for global. Do not edit comment generated here */…省略(上の今回の小細工です)…/* End user code. Do not edit comment generated here */
#if FAST_INTERRUPT_VECTOR == VECT_RIIC0_TXI0#pragma interrupt r_Config_RIIC0_transmit_interrupt(vect=VECT(RIIC0,TXI0),fint)#else#pragma interrupt r_Config_RIIC0_transmit_interrupt(vect=VECT(RIIC0,TXI0))#endifstatic void r_Config_RIIC0_transmit_interrupt(void){ …途中省略…}
#if FAST_INTERRUPT_VECTOR == VECT_RIIC0_RXI0#pragma interrupt r_Config_RIIC0_receive_interrupt(vect=VECT(RIIC0,RXI0),fint)#else#pragma interrupt r_Config_RIIC0_receive_interrupt(vect=VECT(RIIC0,RXI0))#endifstatic void r_Config_RIIC0_receive_interrupt(void){ …途中省略…}
リストファイル: (以前に投稿した小細工の場合の繰り返し(同じ生成コードです))コンパイルオプションに一応 -save_acc (割り込み関数でのアキュムレータの退避/復帰を行う)を指定アキュムレータが使われない/値が壊れないことを認識してアキュムレータの退避/復帰を省略していますね
00000001 __$r_Config_RIIC0_transmit_interrupt: .STACK __$r_Config_RIIC0_transmit_interrupt=24 .RVECTOR 53,__$r_Config_RIIC0_transmit_interrupt00000001 7FA8 SETPSW I00000003 6E14 PUSHM R1-R4 …途中省略…00000048 6F14 POPM R1-R40000004A 7F95 RTE …途中省略…00000061 6F14 POPM R1-R400000063 7F95 RTE …途中省略…00000082 6F14 POPM R1-R400000084 7F95 RTE …途中省略…000000B2 6F14 POPM R1-R4000000B4 7F95 RTE …途中省略…000000D8 6F14 POPM R1-R4000000DA 7F95 RTE …途中省略…000000F4 6F14 POPM R1-R4000000F6 7F95 RTE …途中省略…00000112 6F14 POPM R1-R400000114 7F95 RTE
00000156 __$r_Config_RIIC0_receive_interrupt: .STACK __$r_Config_RIIC0_receive_interrupt=32 .RVECTOR 52,__$r_Config_RIIC0_receive_interrupt00000156 7FA8 SETPSW I00000158 6E15 PUSHM R1-R5 …1行省略…00000160 6040 SUB #04H, R0 …途中省略…0000025D 6240 ADD #04H, R00000025F 6F15 POPM R1-R500000261 7F95 RTE