こんにちは。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です。別スレッド『GNURX用のCCRXmachine.hとCCRXmachine.cというソースがe2 studioフォルダにありました(内容は概ね名前から予想される通りのものでした)』に投稿したのですが、先月リリースされたGNURX 8.3.0.202002(及びGNURL78 4.9.2.202002)でスタック使用量の計算方法の修正があったようなので調べてみました。調査に使ったプロジェクトのファイル一式issue_20200509.zip 742KB上記に含まれるビルド結果のフォルダ一覧HardwareDebug.8.3.0.201904.O0 → GNURX 8.3.0.201904 最適化無し (-O0)HardwareDebug.8.3.0.201904.O2 → GNURX 8.3.0.201904 最適化レベル2 (-O2)HardwareDebug.8.3.0.201904.Og → GNURX 8.3.0.201904 デバッグ優先最適化 (-Og)HardwareDebug.8.3.0.202002.O0 → GNURX 8.3.0.202002 最適化無し (-O0)HardwareDebug.8.3.0.202002.O2 → GNURX 8.3.0.202002 最適化レベル2 (-O2)HardwareDebug.8.3.0.202002.Og → GNURX 8.3.0.202002 デバッグ優先最適化 (-Og)結果は以下の表の通り、かなり期待値と一致するようになっていました。ただ、まだ以下の不一致が残っていました。また、一致していても疑念のある項目もあります。GNURX 8.3.0.202002で残っているスタック使用量の不一致の内容(1) 最適化ありの場合に通常の関数で表示値が期待値より4バイト多い (表の赤色文字/ピンク色背景の箇所)(2) 割り込み関数でPSWの分を計上し忘れている気がします (表の赤色文字/黄色背景の箇所)GNURX 8.3.0.202002でスタック使用量が一致していても疑念のある内容(ただし直感でしかないですが)(3) 最適化ありの場合に通常の関数で基本的に表示値が期待値より4バイト多いが別要因発生により運良く一致? (表の青色文字/ピンク色背景の箇所)(4) 割り込み関数では基本的にPSWの分を計上し忘れているが別要因発生により運良く一致? (表の青色文字/黄色背景の箇所)
スタック解析ビューの表示は以下の画面コピーの通り、[呼び出し先関数との合計を表示]に設定しています。また、期待値はリストファイルのアセンブラコードから求めたものです。以下、それぞれのスタック解析ビューの画面コピーです。GNURX 8.3.0.201904 最適化無し (-O0)GNURX 8.3.0.201904 最適化レベル2 (-O2)GNURX 8.3.0.201904 デバッグ優先最適化 (-Og)GNURX 8.3.0.202002 最適化無し (-O0)GNURX 8.3.0.202002 最適化レベル2 (-O2)GNURX 8.3.0.202002 デバッグ優先最適化 (-Og)以下、ソースコード(抜粋)と幾つかのリストファイル(抜粋)です。src/Test.c
uint32_t func0( void ){ return 0;}uint32_t func1( uint32_t a1 ){ return a1;}uint32_t func4( uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4 ){ return a1 + a2 + a3 + a4;}uint32_t func5( uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5 ){ return a1 + a2 + a3 + a4 + a5;}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 ){ return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8;}
src/TestStackAnalysisForGNURX.c
extern volatile uint32_t a1, a2, a3, a4, a5, a6, a7, a8;extern volatile uint32_t r0, r1, r4, r5, r8;
int main(void){ r0 = func0(); r1 = func1( a1 ); r4 = func4( a1, a2, a3, a4 ); r5 = func5( a1, a2, a3, a4, a5 ); r8 = func8( a1, a2, a3, a4, a5, a6, a7, a8 );#if 1 (*fptr)();#elif 0 func();#endif while(1) { // TODO: add application code here } return 0;}
generate/interrupt_handlers.h
void INT_Excep_PERIB_INTB181(void) __attribute__ ((interrupt));
generate/inthandler.c
void INT_Excep_PERIB_INTB181(void){ }
HardwareDebug.8.3.0.202002.O2/Test.lst
7 _func0: 12:../src/Test.c **** uint32_t func0( void ) 13:../src/Test.c **** { 14:../src/Test.c **** return 0; 15:../src/Test.c **** } 13 0000 66 01 mov.L #0, r1 14 0002 02 rts ⇒ スタック使用量の期待値 = 4
20 _func1: 17:../src/Test.c **** uint32_t func1( uint32_t a1 ) 18:../src/Test.c **** { 19:../src/Test.c **** return a1; 20:../src/Test.c **** } 26 0000 02 rts ⇒ スタック使用量の期待値 = 4
32 _func4: 22:../src/Test.c **** uint32_t func4( uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4 ) 23:../src/Test.c **** { 24:../src/Test.c **** return a1 + a2 + a3 + a4; 38 0000 4B 34 add r3, r4 40 0002 4B 24 add r2, r4 25:../src/Test.c **** } 42 0004 4B 41 add r4, r1 44 0006 02 rts ⇒ スタック使用量の期待値 = 4
50 _func5: 27:../src/Test.c **** uint32_t func5( uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5 ) 28:../src/Test.c **** { 54 0000 60 40 sub #4, r0 29:../src/Test.c **** return a1 + a2 + a3 + a4 + a5; 58 0002 06 89 04 02 add 8[r0].L, r4 60 0006 4B 34 add r3, r4 61 0008 4B 24 add r2, r4 30:../src/Test.c **** } 63 000a 4B 41 add r4, r1 65 000c 67 01 rtsd #4 ⇒ スタック使用量の期待値 = 8
71 _func8: 32:../src/Test.c **** 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 ) 33:../src/Test.c **** { 75 0000 7E A7 push.l r7 77 0002 71 00 F0 add #-16, r0 34:../src/Test.c **** return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8; 81 0005 75 47 18 mov.L #24, r7 82 0008 4B 07 add r0, r7 83 000a A8 F5 mov.L 8[r7], r5 85 000c 06 89 75 03 add 12[r7].L, r5 86 0010 06 89 75 01 add 4[r7].L, r5 87 0014 06 88 75 add [r7].L, r5 88 0017 4B 45 add r4, r5 89 0019 4B 35 add r3, r5 90 001b 4B 25 add r2, r5 35:../src/Test.c **** } 92 001d 4B 51 add r5, r1 94 001f 3F 77 05 rtsd #20, r7-r7 ⇒ スタック使用量の期待値 = 24
HardwareDebug.8.3.0.202002.O2/inthandler.lst
1370 _INT_Excep_PERIB_INTB181: 1372 ; Note: Interrupt Handler 1373 0000 7F 95 rte ⇒ スタック使用量の期待値 = 8
HardwareDebug.8.3.0.202002.O2/TestStackAnalysisForGNURX.lst
18 _main: 55:../src/TestStackAnalysisForGNURX.c **** int main(void) 56:../src/TestStackAnalysisForGNURX.c **** { 21 0000 6E 6C pushm r6-r12 ↓ 23 0002 71 00 F0 add #-16, r0 ⇒ main()内のスタック使用量の期待値 = 48 = 4(戻り番地分)+28(r6~r12)+16(此処) 57:../src/TestStackAnalysisForGNURX.c **** 58:../src/TestStackAnalysisForGNURX.c **** r0 = func0(); 59:../src/TestStackAnalysisForGNURX.c **** r1 = func1( a1 ); 27 0005 FB 72 00 00 00 00 mov.L #_a1, r7 58:../src/TestStackAnalysisForGNURX.c **** r1 = func1( a1 ); 29 000b 05 00 00 00 bsr _func0 58:../src/TestStackAnalysisForGNURX.c **** r1 = func1( a1 ); 32 000f FB A2 00 00 00 00 mov.L #_r0, r10 33 0015 E3 A1 mov.L r1, [r10] 60:../src/TestStackAnalysisForGNURX.c **** r4 = func4( a1, a2, a3, a4 ); 36 0017 FB B2 00 00 00 00 mov.L #_a2, r11 59:../src/TestStackAnalysisForGNURX.c **** r1 = func1( a1 ); 38 001d EC 71 mov.L [r7], r1 40 001f FB 62 00 00 00 00 mov.L #_a3, r6 41 0025 FB A2 00 00 00 00 mov.L #_a4, r10 61:../src/TestStackAnalysisForGNURX.c **** r5 = func5( a1, a2, a3, a4, a5 ); 43 002b FB C2 00 00 00 00 mov.L #_a5, r12 59:../src/TestStackAnalysisForGNURX.c **** r4 = func4( a1, a2, a3, a4 ); 45 0031 05 00 00 00 bsr _func1 59:../src/TestStackAnalysisForGNURX.c **** r4 = func4( a1, a2, a3, a4 ); 48 0035 FB 52 00 00 00 00 mov.L #_r1, r5 49 003b E3 51 mov.L r1, [r5] 60:../src/TestStackAnalysisForGNURX.c **** r4 = func4( a1, a2, a3, a4 ); 52 003d EC 71 mov.L [r7], r1 53 003f EC B2 mov.L [r11], r2 54 0041 EC 63 mov.L [r6], r3 55 0043 EC A4 mov.L [r10], r4 56 0045 05 00 00 00 bsr _func4 60:../src/TestStackAnalysisForGNURX.c **** r4 = func4( a1, a2, a3, a4 ); 59 0049 FB 52 00 00 00 00 mov.L #_r4, r5 60 004f E3 51 mov.L r1, [r5] 63 0051 EC 71 mov.L [r7], r1 64 0053 EC B2 mov.L [r11], r2 65 0055 EC 63 mov.L [r6], r3 66 0057 EC A4 mov.L [r10], r4 67 0059 EC C5 mov.L [r12], r5 68 005b E3 05 mov.L r5, [r0] 69 005d 05 00 00 00 bsr _func5 72 0061 FB 52 00 00 00 00 mov.L #_r5, r5 73 0067 E3 51 mov.L r1, [r5] 62:../src/TestStackAnalysisForGNURX.c **** r8 = func8( a1, a2, a3, a4, a5, a6, a7, a8 ); 76 0069 EC 71 mov.L [r7], r1 77 006b EC B2 mov.L [r11], r2 78 006d EC 63 mov.L [r6], r3 79 006f EC A4 mov.L [r10], r4 80 0071 EC C6 mov.L [r12], r6 81 0073 FB 72 00 00 00 00 mov.L #_a6, r7 82 0079 EC 75 mov.L [r7], r5 83 007b FB 72 00 00 00 00 mov.L #_a7, r7 84 0081 EC 77 mov.L [r7], r7 85 0083 FB A2 00 00 00 00 mov.L #_a8, r10 86 0089 EC AA mov.L [r10], r10 87 008b E3 06 mov.L r6, [r0] 88 008d A0 0D mov.L r5, 4[r0] 89 008f E7 0A 03 mov.L r10, 12[r0] 90 0092 A0 87 mov.L r7, 8[r0] 91 0094 05 00 00 00 bsr _func8 63:../src/TestStackAnalysisForGNURX.c **** #if 1 64:../src/TestStackAnalysisForGNURX.c **** (*fptr)(); 94 0098 FB 72 00 00 00 00 mov.L #_fptr, r7 95 009e EC 77 mov.L [r7], r7 62:../src/TestStackAnalysisForGNURX.c **** r8 = func8( a1, a2, a3, a4, a5, a6, a7, a8 ); 97 00a0 FB A2 00 00 00 00 mov.L #_r8, r10 98 00a6 E3 A1 mov.L r1, [r10] 101 00a8 7F 17 jsr r7 103 .balign 8,3,3 104 .L4: 65:../src/TestStackAnalysisForGNURX.c **** #elif 0 66:../src/TestStackAnalysisForGNURX.c **** func(); 67:../src/TestStackAnalysisForGNURX.c **** #endif 68:../src/TestStackAnalysisForGNURX.c **** 69:../src/TestStackAnalysisForGNURX.c **** while(1) 70:../src/TestStackAnalysisForGNURX.c **** { 71:../src/TestStackAnalysisForGNURX.c **** // TODO: add application code here 72:../src/TestStackAnalysisForGNURX.c **** } 109 00aa 2E 00 bra .L4