2021年9月5日日曜日

STM32CubeIDE サイクル・カウンタ(CYCLECOUNTER)を使って処理速度を測定

STMicroのWebサイトで、CYCLECOUNTERレジスタを使ってマイコンの処理速度を測定する方法が紹介されています。

マイコンの演算速度を測る(その2)https://www.stmcu.jp/technical/hint/no-085/

GPIOをHigh/Lowさせて計測するよりスマートです。サイクル・カウンタとGPIO両方で処理速度を測定し、比較してみました。サイクル・カウンタの計測とGPIOの出力をオシロで観測した結果はほぼ同じ値になるはずです。

STM32CubeIDEのバージョンは1.7.0です。

MXの設定


Clock
HSE→PLL
HCLK:180MHz

Pinout & Configuration
System Core
  GPIO
    PA10
      GPIO mode: Output Push Pull
      Maximum output speed: Very High
      User Label: PIN_CHK1

ソースコード(main.cに追加)


  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    HAL_GPIO_TogglePin(PIN_CHK1_GPIO_Port, PIN_CHK1_Pin);
  }
  /* USER CODE END 3 */

ConfigurationはDebugで、最適化なし(-O0)

最適化の設定方法は「STM32CubeIDE: 覚え書き」の「Buildの設定」で書きました。

サイクル・カウンタで計測


公式ページの説明は少し分かりづらかったので、注釈をつけてみました。


① Run-Debug(F11)でDebug開始


Debugを開始するとint main(void)のHAL_Init()で停止します。

② 希望の測定開始BreakPointまでコード実行(Resume,F8)


行頭をダブルクリックするとブレークポイントを切り替えられます。ブレークポイントを設定し、F8を押します。

③ Window-Show View-Memory Browserを選択し、0xE0001000番地に移動


Memory Browserのテキストボックスに「0xE0001000」と入力し「Go」をクリックします。

④ 0xE0001000のLSBビットを‘1’に変更(CYCLECOUNTERの開始)*初回のみ


Memory Browser内で右クリックしてメニューを表示→「Cell Size」で1byteを選択します。0xE0001000のセルをクリックし「01」と入力しEnter。



⑤ 希望の測定終了BreakPointまでコード実行(Resume,F8)


⑥ 0xE0001004の値を確認(= CYCLECOUNTERの値)


Memory Browser内で右クリックしてメニューを表示→「Cell Size」で2byteを選択、「Radix」でDecimal Unsignedを選択。16byte区切りで10進表示になります。



⑦ 以降の測定Pointについては、0xE0001004の値を‘0’に変えて、②⑤⑥の繰り返し(④の再設定は不要)


0xE0001004, 0xE0001005のセルに「00000」と入力し、Enter。


今回は、

HAL_GPIO_TogglePin(PIN_CHK1_GPIO_Port, PIN_CHK1_Pin);

にBreakPointを置いて実行しました。Resumeすると、Whileループ内で再び同じ行に戻ります。

私の環境では、whileループの1回目は54、2回目以降は50となりました。1回目は何か特別な処理が行われていると思います。

50cycleとすると、180MHz駆動なので、(1 / 180MHz) * 50cycle ≒ 277.7ns

オシロでD2(PA10)の出力を観測


BreakPointを外し、Run-Debug(F11)、Resume(F8)して計測しました


周期 T = 555.2nsなので、Toggle1回分は半分の277.6nsです。

CYCLECOUNTERでの計測の結果とオシロの観測結果がほぼ等しいので、CYCLECOUNTERで処理速度を測定できているようです。

0 件のコメント:

コメントを投稿