こんにちは。NoMaYです。e2 studio 7.5.0+RXスマートコンフィグレータplugin 7.5.0+GNURX 2019q2(4.8.4.201902)で作業していてスタック解析ビューの致命的な(だと私は思う)制限事項に気付きました。1箇所でも関数ポインタで関数呼び出しする箇所があると、以下の画面コピーの通り(原因が大変分かり難い)エラーになってしまうのですが、そもそもR_BSPモジュールにそういう箇所が存在していますので、実務的には全く使えない、ということになりますね。(ちなみに、FreeRTOS Kernelのソースにもそういう箇所が存在していますし、FITの各モジュールでのコールバック関数の呼び出しも関数ポインタを使用した関数呼び出しですね。)現象再現プロジェクトのファイル一式issue_20191007.zip 162KBe2 studioのスタック解析ビューはGNURXでは関数ポインタで関数呼び出ししているとエラーになる素朴に関数呼び出ししているのであればスタック解析ビューにスタック情報が表示される
こんにちは。NoMaYです。今度はCC-RXでスタック使用量の見積もりの表示が期待値と一致するかどうか先日のGNURXと同様に調べてみました。結果は以下の表の通り、問題は見つかりませんでした。なお、今回気付いたのですが、CC-RXでは、GNURX(及びCC-RL)と異なり、スタック使用量の計算方法に以下の相違点がありました。(なお、諸般の事情で、CC-RXはV2.03、CC-RLはV1.02、です。) プログラムが必要とするスタック領域サイズを見積もるという観点からは、CC-RXの方法がGNURX(及びCC-RL)の方法より誤差が少なくなるので望ましいと思います。(誤差の具体例が、CC-RLですが、別スレッド『RL78 FreeRTOS APIを特別なおまじない記述無しで割り込みルーチンから呼び出せるようにしてみた(CC-RL/GNURL78)』にあります。)CC-RXとGNURX(及びCC-RL)のスタック使用量の計算方法の相違(CC-RXの方法がGNURX(及びCC-RL)の方法より望ましい)CC-RXの場合:スタック渡し引数で使用されるスタックは呼び出し先の関数に計上されるGNURX(及びCC-RL)の場合:スタック渡し引数で使用されるスタックは呼び出し元の関数に計上される調査に使ったプロジェクトのファイル一式issue_20200515.zip 987KB上記に含まれるビルド結果のフォルダ一覧DefaultBuild.v203.optimize0.speed → CC-RX V2.03 最適化レベル0/実行性能重視 (-optimize=0 -speed)DefaultBuild.v203.optimize2.speed → CC-RX V2.03 最適化レベル最大/実行性能重視 (-optimize=max -speed)
スタック解析ビューの表示は以下の画面コピーの通り、[呼び出し先関数との合計を表示]に設定しています。また、期待値はリストファイルのアセンブラコードから求めたものです。以下、それぞれのスタック解析ビューの画面コピーです。CC-RX V2.03 最適化レベル0/実行性能重視 (-optimize=0 -speed)CC-RX V2.03 最適化レベル最大/実行性能重視 (-optimize=max -speed)以下、幾つかのリストファイル(抜粋)です。DefaultBuild.v203.optimize_0.speed/src/Test.lst
00000000 _func0: ; 12 uint32_t func0( void )00000000 6040 SUB #04H, R0 ; 13 { ; 14 return 0;00000002 F80600 MOV.L #00000000H, [R0]00000005 6601 MOV.L #00000000H, R1 ; 15 }0000007 6701 RTSD #04H ⇒ スタック使用量の期待値 = 8 = 4(戻り番地分)+04H
00000009 _func1: .STACK _func1=12 ; 17 uint32_t func1( uint32_t a1 )00000009 6080 SUB #08H, R00000000B A009 MOV.L R1, 04H[R0] ; 18 { ; 19 return a1;0000000D E301 MOV.L R1, [R0] ; 20 }0000000F 6702 RTSD #08H ⇒ スタック使用量の期待値 = 12 = 4(戻り番地分)+08H
00000011 _func4: .STACK _func4=24 ; 22 uint32_t func4( uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4 )00000011 7100EC ADD #0FFFFFFECH, R000000014 A101 MOV.L R1, 10H[R0]00000016 A08A MOV.L R2, 0CH[R0]00000018 A083 MOV.L R3, 08H[R0]0000001A A00C MOV.L R4, 04H[R0] ; 23 { ; 24 return a1 + a2 + a3 + a4;0000001C A901 MOV.L 10H[R0], R10000001E 06890103 ADD 0CH[R0].L, R100000022 06890102 ADD 08H[R0].L, R100000026 4B41 ADD R4, R100000028 E301 MOV.L R1, [R0] ; 25 }0000002A 6705 RTSD #14H ⇒ スタック使用量の期待値 = 24 = 4(戻り番地分)+14H
0000002C _func5: .STACK _func5=28 ; 27 uint32_t func5( uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5 )0000002C 7100E8 ADD #0FFFFFFE8H, R00000002F A109 MOV.L R1, 14H[R0]00000031 A102 MOV.L R2, 10H[R0]00000033 A08B MOV.L R3, 0CH[R0]00000035 A084 MOV.L R4, 08H[R0]00000037 A98A MOV.L 1CH[R0], R2 ← スタック渡し引数00000039 A00A MOV.L R2, 04H[R0] ; 28 { ; 29 return a1 + a2 + a3 + a4 + a5;0000003B A909 MOV.L 14H[R0], R10000003D 06890104 ADD 10H[R0].L, R100000041 06890103 ADD 0CH[R0].L, R100000045 06890102 ADD 08H[R0].L, R100000049 4B21 ADD R2, R10000004B E301 MOV.L R1, [R0] ; 30 }0000004D 6706 RTSD #18H ⇒ スタック使用量の期待値 = 32 = 4(スタック渡し引数分)+4(戻り番地分)+18H
0000004F _func8: .STACK _func8=40 ; 32 uint32_t func8( uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5, uint32_t a6, uint32_t a7, uint32_t a8 )0000004F 7100DC ADD #0FFFFFFDCH, R000000052 A201 MOV.L R1, 20H[R0]00000054 A18A MOV.L R2, 1CH[R0]00000056 A183 MOV.L R3, 18H[R0]00000058 A10C MOV.L R4, 14H[R0]0000005A E5000A04 MOV.L 28H[R0], 10H[R0] ← スタック渡し引数0000005E E5000B03 MOV.L 2CH[R0], 0CH[R0] ← スタック渡し引数00000062 E5000C02 MOV.L 30H[R0], 08H[R0] ← スタック渡し引数00000066 AB0A MOV.L 34H[R0], R2 ← スタック渡し引数00000068 A00A MOV.L R2, 04H[R0] ; 33 { ; 34 return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8;0000006A AA01 MOV.L 20H[R0], R10000006C 06890107 ADD 1CH[R0].L, R100000070 06890106 ADD 18H[R0].L, R100000074 06890105 ADD 14H[R0].L, R100000078 06890104 ADD 10H[R0].L, R10000007C 06890103 ADD 0CH[R0].L, R100000080 06890102 ADD 08H[R0].L, R100000084 4B21 ADD R2, R100000086 E301 MOV.L R1, [R0] ; 35 }00000088 6709 RTSD #24H ⇒ スタック使用量の期待値 = 56 = 16(スタック渡し引数分)+4(戻り番地分)+24H
DefaultBuild.v203.optimize_0.speed/generate/intprg.lst
00000168 _Excep_PERIA_INTA209: .STACK _Excep_PERIA_INTA209=8 .RVECTOR 209,_Excep_PERIA_INTA209 ; 558 ; 559 // PERIA INTA209 ; 560 void Excep_PERIA_INTA209(void){ }00000168 7F95 RTE ⇒ スタック使用量の期待値 = 8
DefaultBuild.v203.optimize_0.speed/src/TestStackAnalysisForCCRX.lst
00000001 _main: .STACK _main=24 ; 41 int main(void)00000001 7EA6 PUSH.L R6 ⇒ main()内のスタック使用量の期待値 = 8 = 4(戻り番地分)+4(此処) ; 42 { ; 44 r0 = func0();00000003 05rrrrrr A BSR _func000000007 FBE2rrrrrrrr MOV.L #_r0, R140000000D E3E1 MOV.L R1, [R14] ; 45 r1 = func1( a1 );0000000F FBE2rrrrrrrr MOV.L #_a1, R1400000015 ECE1 MOV.L [R14], R100000017 05rrrrrr A BSR _func10000001B FBE2rrrrrrrr MOV.L #_r1, R1400000021 E3E1 MOV.L R1, [R14] ; 46 r4 = func4( a1, a2, a3, a4 );00000023 FBE2rrrrrrrr MOV.L #_a1, R1400000029 ECE1 MOV.L [R14], R10000002B FBE2rrrrrrrr MOV.L #_a2, R1400000031 ECE2 MOV.L [R14], R200000033 FBE2rrrrrrrr MOV.L #_a3, R1400000039 ECE3 MOV.L [R14], R30000003B FBE2rrrrrrrr MOV.L #_a4, R1400000041 ECE4 MOV.L [R14], R400000043 05rrrrrr A BSR _func400000047 FBE2rrrrrrrr MOV.L #_r4, R140000004D E3E1 MOV.L R1, [R14] ; 47 r5 = func5( a1, a2, a3, a4, a5 );0000004F FBE2rrrrrrrr MOV.L #_a1, R1400000055 ECE1 MOV.L [R14], R100000057 FBE2rrrrrrrr MOV.L #_a2, R140000005D ECE2 MOV.L [R14], R20000005F FBE2rrrrrrrr MOV.L #_a3, R1400000065 ECE3 MOV.L [R14], R300000067 FBE2rrrrrrrr MOV.L #_a4, R140000006D ECE4 MOV.L [R14], R40000006F FBE2rrrrrrrr MOV.L #_a5, R1400000075 ECEE MOV.L [R14], R1400000077 6040 SUB #04H, R000000079 E30E MOV.L R14, [R0]0000007B 05rrrrrr A BSR _func50000007F 6240 ADD #04H, R000000081 FBE2rrrrrrrr MOV.L #_r5, R1400000087 E3E1 MOV.L R1, [R14] ; 48 r8 = func8( a1, a2, a3, a4, a5, a6, a7, a8 );00000089 FBE2rrrrrrrr MOV.L #_a1, R140000008F ECE1 MOV.L [R14], R100000091 FBE2rrrrrrrr MOV.L #_a2, R1400000097 ECE2 MOV.L [R14], R200000099 FBE2rrrrrrrr MOV.L #_a3, R140000009F ECE3 MOV.L [R14], R3000000A1 FBE2rrrrrrrr MOV.L #_a4, R14000000A7 ECE4 MOV.L [R14], R4000000A9 FBE2rrrrrrrr MOV.L #_a5, R14000000AF ECEE MOV.L [R14], R14000000B1 FBF2rrrrrrrr MOV.L #_a6, R15000000B7 ECF5 MOV.L [R15], R5000000B9 FBF2rrrrrrrr MOV.L #_a7, R15000000BF ECFF MOV.L [R15], R15000000C1 FB62rrrrrrrr MOV.L #_a8, R6000000C7 EC66 MOV.L [R6], R6000000C9 7100F0 ADD #0FFFFFFF0H, R0000000CC A08E MOV.L R6, 0CH[R0]000000CE E70F02 MOV.L R15, 08H[R0]000000D1 A00D MOV.L R5, 04H[R0]000000D3 E30E MOV.L R14, [R0]000000D5 05rrrrrr A BSR _func8000000D9 710010 ADD #10H, R0000000DC FBE2rrrrrrrr MOV.L #_r8, R14000000E2 E3E1 MOV.L R1, [R14] ; 49 #if 1 ; 50 (*fptr)();000000E4 FBE2rrrrrrrr MOV.L #_fptr, R14000000EA ECEE MOV.L [R14], R14000000EC 7F1E JSR R14000000EE L17: ; bb24 ; 51 #elif 0 ; 52 func(); ; 53 #endif ; 54 ; 55 while(1)000000EE 2Err B BRA L17 ; 56 { ; 57 // TODO: add application code here ; 58 } ; 59 }