2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

mruby/c を、Nucleo-F091RC (STM32F091RC) へ移植する

Last updated at Posted at 2024-10-17

しまねソフト研究開発センター(略称 ITOC)にいます、東です。

先日来、STマイクロエレクトロニクス製のマイコンボード、「Nucleo-F401RE」と、開発環境「STM32CubeIDE」を使って、mruby/c の移植などを行ってきました。
ITOCには、他にNucleoシリーズの「Nucleo-F091RC」と、「Nucleo-L476RG」を所有しています。せっかくなので、これらのデバイスにも mruby/c の移植を行い、その手順を公開します。

予定

Nucleo-F091RC

前回までターゲットにしていた機種と比較して、より小規模のMPU搭載機種です。
CPU: Cortex-M0
RAM: 32KB

こちらは、mruby/c のバイトコードを C言語の配列として書き込む方法(この記事 の方法2)をやってみます。
すなわち、mruby/c移植チュートリアル記事 を、機種を Nucleo-F091RC に替えて実施することとなります。

Nucleo-L476RG

こちらは、より大規模のMPU搭載機種です。

CPU: Cortex-M4
RAM: 128KB

この機種では、次回以降に別記事として、バイトコードのみを書き込む方法(この記事 の方法1)を実施する計画です。

準備するもの

STM32マイコン評価ボード Nucleo-F091RC
(https://www.st.com/ja/evaluation-tools/nucleo-f091rc.html)
開発環境 STM32CubeIDE (ver 1.15.1)
(https://www.st.com/ja/development-tools/stm32cubeide.html)

202410-1_Nucleo-F091RC.jpeg

作業手順

STM32CubeIDE 上で、MPUの種類を変更する方法が無いか探したのですが、おそらくメーカーが想定しているGUI操作の範囲内では用意は無さそうです。従って、新規にプロジェクトを作って、チュートリアルの手順を最短で組み入れる方法をとりました。

新規プロジェクトの作成

別記事「mruby/cをSTM32マイコンで動かす Chapter01: 環境構築」 に書いた方法と同様の手順でプロジェクトを作ります。

Board Selector をクリックしてボードセレクタタブに変更し、Commercial Part Number 欄に、"F901" と入力すれば NUCLEO-F091RC が検索されますので、ボードリスト欄で選べばOKです。

202410-1_scan14.39.16.png

プロジェクト名は、任意でかまいません。今回私は、"F091RC_mrubyc" とつけました。

デフォルトデバイスの確認

プロジェクトが作成されましたら、デフォルトでマップされた以下のデバイスを確認します。

  • オンボードLEDのポート番号 (前回F401REでは、PA5)
  • オンボードスイッチのポート番号 (前回F401REでは、PC13)
  • USBシリアルにマップされたUART番号 (前回F401REでは、UART2)

幸いなことに、今回のボード F091RC は、チュートリアルで使ったボード F401RE と同じポート番号、UART番号でした。よって、ポーティングは最小限の手順で行う事ができます。

ソースコードのダウンロードとマージ

「チュートリアル Chapter04: halの仕上げ」あたりのソースコードが一番使いやすいと思うので、こちらをつかいます。

このページから、Code > Download ZIP 等でダウンロードし、展開しておきます。

展開したソースツリーから、以下のディレクトリを今回のプロジェクトのCoreディレクトリへコピーします。

  • Core/mrubyc
  • Core/mrubyc_src

202410-1_scan14.47.56.png

自動生成されたソースコードへ追記

Core/Src/ 以下のファイルを編集し、以下のコードを追記します。

mruby/c の開始指示

Core/Src/main.c
  /* USER CODE BEGIN 2 */
  void start_mrubyc(void);
  start_mrubyc();
  /* USER CODE END 2 */

割り込み処理の追加

Core/Src/stm32f0xx_it.c
  /* USER CODE BEGIN SysTick_IRQn 0 */
  void mrbc_tick(void);
  mrbc_tick();
  /* USER CODE END SysTick_IRQn 0 */

ビルドプロパティーの変更

メニューから、Project > Properties を選び、ダイアログを開きます。

ダイアログ左ペインの C/C++ Build > Settings をクリックします。

右ペインの Configuration: を、All configurations に変更します。

右ペインの Tool Settings タブをクリックし、MCU Settings をクリックします。

Use float with printf from newlib-nano 欄のチェックをつけます。

202410-1_scan14.54.18.png

右ペインの Build Steps タブをクリックします。

Pre-build steps の Command: 欄へ、以下の通り入力します。

cd ..\\Core\\mrubyc; make

202410-1_scan14.55.43.png

CPU Cortex-M0 に対応

Cortex-M0 は、メモリアクセスに32bit アライメントを要求するので、vm_config.h でコメントアウトしてある以下の定義を有効化します。

Core/mrubyc_src/vm_config.h
#define MRBC_REQUIRE_32BIT_ALIGNMENT

もしくは、IDEのビルドプロパティーで定義しても、おそらく問題ないでしょう。

mruby/c プログラムが使うワークメモリの縮小

チュートリアルでは、mruby/c プログラムが使うワークメモリに30KBほど確保するよう記述しました。一方このMPUの内蔵メモリは、トータルで32KBしかないので、このままだとリンクエラーになります。従って、以下のように約半分の16KBに縮小します。

Core/mrubyc/start_mrubyc.c
/* mruby/c プログラムが使うワークメモリの確保 */
#define MRBC_MEMORY_SIZE (1024*16)

これでOKです。

動作確認

ビルドしてターゲットに書き込みます。
TeraTerm 等を使い、ターゲットボードの COM 番号を開いて、"Hello, mruby/c ..." 等と表示されればOKです。

その他の変更点

オンボードLEDのポート番号が違う場合

オンボードLEDの割り当てポートが PA5 ではない場合は、c_led_write 関数を変更します。以下の例は、PB15に割り当てる例です。

Core/mrubyc/start_mruby.c
/*! オンボードLED ON/OFF メソッドの実装
*/
static void c_led_write(mrbc_vm *vm, mrbc_value v[], int argc)
{
  int on_off = GET_INT_ARG(1);
  HAL_GPIO_WritePin( GPIOB, GPIO_PIN_15, on_off );
}

UART 番号が違う場合

UARTが 2番ではない場合は、hal_write 関数を変更します。以下の例は、UART3に割り当てる例です。

Core/mrubyc/start_mruby.c
int hal_write(int fd, const void *buf, int nbytes)
{
  extern UART_HandleTypeDef huart3;
  HAL_UART_Transmit( &huart3, buf, nbytes, HAL_MAX_DELAY );

  return nbytes;
}

mruby/c ソースコードの入れ替え

バージョンアップやバグ対応等で、mruby/c VM のソースコードを更新したい場合の手順を記します。基本的には mrubyc_src ディレクトリの内容を入れ替えるだけです。

  1. Core/mrubyc_src/hal.h ファイル、及び vm_config.h ファイルを任意の場所にバックアップする
  2. Core/mrubyc_src ディレクトリの内容を、最新のmruby/c VM ソースコードの src ディレクトリの内容に全て入れ替える
  3. バックアップした hal.h を mrubyc_src ディレクトリ内へ戻す
  4. バックアップした vm_config.h を最新の vm_config.h と比較し、マージする

おまけ

https://qiita.com/HirohitoHigashi/items/a0acb20ec8b58a21a9d4 と同じ条件にして、ベンチマークを行ってみました。

MPU Core clock(MHz) 最適化 実行時間(ms)
STM32F401RET6  ARM Cortex M4 84 -O2 2303
STM32F091RC ARM Cortex M0 48 -O2 9055

クロックが約1.8倍程度の差に対して、実行時間は約4倍の差がありますので、クロックあたりの性能比較では、約2.2倍の差が観測できました。
ただし、Cortex M0では、32bit align 回避が、このベンチマークにおいてはかなり不利になっていると思われ、コア単体の計算速度は、そこまで差が出ないはずと考えています。

おわりに

次回は、ペリフェラルライブラリとバイトコード書き込み機能を含め、もう一つの機種「Nucleo-L476RG」への移植にトライします。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?