M5StickC(ESP32)のCPU関連関数を調べた

※本ブログは現時点での情報です、最新情報はM5StickC非公式日本語リファレンスを参照してください。

esp32-hal-cpu.hに定義されている関数を調べました。

概要

M5StickCは周波数40MHzのクリスタルを搭載しており、CPUは10から240MHzで動作することが可能です。

SPIやフラッシュなどのペリフェラルは80MHzが最大で、CPU周波数が下がるとともに下がります。

PWMのようにペリフェラル周波数に依存して制御が必要な機能についてはコールバック関数を設定し、周波数変更した場合の処理を設定することが可能です。

CPU周波数(MHz)ペリフェラル周波数(Hz)クリスタル周波数(MHz)
2408000000040
1608000000040
808000000040
404000000040
202000000040
101000000040

CPU周波数設定

標準は240MHzで動いているので、下げることで省電力動作が可能になります。

ただし通信をする場合にはCPU速度を落とすより、Wi-FiなどをONにしている時間を短くするほうが省電力になることがあるので、消費電力を実測しながら調整しましょう。

サンプルスケッチ

volatile int g_ev_cnt = 0;
volatile apb_change_ev_t b_ev_type;
volatile apb_change_ev_t a_ev_type;
volatile uint32_t b_old_apb;
volatile uint32_t b_new_apb;
volatile uint32_t a_old_apb;
volatile uint32_t a_new_apb;

static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb) {
  g_ev_cnt++;
  if ( ev_type == APB_BEFORE_CHANGE ) {
    b_ev_type = ev_type;
    b_old_apb = old_apb;
    b_new_apb = new_apb;
  } else if ( APB_AFTER_CHANGE ) {
    a_ev_type = ev_type;
    a_old_apb = old_apb;
    a_new_apb = new_apb;
  }
}

uint32_t iarg = 1;

void setup() {
  Serial.begin(115200);

  Serial.printf( "getXtalFrequencyMhz() : %d\n", getXtalFrequencyMhz() );
  Serial.printf( "getCpuFrequencyMhz() : %d\n", getCpuFrequencyMhz() );
  Serial.printf( "getApbFrequency() : %d\n", getApbFrequency() );

  Serial.printf( "\n" );

  Serial.printf( "addApbChangeCallback() : %d\n", addApbChangeCallback((void*)iarg, _on_apb_change) );

  Serial.printf( "g_ev_cnt : %d, b_ev_type : %d, b_old_apb : %d, b_new_apb : %d\n", g_ev_cnt, b_ev_type, b_old_apb, b_new_apb );
  Serial.printf( "g_ev_cnt : %d, a_ev_type : %d, a_old_apb : %d, a_new_apb : %d\n", g_ev_cnt, a_ev_type, a_old_apb, a_new_apb );

  Serial.printf( "\n" );

  for ( int i = 0 ; i <= 500 ; i++ ) {
    int ret = setCpuFrequencyMhz(i);
    if ( ret ) {
      Serial.printf( "setCpuFrequencyMhz(%d) : %d\n", i, ret );
      Serial.printf( "getCpuFrequencyMhz() : %d\n", getCpuFrequencyMhz() );
      Serial.printf( "getApbFrequency() : %d\n", getApbFrequency() );
      Serial.printf( "getXtalFrequencyMhz() : %d\n", getXtalFrequencyMhz() );
      Serial.printf( "g_ev_cnt : %d, b_ev_type : %d, b_old_apb : %d, b_new_apb : %d\n", g_ev_cnt, b_ev_type, b_old_apb, b_new_apb );
      Serial.printf( "g_ev_cnt : %d, a_ev_type : %d, a_old_apb : %d, a_new_apb : %d\n", g_ev_cnt, a_ev_type, a_old_apb, a_new_apb );
      Serial.printf( "\n" );
    }
  }

  Serial.printf( "removeApbChangeCallback() : %d\n", removeApbChangeCallback((void*)iarg, _on_apb_change) );
}

void loop() {
}

まとめ

リファレンスでは全部の関数を調べてみましたが、普段使うのはsetCpuFrequencyMhz()だけだと思います。

コールバックもPWMの内部で使っていますが、普通の人は使わないかな。。。

コメントする

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)