TOPPERS/ASP3をビルドして動かしてみる

##はじめに
TOPPERSプロジェクトのトピックスに2019年12月25日に**TOPPERS/ASP3**カーネルの Nucleo F401RE 向け簡易パッケージを公開したことがアナウンスされていました。
以前に「<a href="https://qiita.com/Yukiya_Ishioka/items/9ecbe080939600c323c6">TOPPERS/ASPをビルドして動かしてみる</A>（ https://qiita.com/Yukiya_Ishioka/items/9ecbe080939600c323c6 ）」で**TOPPERS/ASP**という**RTOS**をビルドしてマイコンボードで動作させる記事を書きましたが、今回はTOPPERS第3世代カーネルである**TOPPERS/ASP3**を前回と同様に**NUCLEO-F401RE**というマイコンボードで動くよう、Linux環境でソースからビルドするための方法をまとめました。
なお、Linux環境の大部分は前回の環境を利用できるので、そこからの変更点のみを記します。

##TOPPERS/ASP3とは
**TOPPERS/ASP3**は、TOPPERSプロジェクト（TOPPERS：**T**oyohashi **OP**en **P**latform for **E**mbedded **R**eal-time **S**ystems）が管理、公開しているITRON仕様のRTOSの１つです。
TOPPERS/ASPカーネルを拡張・改良したもので、TOPPERS第3世代カーネルになります。
**TOPPERS/ASP**からの主な変更点は以下になります。

・追加した機能
　ティックレスの高分解能時間管理
　外部時刻同期機能
　タスク終了要求機能
・削除した機能
　タスク例外処理機能
　メールボックス機能

私見では「ティックレスの高分解能時間管理」が大きな特徴で、不必要なカーネル動作を減らして、細かな時間制御が可能になります。
省電力機能の実装や、高速なマイコンを使った時のリアルタイム性の向上が望めそうです。
**TOPPERS**や**TOPPERSプロジェクト**、**TOPPERS/ASP3**の詳細は以下のページを参照してください。

・TOPPERSのページ
　https://www.toppers.jp/
・TOPPERSプロジェクトのページ
　https://www.toppers.jp/project.html
・TOPPERS/ASP3カーネルのページ
　https://www.toppers.jp/asp3-kernel.html

##TOPPERS/ASP3を動かすための準備
###１．マイコンボードを用意しよう
今回も、**STMicroelectronics社**（以下、**STマイクロ**）から発売されている**NUCLEO-F401RE**というマイコンボードを使って**TOPPERS/ASP3**を動かします。
https://www.st.com/ja/evaluation-tools/nucleo-f401re.html

**NUCLEO-F401RE**はARM社のCortex-M4コアのマイコンを使ったボードです。組込み機器向けなどの展示会のSTマイクロのブースでアンケートに回答すると無料でもらえたりしますし、以下のページのような電子部品を扱う販売店で購入することもできます。
http://akizukidenshi.com/catalog/g/gM-07723/

###２．ソースファイルをゲットしよう
**TOPPERS/ASP3**のソースファイルは以下のページからゲットできます。
https://www.toppers.jp/asp3-e-download.html#nucleo

TOPPERS/ASP系カーネルは通常、**ターゲット非依存部**と**ターゲット依存部**の２つに分けて提供されますが、今回は**NUCLEO-F401RE**用の**ターゲット非依存部**と**ターゲット依存部**を結合した**簡易パッケージ**が以下のZIPファイルで提供されています。
　https://www.toppers.jp/download.cgi/asp3_nucleo_f401re_gcc-20191220.zip

また、**TOPPERS/ASP3**のビルドには**コンフィギュレータ**や**TECSジェネレータ**が必要ですが、これらも上記の**簡易パッケージ**に含まれています。

###３．ビルド環境を準備しよう（１）
Linux環境で**TOPPERS/ASP3**のビルドを行いますが、今回は以前に**TOPPERS/ASP**のビルドで利用した環境を流用します。
**TOPPERS/ASP**のビルド環境がない方は、以下のページを参考にしてください。

TOPPERS/ASPをビルドして動かしてみる
https://qiita.com/Yukiya_Ishioka/items/9ecbe080939600c323c6

###４．ビルド環境を準備しよう（２）
**TOPPERS/ASP**のビルド環境を使えば**TOPPERS/ASP3**のビルドも容易に行えると思っていましたが、**コンフィギュレータ**や**TECSジェネレータ**の実行に**Ruby**が必要なことが分かりました。
そういえば、以前にも**TOPPERS/ASP3**をビルドしようとしてRubyが必要なことが分かり断念したことを思い出しました。私が使った**ubuntu**には**Ruby**が入っていないのですが、今回はインストールを試みます。
試みるといっても「ubuntu」「Ruby」「インストール」で検索すればすぐに見つかりますが・・・
実施した手順を以下に記します。

１）必要パッケージのインストール
　sudo apt-get install rbenv ruby-build

２）rbenvをbashで使用可能にする
　echo 'eval "$(rbenv init -)"' >> ~/.bash_profile

３）インストール可能なRubyのバージョンを確認
　rbenv install --list
　　※実施しなくても大丈夫

４）バージョンを指定してRubyをインストール
　rbenv install 2.1.0

インストールするRubyのバージョンは**TOPPERS/ASP3**のソース内にある **doc/user.txt** に記されていて「2.0.0」となっていましたが、インストール可能なバージョンになかったので「2.1.0」指定しました。ただし、インストール後にバージョンを確認したら別のバージョンがインストールされていました。結果として**TOPPERS/ASP3**のビルドは完了したので、気にせずに進めて構わないと思います。

```
$ ruby --version
ruby 2.3.1p112 (2016-04-26) [i386-linux-gnu]
```

##TOPPERS/ASPのビルド準備
###１．TOPPERS/ASPカーネルのソースの展開

TOPPERS/ASP3カーネルのソースファイル**asp3_nucleo_f401re_gcc-20191220.zip**を任意のディレクトリに展開します。

```
unzip asp3_nucleo_f401re_gcc-20191220.zip
```

展開すると**asp3_3.5**ディレクトリが生成され、配下は以下のようなディレクトリ構成となります。

```
└ asp3_3.5
    ├── arch
    ├── cfg
    ├── doc
    ├── extension
    ├── include
    ├── kernel
    ├── library
    ├── sample
    ├── syssvc
    ├── target
    │   ├── dummy_gcc
    │   └── nucleo_f401re_gcc
    ├── tecs_kernel
    ├── tecsgen
    ├── test
    └── utils
```

###２．アプリケーションビルド用ディレクトリの作成

**asp3_3.5**ディレクトリの１つ上のディレクトリへ戻り、アプリケーション用ディレクトリとアプリケーションビルド用ディレクトリを作成します。
ここでは**appli**としましたが、任意のディレクトリ名を付けて構いません。

```
cd ..
mdir -p appli/obj
```

```
├─ asp3_3.5
│   ├─arch
│   ：
│
└─ appli     ←アプリケーション用ディレクトリ
     └─ obj  ←アプリケーションビルド用ディレクトリ
```

###３．サンプルアプリケーションのコピー
**TOPPERS/ASP3**内に含まれるサンプルアプリケーションソースコードを**appli**ディレクトリ配下へコピーします。
動作確認だけであればコピーは不要ですが、修正しながら動作をみたり、ユーザプログラムのベースにもなるので、コピーしておきます。

```
cd appli
/bin/cp -a ../asp3_3.5/sample .
```

###４．TOPPERS/ASP3カーネルのコンフィグレーション
次に**appli/obj**ディレクトリへ移動し、カーネルのコンフィグレーションを行います。
configureコマンドのオプションの意味は以下になります。
 -T：ターゲットの選択
 　　今回は**NUCLEO-F401RE**用なので**nucleo_f401re_gcc**を設定

```
cd appli/obj
../../asp3_3.5/configure.rb -T nucleo_f401re_gcc
```

###５．Makefileの修正
カーネルのコンフィグレーションが成功するとappli/obj/Makefileが生成されます。生成されたMakefileの51行目の定義を確認してください。

```
TARGET = nucleo_f401re_gcc
```

ビルドで生成されるコードのファイルにバイナリファイルが含まれるよう435行目に **$(OBJNAME).bin** を追加します。

```
    430 #
    431 #  エラーチェック処理
    432 #
    433 .PHONY: check
    434 check: check.timestamp ;
    435 check.timestamp: cfg2_out.db $(OBJNAME).syms $(OBJNAME).srec $(OBJNAME).bin
                                                                     ~~~~~~~~~~~~~~
    436         $(CFG) --pass 3 $(CFG_KERNEL) -O $(INCLUDES) -T $(TARGET_CHECK_TRB) \
    437                                 --rom-symbol $(OBJNAME).syms --rom-image $(OBJNAME).srec
    438         @echo "configuration check passed"
    439 
```

サンプルアプリケーションプログラムのパス指定を変更するため181行目のAPPLDIRS定義の内容を以下の★印ように修正、追加します。


```
    177 #
    178 #  アプリケーションプログラムに関する定義
    179 #
★  180 APPLNAME = sample1
★  181 #APPLDIRS = $(SRCDIR)/sample
    182 APPLDIRS = ../sample
```


##TOPPERS/ASPのビルド実行
**appli/obj**ディレクトリで makeコマンドを実行してください。
ビルドに成功するとasp.binなどTOPPERS/ASP3の実行に必要なファイルが生成されます。

```
$ ll asp*
-rwxrwxr-x 1 ubuntu ubuntu 510968  1月 13 17:59 asp*
-rwxrwxr-x 1 ubuntu ubuntu  26944  1月 13 17:59 asp.bin*
-rwxrwxr-x 1 ubuntu ubuntu  80892  1月 13 17:59 asp.srec*
-rw-rw-r-- 1 ubuntu ubuntu  10441  1月 13 17:59 asp.syms
```


##マイコンボードで動かす
###１．マイコンに書き込む
NUCLEO-F401REボードをUSB経由でPCと接続します。接続するとPCからはマスストレージとして認識され、エクスプローラーでファイルのコピー操作が可能となります。
次にUbuntu上でビルドにより生成された asp.binファイルをエクスプローラー経由でNUCLEO-F401REボードへコピーします。
コピーが完了するとボードへの書き込みが完了となります。

###２．実行する
STマイクロのドライバをインストールすると、NUCLEO-F401REボードのUSBは仮想COMポートとしても認識されます。
TeraTermなどのシリアル端末ソフトを立ち上げ、NUCLEO-F401REボードのCOMポートを**115200bps**で接続するとTOPPERS/ASPカーネルが出力するログ情報がシリアル端末ソフト上に表示され、NUCLEO-F401REボード上でTOPPERS/ASP3カーネルとサンプルプログラムが動作していることを確認できます。

```
TOPPERS/ASP3 Kernel Release 3.5.0 for NUCLEO(STM32F401RE:ARM Cortex-M4) (Jan 13 2020, 18:20:43)
Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
                            Toyohashi Univ. of Technology, JAPAN
Copyright (C) 2004-2019 by Embedded and Real-Time Systems Laboratory
            Graduate School of Information Science, Nagoya Univ., JAPAN

System logging task is started.
Sample program starts (exinf = 0).
task1 is running (001).   |
task1 is running (002).   |
task1 is running (003).   |
           ：
```

上記の操作で実行した場合、appli/sample/sample1.cがユーザプログラムとしてビルドされ実行しています。sample1.cのコメントには以下のように記述されています。文字を入力すると文字コードにあった動作をログ出力で確認できます。
また、このソースコードを参考に自分で作成したプログラムも動かせます。
イロイロと試してみてください。

```
 *  '1' : 対象タスクをTASK1に切り換える（初期設定）．
 *  '2' : 対象タスクをTASK2に切り換える．
 *  '3' : 対象タスクをTASK3に切り換える．
 *  'a' : 対象タスクをact_tskにより起動する．
 *  'A' : 対象タスクに対する起動要求をcan_actによりキャンセルする．
 *  'e' : 対象タスクにext_tskを呼び出させ，終了させる．
 *  't' : 対象タスクをter_tskにより強制終了する．
 *  '>' : 対象タスクの優先度をHIGH_PRIORITYにする．
 *  '=' : 対象タスクの優先度をMID_PRIORITYにする．
 *  '<' : 対象タスクの優先度をLOW_PRIORITYにする．
 *  'G' : 対象タスクの優先度をget_priで読み出す．
 *  's' : 対象タスクにslp_tskを呼び出させ，起床待ちにさせる．
 *  'S' : 対象タスクにtslp_tsk(10秒)を呼び出させ，起床待ちにさせる．
 *  'w' : 対象タスクをwup_tskにより起床する．
 *  'W' : 対象タスクに対する起床要求をcan_wupによりキャンセルする．
 *  'l' : 対象タスクをrel_waiにより強制的に待ち解除にする．
 *  'u' : 対象タスクをsus_tskにより強制待ち状態にする．
 *  'm' : 対象タスクの強制待ち状態をrsm_tskにより解除する．
 *  'd' : 対象タスクにdly_tsk(10秒)を呼び出させ，時間経過待ちにさせる．
 *  'x' : 対象タスクにras_terにより終了要求する．
 *  'y' : 対象タスクにdis_terを呼び出させ，タスク終了を禁止する．
 *  'Y' : 対象タスクにena_terを呼び出させ，タスク終了を許可する．
 *  'r' : 3つの優先度（HIGH_PRIORITY，MID_PRIORITY，LOW_PRIORITY）のレ
 *        ディキューを回転させる．
 *  'c' : 周期ハンドラを動作開始させる．
 *  'C' : 周期ハンドラを動作停止させる．
 *  'b' : アラームハンドラを5秒後に起動するよう動作開始させる．
 *  'B' : アラームハンドラを動作停止させる．
 *  'z' : 対象タスクにCPU例外を発生させる（ターゲットによっては復帰可能）．
 *  'Z' : 対象タスクにCPUロック状態でCPU例外を発生させる（復帰不可能）．
 *  'V' : 短いループを挟んで，fch_hrtで高分解能タイマを2回読む．
 *  'v' : 発行したシステムコールを表示する（デフォルト）．
 *  'q' : 発行したシステムコールを表示しない．
```

##おまけ
サンプルアプリケーション sample1.c の動作は**TOPPERS/ASP3**も**TOPPERS/ASP**と同じなので、起動時のメッセージ以外で違いは判りません。
ただ、sample1.cやsample1.cfgの中身を見ると時間の指定がマイクロ秒単位になっているので、ASP3カーネルであることが分かります。

``` sample/sample1.c
    188       case 'S':
    189           syslog(LOG_INFO, "#%d#tslp_tsk(10000000)", tskno);
    190           SVC_PERROR(tslp_tsk(10000000));
    191           break;
    192       case 'd':
    193           syslog(LOG_INFO, "#%d#dly_tsk(10000000)", tskno);
    194           SVC_PERROR(dly_tsk(10000000));
    195           break;
```


```sample/sample1.cfg
     14 CRE_CYC(CYCHDR1, { TA_NULL, { TNFY_HANDLER, 0, cyclic_handler }, 2000000, 0 });
```

sample1.cをベースにしてタスクの切り換えや周期ハンドラ、アラームハンドラなどを自身のプログラムへ置き換えて試すことができます。
また、TOPPERS/ASPカーネルも同じボードで動作させることができるので、違いを実機で比較することも可能です。
もしここまで環境構築やビルドなどしたら、いろいろと試されてはいかがでしょうか。

－ 以上 －