過去回でSTM32 NUCLEOボード上のMbed OSの練習実施。RTOSなのでついThread(Mbed OSではTaskでなくThreadと称します)だの同期だのに走ってました。しかしMbed OSはIOドライバも含めた立派なOSなのでIOの練習もいるよな、できればArduinoとの比較付でと思い至りました。
※「モダンOSのお砂場」投稿順Indexはこちら
※Arm社のWeb開発環境(無料)、Arm Keil Studio Cloud 上でArm社のRTOS、Arm Mbed OS6 を使って実験してます。ターゲット機はST Microelectronis製STM32F401RE搭載、NUCLEO-F401REボードです。
Arduino_FreeRTOSとMbed OS6の違い
過去回で、Arduino環境から使える Arduino_FreeRTOSを練習してみたことがありました。Arduino IDEをArduino Uno R4用のオブジェクトが作成できるようにセットアップしてあればヘッダファイルをインクルードするだけで即使える FreeRTOS です。これによりArduino Uno R4上で「マルチタスク」を簡単に実現し、タスク間の通信とか同期とかもバッチリでした。ただし、Arduino_FreeRTOS の場合、入出力やその他のライブラリなどはArduino環境の既存のものを利用です。タスクのスケジューリングなどに関する部分のみをFreeRTOSが担うスタイルでした。よって入出力などはArduinoと以下同文。ライブラリによってはRTOSでの使用を前提にしていないものもある筈ですが、その辺は自分で調べて、問題起こらないように使ってね、という感じか。
一方、Mbed OS6は、上記のような「寄生」スタイルではなく、IOライブラリも含めて完結したオペレーティングシステムです。Armコア登載の各社のボード上で実行可能なライブラリを備えてます(各社固有部分は下のレイヤに押し込められて隠蔽されている。)
ついては ArduinoのAPI毎に、Mbed OS6上で相当する機能をどう書いたらよいのか1対1で復習していくことにいたしました。
今回ターゲットのArduino API
今回のAPIは、Lチカに必須のAPIを含む以下の3つのAPIです。
-
- digitalWrite()
- digitalRead()
- pinMode()
デジタル端子にHIGH、LOWを出力あるいは、入力するためのAPIです。Arduino Uno の場合は、D0からD13というデジタル端子および、A0からA5というアナログ(兼用)端子についてこの操作を行うことができます。
入出力の事前準備として、pinMode()を使って、該当端子が出力なのか入力なのか指定しておく必要があります。こんな感じ。
pinMode(ledPin, OUTPUT);
なお入力の場合はINPUTを指定するか、プルアップ抵抗付のINPUT_PULLUP を指定します。
Mbed OS6上での対応オブジェクト
Mbed OS6上では、相当機能を実現するためにいくつかのオブジェクトがあり、複数通りの方法があるのです。上記Arduinoと直接の「対応」関係をとりやすいのは以下の2つでないかと思います。
-
- DigitalIn
- DigitalOut
どちらもクラスであり、特定のピンに対してインスタンスを生成することによって使えるようになります。こんな感じ。
DigitalOut ledRED(ARDUINO_UNO_D2);
上記では ledREDがインスタンス名であり、ARDUINO_UNO_D2がそのインスタンスに結びつけられた物理端子名です。PA_10といったSTM32マイコンの端子名で呼び出すことも可能ですが、Arduinoピンソケット対応信号には上記のような分かり易いお名前が付与されています。
なお、STM32-NUCLEOでの注意点としては、Arduino対応ピンソケットのD0とD1ピンは使わない方が安全です。これら端子はUART2のTX/RXがアサインされているのですが、それらはボード上でデバッグ部のST-LINKのマイコンに接続されています。
Nucleo F401REの端子等については以下のページに分かり易い図が掲載されています。
DigitalOutオブジェクトの方は、端子名を与えてコンストラクタを呼び出した後は、メソッド write()を呼び出すことで書き込み可能です。こんな感じ。
ledRED.write(1);
さらに代入演算子などもオーバライドされているので、ledRED=1; などと直接書き込む表記もOKっす。
一方、DigitalInオブジェクトの方は、コンストラクタに端子だけ与えた場合、mode()メソッドで端子モードの設定をする必要があるかもしれません。コンストラクタの引数にモードも与えてしまえば、一発で済みます。こんな感じ。
DigitalIn button(ARDUINO_UNO_D3, PullNone);
DigitalInなので、入力オブジェクトだということは判明しており、モードで設定するのは、
-
- PullUp
- PullDown
- PullNone
- OpenDrain
の各指定です。Arduinoより細かく設定できますな。
なお、どちらのオブジェクトにも is_connected() メソッドがあり、オブジェクトが初期化されているか否か確認できます。また、デストラクタが走るとインスタンスが確保していたメモリが開放されるみたいです。
Arm御本家のドキュメントは以下に。
実機動作確認
前回も使用したソースにちょいと手を入れて動作確認してみました。
Lチカに毛の生えたようなもの?