EK-RA8M1 の Cortex-M85 の Performance Monitoring Unit (PMU) について

EK-RA8M1 で Performance Monitoring Unit (PMU) を使おうとしていますが、DWTとPMUのCCNTR(0xE000307C)のサイクルカウントは取得できているのですが、PMUイベントはサイクルカウントも含めて、全て 0 のままカウントアップされていません。

環境は e2studio 25.1.0 の Renesas RA C/C++ Project で、gcc / armclang, Flat / TrustZone Secure のどれも同じ結果でした。

CMSISのAPI経由でもレジスタ直叩きでも同じ結果でした。

PMUに関する設定、データ取得手順ですが、別のCortex-M55のSoC (Grove Vision AI Module V2) では同じ設定でPMUイベントが取れたので、ソフトウェアの手順がおかしいわけではないと思っております。

EK-RA8M1 は PMUイベントが取得可能なものでしょうか。

PMU関連のレジスタにはアクセスできていますので、PMUはあると思っているのですが、HWの設定が必要?使用には条件または制限がある?

J-Link RTT Viewerで、レジスタダンプしたところ、このようになっておりました。

00> [PMU] num_event_counters 8
00> PMU->CNTENSET 0x00000000
00> PMU->CNTENCLR 0x00000000
00> PMU->INTENSET 0x00000000
00> PMU->INTENCLR 0x00000000
00> PMU->OVSCLR 0x00000000
00> PMU->SWINC 0x00000000
00> PMU->OVSSET 0x00000000
00> PMU->TYPE 0x00A05F08
00> PMU->CTRL 0x00000000
00> PMU->AUTHSTATUS 0x00FF00FF
00> PMU->DEVARCH 0x47700A06
00> PMU->DEVTYPE 0x00000016

ここまで設定直後

ここから、PMU->CTRL と PMU->CNTENSET をセットして、一定時間経過後のダンプがこうなりました。

00> PMU->CTRL 0x00000001
00> PMU->CNTENSET 0x800000FF
00> [DWT] Cycle Count Register 2258268206
00> [DWT] CPI Count Register 0
00> [DWT] Exception Overhead Count Register 0
00> [DWT] Sleep Count Register 0
00> [DWT] LSU Count Register 0
00> [DWT] Folded-instruction Count Register 0
00> [DWT] Program Counter Sample Register 33555588
00> [PMU] Cycle count 2258276003
00> [PMU] Time 4704741 [us]
00> PMU_EVTYPER[0] 0x0011, PMU_EVCNTR[0] 0
00> PMU_EVTYPER[1] 0x0001, PMU_EVCNTR[1] 0
00> PMU_EVTYPER[2] 0x0006, PMU_EVCNTR[2] 0
00> PMU_EVTYPER[3] 0x0007, PMU_EVCNTR[3] 0
00> PMU_EVTYPER[4] 0x0008, PMU_EVCNTR[4] 0
00> PMU_EVTYPER[5] 0x0023, PMU_EVCNTR[5] 0
00> PMU_EVTYPER[6] 0x0024, PMU_EVCNTR[6] 0
00> PMU_EVTYPER[7] 0x003C, PMU_EVCNTR[7] 0

このように、PMUイベントは取得できておりません。

  • みりんレモンさん、こんにちは。

    RA8M1デバイスや周辺ソリューションの詳細な対応状況はルネサスの技術問い合わせ窓口に問い合わせされた方がよいかと思われます。
    特にCM85 PMUはArm CoreSight(デバッグ)の一部機能になるため、ツール・デバッガが使用する機能とバッティングしないように注意を払う必要があります。

    一先ず私の環境(EK-RA8D1、FSPv5.8.0、e2studio2025-01)で動作することを確認できましたので、手順を共有します。
    ※PMUレジスタ・CMSIS APIの使い方や実行手順が正しいかは分かりません。ご参考まで。

    ステップ1. RAプロジェクトを作成
      私のテストではBare Metal - Minimalテンプレート、Flatプロジェクトタイプ、GCCコンパイラ、J-Linkデバッガを選択
    ステップ2. Stacksタブでr_icuドライバを追加。インスタンス名は"g_external_irq0".
      これは例外呼び出しテスト用のダミーですので、その他のモジュール設定変更は不要
    ステップ3. Generate Project Contentボタンを押す
    ステップ4. 以下に添付のユーザコードをhal_entry.cファイルに追加
    ステップ5. プロジェクトをビルド
    ステップ6. デバッグ構成を開き、時間計測機能を無効化 (Debugger > デバッグ・ツール設定 > 時間計測)
    ステップ7. デバッグ接続開始
    ステップ8. プログラムを走らせ、hal_entry関数の末尾のブレイクポイントで停止するまで待つ
      停止したらcycle_count変数とevent_count_n (n=0~3)変数の値をe2studioの式ビューなどで確認
      event_count_0とevent_count_1の期待値は100、それ以外はクロック構成やL1キャッシュの動き次第で異なります。
      (参考)
      

    hal_entry.cファイルに実装するコード:

    #include "hal_data.h"
    
    volatile unsigned int cycle_count = 0;
    volatile unsigned int event_count_0 = 0;
    volatile unsigned int event_count_1 = 0;
    volatile unsigned int event_count_2 = 0;
    volatile unsigned int event_count_3 = 0;
    
    void pmu_test(void);
    void R_BSP_WarmStart(bsp_warm_start_event_t event);
    
    void hal_entry(void)
    {
        R_ICU_ExternalIrqOpen(&g_external_irq0_ctrl, &g_external_irq0_cfg);
        R_ICU_ExternalIrqEnable(&g_external_irq0_ctrl);
    
        pmu_test();
    
        __BKPT(0);
    }
    
    void pmu_test(void)
    {
        // Disable DWT CYCCNT
        DWT->CTRL &= 0xFFFFFFFE;
    
        // Enable the PMU
        // Note: Before using the PMU, software needs to ensure
        // that trace is enabled via the Debug Exception Monitor Control Register, DEMCR:
        CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
    
        __ISB();
        __DSB();
    
        ARM_PMU_Enable();
    
        // Configure Event Counter Registers
        ARM_PMU_Set_EVTYPER(0, ARM_PMU_SW_INCR);
        ARM_PMU_Set_EVTYPER(1, ARM_PMU_EXC_TAKEN);
        ARM_PMU_Set_EVTYPER(2, ARM_PMU_L1I_CACHE);
        ARM_PMU_Set_EVTYPER(3, ARM_PMU_L1I_CACHE_REFILL);
    
        // Reset Event Counters and Cycle Counter
        ARM_PMU_EVCNTR_ALL_Reset();
        ARM_PMU_CYCCNT_Reset();
    
        // Start incrementing Cycle Count Register and Event Counter Registers 0 ~ 3
        ARM_PMU_CNTR_Enable(PMU_CNTENSET_CCNTR_ENABLE_Msk|
                            PMU_CNTENSET_CNT0_ENABLE_Msk|
                            PMU_CNTENSET_CNT1_ENABLE_Msk|
                            PMU_CNTENSET_CNT2_ENABLE_Msk|
                            PMU_CNTENSET_CNT3_ENABLE_Msk);
    
        // Code you want to measure here
        for(int i=0; i<100; i++)
        {
            // Software increment for CNT0
            ARM_PMU_CNTR_Increment(PMU_CNTENSET_CNT0_ENABLE_Msk);
    
            // Dummy exception call
            NVIC_SetPendingIRQ(g_external_irq0_cfg.irq);
    
            __NOP();
        }
    
        // Stop incrementing Cycle Count Register and Event Counter Registers 0 ~ 3
        ARM_PMU_CNTR_Disable(PMU_CNTENCLR_CCNTR_ENABLE_Msk|
                             PMU_CNTENCLR_CNT0_ENABLE_Msk|
                             PMU_CNTENCLR_CNT1_ENABLE_Msk|
                             PMU_CNTENSET_CNT2_ENABLE_Msk|
                             PMU_CNTENSET_CNT3_ENABLE_Msk);
    
        // Get count data
        cycle_count = ARM_PMU_Get_CCNTR();
        event_count_0 = ARM_PMU_Get_EVCNTR(0);
        event_count_1 = ARM_PMU_Get_EVCNTR(1);
        event_count_2 = ARM_PMU_Get_EVCNTR(2);
        event_count_3 = ARM_PMU_Get_EVCNTR(3);
    
        (void) cycle_count;
        (void) event_count_0;
        (void) event_count_1;
        (void) event_count_2;
        (void) event_count_3;
    }
    
    void R_BSP_WarmStart(bsp_warm_start_event_t event)
    {
        if (BSP_WARM_START_POST_C == event)
        {
            /* Configure pins. */
            R_IOPORT_Open (&IOPORT_CFG_CTRL, &IOPORT_CFG_NAME);
        }
    }
    

  • ReKawashima さん、

    ご対応ありがとうございます。

    こちらの環境(EK-RA8M1、FSPv5.8.0、e2studio2025-01)でも、教えていただいた手順でPMU Eventがカウントされていることが確認できました。

    元々作っていたプロジェクトで確認したところ、状況証拠から DWT->CTRL レジスタの CYCCNTENA ビットを落としていなかったことが原因だったようです。

    > 特にCM85 PMUはArm CoreSight(デバッグ)の一部機能になるため、ツール・デバッガが使用する機能とバッティングしないように注意を払う必要があります。

    Grove Vision AI Module V2では デバッガを接続せず確認したので、ご指摘の通りかと思います。

    これで、CPUストール要因の分析を進めることができるようになります。

    ありがとうございました。