2021年8月12日木曜日

STM32CubeIDE Nucleo-G431KBの実行速度を測定 I2S

I2Sのサンプリング周波数が192kHzの場合、周期 T = 1 / f ≒ 5.21us、L/Rの2chだとその半分の2.60usがリアルタイムな計算に使える時間となります。

前回、FPUを使って算術関数の実行速度を測定しました。G431KBの場合、expf()1000回で1msだったので、1回あたり1usとなります。リアルタイムに計算する場合せいぜいexpf()2回が限度となります。

さらに、I2SのDMA転送が完了するまでメモリの内容はいじれませんので、転送が完了するまでの待ち時間が発生します。転送完了の割り込みが発生してから次の転送開始までどれぐらいの猶予があるか測定しました。

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

/* USER CODE BEGIN PV */
int32_t data[2] = { 0 };
int32_t tx_buffer[2] = { 0 };
/* USER CODE END PV */

<中略>

int main(void)
{
  /* USER CODE BEGIN 2 */
  HAL_I2S_Transmit_DMA(&hi2s2, (uint16_t *)tx_buffer, 2);
  /* USER CODE END 2 */

<中略>

/* USER CODE BEGIN 4 */
static int32_t swap16(int32_t x)
{
	return ((uint32_t)x << 16) | ((uint32_t)x >> 16);
}

void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
{
	HAL_GPIO_WritePin(CK_HALF_CPLT_GPIO_Port, CK_HALF_CPLT_Pin, GPIO_PIN_SET);

	tx_buffer[0] = swap16(data[0]++);

	HAL_GPIO_WritePin(CK_HALF_CPLT_GPIO_Port, CK_HALF_CPLT_Pin, GPIO_PIN_RESET);
}

void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s)
{
	HAL_GPIO_WritePin(CK_CPLT_GPIO_Port, CK_CPLT_Pin, GPIO_PIN_SET);

	tx_buffer[1] = swap16(data[1]--);

	HAL_GPIO_WritePin(CK_CPLT_GPIO_Port, CK_CPLT_Pin, GPIO_PIN_RESET);
}
/* USER CODE END 4 */

32bit値をインクリメント、デクリメントして出力しています。STM32のI2Sは32bitの場合上下16bitを入れ替える必要があり、swap16()で行っています。参考「STM32CubeIDE: I2Sを32bit長で使う

F303K8はSTM32CubeIDEではI2Sの設定ができませんので、F446RE、F767ZI、G431KBで測定しました。

F446REの設定


MXの設定

Pinout & Configuration
  System Core
    GPIO
      PC10
        Maximum output speed: Very High
        User Label: CK_HALF_CPLT
      PC12
        Maximum output speed: Very High
        User Label: CK_CPLT
  Multimedia
    I2S2
   Mode: Half-Duplex Master
      Parameter Settings
        Data and Frame Format: 32 Bits Data on 32 Bits Frame
        Selected Audio Frequency: 192KHz
        Real Audio Frequency: 195.312Khz
      DMA Settings
        SPI2_TX
          Mode: Circular
          Data Width: Half Word / Half Word

Clock Configuration
     HSE->PLL HCLK: 180MHz

プロジェクトの設定

Project - Properties
  C/C++ Build
    Settings
      Configuraion: Release
    Tool Settings
      MCU GCC Compiler
        Optimization
          Optimizaion level: Optimize for speed (-Ofast)

F767ZIの設定


Nucleo-F767ZIはデフォルトでETHが有効化されていて実行時にエラーが発生するので、MXで無効化します。

MXの設定

Pinout & Configuration
  System Core
    GPIO
      PB10
        Maximum output speed: Very High
        User Label: CK_CPLT
      PB11
        Maximum output speed: Very High
        User Label: CK_HALF_CPLT
  Connectivity
    ETH
      Mode: Disable
  Multimedia
    I2S2
   Mode: Half-Duplex Master
      Parameter Settings
        Data and Frame Format: 32 Bits Data on 32 Bits Frame
        Selected Audio Frequency: 192KHz
        Real Audio Frequency: 187.5Khz
      DMA Settings
        SPI2_TX
          Mode: Circular
          Data Width: Half Word / Half Word

Clock Configuration
     HSE->PLL HCLK: 216MHz

プロジェクトの設定

Project - Properties
  C/C++ Build
    Settings
      Configuraion: Release
    Tool Settings
      MCU GCC Compiler
        Optimization
          Optimizaion level: Optimize for speed (-Ofast)

G431GBの設定


Nucleo-G431KBはPF0、PF1を有効にするためにボード上のはんだジャンパSB8、SB11をブリッジしました。



MXの設定

Pinout & Configuration
  System Core
    GPIO
      PA12
        Maximum output speed: Very High
        User Label: CK_HALF_CPLT
      PB0
        Maximum output speed: Very High
        User Label: CK_CPLT
  Multimedia
    I2S2
   Mode: Half-Duplex Master
      Parameter Settings
        Data and Frame Format: 32 Bits Data on 32 Bits Frame
        Selected Audio Frequency: 192KHz
        Real Audio Frequency: 189.732dKhz
      DMA Settings
        SPI2_TX
          Mode: Circular
          Data Width: Half Word / Half Word

Clock Configuration
     HSI->PLL HCLK: 170MHz

プロジェクトの設定

Project - Properties
  C/C++ Build
    Settings
      Configuraion: Release
    Tool Settings
      MCU GCC Compiler
        Optimization
          Optimizaion level: Optimize for speed (-Ofast)

各Nucleoボードのデフォルトの設定で、I2Sを初期化すると割り当てられるピンは以下の通りです。

Board I2S2_CK I2S2_WS I2S2_SD
F446RE PB10 PB12 PC1
F767ZI PD3 PB12 PC3
G431KB PF1 PF0 PA11

実行結果


LchのDMA転送が完了したときに発生する割り込みHAL_I2S_TxHalfCpltCallback()から、RchのI2S通信が開始するWSがHighになる時点までの時間を計測しました。

WSがHighになってRchの通信が開始してからも、しばらくはLchのバッファをいじれるかもしれませんが、よくわかっていないので考慮にいれていません。少なくともRchのCPLTが呼び出されて、MPU本体に制御が戻る前にLchの仕事を完了させないといけません。

F446RE

F767ZI

G431KB


Board 猶予時間(us)
F446RE 1.59
F767ZI 1.1
G431KB 1.89


このテストもF767ZIの成績が芳しくありません。

おおよその目安として、192kHz/2chでI2S出力する場合、リアルタイムに算術関数を1回実行するが精一杯というところでしょうか。

0 件のコメント:

コメントを投稿