SOLID未分類 OSレスでSOLIDコアサービスを使う(連載24)
(2023/12/4)
[連載24] OSレスでSOLIDコアサービスを使う
今回は今までとは少し変わったアプローチをご紹介します。
最近の記事はおさらいばかりですが、懲りずに、統合開発環境SOLIDの一番の特徴をおさらいすると、
「OS、デバッガ、コンパイラの三位一体」
です。
上記のOSの括りの中には、CPU抽象化レイヤ「SOLID Core Service」という、SOLID独自のレイヤがあります。
過去記事の以下でご紹介しています。
https://note.com/yn_2022/n/nfd36baf8cd11#570cd12d-13a2-489e-8ac5-db1447f164d5
要点を抜粋すると、
SOLIDでは、多種多様なCortex-A CPUに対応できるよう、CPUを抽象化するレイヤ
「SOLID Core Service」を持っています。
TOPPERSカーネルの下位部に位置しています。
良く見てください。
これ、TOPPERSなしでも動くんじゃない?
と、思いませんか?
特にベアメタル信者の。そこの貴方。
筆者はデバイスに近いところのファームウェアに携わって今まで生きてきたので、できればOSを使いたくないなー、なんて思います。
それでもマルチタスク化が必要だったり、便利なミドルウェアがサポートされていたりするのでOSを使うわけですが。。。
話を戻します。
少なからず、OSレスで使いたいニーズはあるわけで。
タスク化は必要ない、とか、
メモリフットプリントをできる限り小さくしたい、とか、
透明性を確保したい、とか。
「SOLID統合開発環境って、TOPPERS使わないといけないんでしょう?」
と思っているそこの貴方。
取り外せるんです。
目標はこうですね。
すなわち、自作関数からSOLIDのCPU抽象化レイヤで提供される様々なAPIを使える。
CPUを抽象化してくれるレイヤなので、CPUを直に操作する面倒な作業から解放されます。
それにCPUが変わっても(CortexAの中で)プログラムも変えなくていいので移植性高いプログラムを書くことができます。
以下手順を実行していきます。
① ソリューションの複製をする(RTOSつきでOK)
② ソリューションからTOPPERSカーネルを削除
③ ソリューションのプロパティシートを変更しIDE再起動
④ 複製元のユーザプログラムを自作関数に置き換える
⑤ スタートアッププロジェクト変更
⑥ ビルドし実機上で動作させる
では、試してみましょう!
評価環境として、Cortex-A9搭載ボード×PARTNER Jet2の組み合わせを使用します。
既存ソリューションを複製します。
提供されているサンプルのうち、今まで使っていた馴染みのサンプルを複製することにします。
①複製する対象のサンプルを起動
ptslnファイルをダブルクリックして起動します。
②ソリューションエクスプローラから、ソリューションを右クリックし、ポップアップメニューから「ソリューションの複製」を選択します。
以下が起動します。
ソリューション名を適当に決め、OKボタンを押すと、複製が完了します。
①TOPPERSカーネルを削除します。
ソリューションエクスプローラから、Kernelプロジェクトを右クリックし、ポップアップメニューから「削除」を選択します。
②BSP内のkernel.h参照部をコメントアウト
複製元ソリューションのBSPではi2c.cとg-sensor.cは、kernel.hをインクルードしているので、削除します。
※BSPにより削除するポイントが異なるかもしれません。
③ユーザフォルダのカーネルコンフィグレーションファイルを削除
複製元のユーザフォルダにはカーネルコンフィグレーションファイルが存在しますので、それらを削除します。
ソリューションエクスプローラのユーザプロジェクトから、kernel_cfg.c, kernel_cfg.hを選択した上で右クリックし、ポップアップメニューから「削除」を選択します。
ソリューションエクスプローラから、ソリューションを右クリックし、ポップアップメニューから「ソリューションプロパティを開く」を選択します。
TOPPERSカーネルを使用しない設定に変更します。
SOLID_USE_TOPPERS_ASP3>1</SOLID_USE_TOPPERS_ASP3> ⇒ 0にする。
※SOLID_USE_TOPPERS_ASP3が存在しない場合はしなくてよい。
<SOLID_CORE_BOOTKERNEL>0</SOLID_CORE_BOOTKERNEL> ⇒0 にする。
※SOLID_CORE_BOOTKERNELが存在しない場合は作成する。
編集終了後、IDEを再起動します。
今回の場合はsample1.cとsample1.hです。
複製元のプログラムをすべて削除し、以下のように変更しました。
[sample1.c]
#include
#include "sample1.h"
void nonos_main(void)
{
SOLID_LOG_printf("nonos_main() is running...\n");
while (1)
{
}
}
[sample1.h]
#ifndef __NONOS_MAIN_H__
#define __NONOS_MAIN_H__
extern void nonos_main(void);
#endif
ここで重要なのは、以下関数が存在することです。
void nonos_main(void)
この名前の関数は、ブートアップ後に最初に飛んでくる関数となります。
今回の場合、この関数に飛んできて、PCのCOMポートに
nonos_main() is running...
と表示がでるはずです。
nonos_main()関数が存在するプロジェクトを、スタートアッププロジェクトとします。
ソリューションエクスプローラから、対象のプロジェクトを右クリックし、ポップアップメニューから「スタートアッププロジェクトに設定」を選択します。
今回の場合、対象はsample1プロジェクトです。
ビルドし、実機上で動作させてみます。
sample1.cにブレークポイントを設定し実行してみましょう。
無事、ブレークしました。
RTOSビュアーを開きっぱなしでしたね。
OSがないので、Error:Not Supportedとなっていますね。
COMポートも見てみましょう。
nonos_main() is running...
が表示されています。
大きく考えて三つメリットがあります。
・便利なAPI群を使える
・デバイスの差異が吸収される
・OSを変更・削除できる
一つ一つ見ていきましょう。
例えば、UART経由のログ出力機能を実装する場合について考えてみましょう。
先程のsample1.cに、以下の行があります。
SOLID_LOG_printf("nonos_main() is running...\n");
この行を書き、solid_log.hをインクルードするだけで、UART経由のログ出力を行うことができます。
このAPIはSOLID Core Serviceとして提供されています。
詳細は以下URLに記載されています。
https://solid.kmckk.com/SOLID/doc/latest/os/cs/log.html#solid-log-printf
このAPIがない場合、UARTのドライバをコールしてWrite/Read関数を実装しないといけないかもしれません。
そういった、ある意味どのデバイスでも共通の処理を実装しないといけないようなものが、API群として提供されています。
どんなAPIがあるかというと、、、
URLを抜粋させていただきます。
抜粋元:
https://solid.kmckk.com/SOLID/doc/latest/os/core-service.html
これらの機能が、SOLID Core Serviceとして提供されています。
OSを搭載する選択をしなくても、これらを使える、という事です。
開発に要する時間が、短縮できますね!
同じCortexAでも、Renesas製RZマイコンであったり、いろいろありますよね。
それぞれのデバイスで、周辺I/O機能や割り込み機能は少しずつ違いますよね。
割り込み番号も違います。
ただし、CortexAなので、割り込みはGIC、タイマはGeneric Timer、と基本的に同じものが搭載されています。
SOLID Core ServiceでAPIとして使う場合、こういった違いはAPI内で吸収されるため、上位ソフトウェアはデバイスの違いをあまり気にする必要はありません。
SOLID Core ServiceはOSと独立して実装されています。
今回は、OSを取り外しましたが、違うOSへ移植することも可能です。
例えば、FreeRTOSとか。
そのOSの下回りとして、SOLID Core Serviceをくっつける、というイメ―ジです。
OSを取り外し、「SOLID Core Service、デバッガ、コンパイラの三位一体」のSOLIDを味わってみました。
今回は、SOLID Core Serviceの機能として、ログ出力APIのみ使ってみましたが、前述のとおりまだまだ沢山の機能があります。
次回も引き続き、OSレスでSOLID Core Serviceを使ってみる予定です。