SOLIDインテリジェントローダー
SOLIDインテリジェントローダー概要
ローダーの機能
SOLID-OS環境やベアメタル環境でアプリケーションをロードし実行する機能(※)
リンカーの機能を有し、単純にメモリに展開して実行するだけではなく、ロード時に未解決シンボルのアドレス解決が可能
メインアプリが、被ロードアプリを複数ロードすることが可能
被ロードアプリ単体で、コーディング、ビルド、ソースコードデバッグ実行が可能(メインアプリはバイナリのみでも可)
PICコードによるDLL形式と、ビルド時にロードアドレスを決めるSOLID独自形式の2種類に対応
メモリの利用効率が高い(MMUの機能を最大限に活用)
アンロードも可能
ローダーを使うメリット
アプリケーションごとの分割開発が可能
開発を担当する以外のアプリケーションは、ソースやオブジェクトなどが無い実行バイナリのみもでも開発可
MMU対応なので、余裕をもったアドレス割り当てをしても効率的にメモリを利用可能
仕向け地向けにカスタマイズした複数バージョンの製品の開発やソース管理が簡単になる
2種類のローダブルアプリケーション
- SOLID独自形式ローダブルアプリケーション
ビルド時にロードアドレスを指定する
ロード後はスタティックリンクと同じ実行効率で実行されます
ヒープをメインアプリと共有するか否かが選択可能
「libc の初期化」、「C++ 静的クラスの生成」、「(独自ヒープの場合の)ヒープの確保」は、ローダブルアプリケーションを最初に呼び出す際にプロジェクト内にある
_slo_start()
@crtslo.c
にて行うIMPORT/EXPORT するシンボルはユーザが決め、SOLIDローダ固有の形式でソースファイル外に記述
EXPORTするシンボルは、メインアプリやほかのSOLID独自形式、DLL形式と重複できません。
- DLL形式
PICでビルド、ロード時にロードアドレスが確定する(PICコードの実行効率=スタティックリンクよりやや低い)
シンボル参照の実行効率は、SOLID独自形式に比べて少し劣ります。
ヒープは、必ずメインアプリと共有する
「libc の初期化」、「C++ 静的クラスの生成」は、アプリケーションのロード時にローダーが自動的に行う
アプリケーション内での未解決シンボルは全てIMPORT対象。EXPORTシンボルは、ソースコード内に “DLL_EXPORT ” で指定
公開するシンボルは、メインアプリやほかのSOLID独自形式、DLL形式と重複することができます。
ローダーを使った開発の流れ
ローダーを使った分散開発
開発協力会社がアプリケーション単位で、プログラムを開発
担当部分以外のソースコード無しで開発を実施
例えばアプリ1を変更した場合にも、本体アプリやアプリ2の再ビルドは必須ではない。 つまり、「ソースコードの相互非開示」や「独立したプロセスでの開発」が可能な分散開発環境が実現できます。
各分散拠点の担当作業
- 開発会社 (or メイン部分開発チーム)
開発用ハードウェアの開発/準備
メインアプリの開発
ローダブルアプリケーション開発環境の提供
開発用ハードウェア
SOLIDツール一式
ローダブルアプリケーション用SOLID-IDEソリューション一式(※)
ビルド済みメインアプリのバイナリ
- 協力会社 (or ローダブルアプリケーション開発チーム)
ローダブルアプリケーションの開発
提供された環境での動作確認
ローダブルアプリケーション開発環境の準備
開発会社が準備すること(1)「最初にすること」
協力会社向けにSOLIDツール一式とライセンスを提供
Note
SOLID-IDEを使ってビルド、デバッグするためには SOLID のライセンスが必要です。
開発会社が準備すること(2) 「コーディング&ビルドのための準備」
メモリーマップの決定(各ローダブルアプリケーションのロードアドレス、DLLのロードアドレス領域)
メインアプリソリューション=ローダブルアプリケーションをロードするプログラムを用意(※ファイルシステムを含む)
ウィザードで ローダブルアプリケーション + SOLID-OS もしくは DLL + SOLID-OS を選択して、ローダブルアプリケーションのソリューションを生成
メモリーマップ (SOLID独自形式の場合)
ビルド時にロードアドレスを決める必要があります
小さくない領域で、空いている仮想アドレスの領域(例 : 0x00000000~0x3FFFFFFF = 1GB)の適当なアドレス(例えば0x10000番地)をロードアドレスとします。
複数ロードする場合は、重複しないよう注意
メモリーマップ (DLL形式の場合)
SOLID-OSがロード時にメモリを割り付けて、アドレスが確定しますが、割り付ける領域を指定しておく (
DLLAREA
)複数ロードする場合もこの領域から適切に割り付けられる(不足したら
SOLID_LDR_LoadDLL
がエラーになるので、メモリマップエディタで、この領域のサイズ増やしてください)
ファイルシステムについて
SOLIDで用意している評価用サンプルファイルシステム
- メモリファイルシステム
メモリの一部をファイルの内容としてアクセスする、 簡易的なファイルシステム。
ファイルパスは
\ROM\<アドレス>,<サイズ>
で指定します
- VLINKファイルシステム
JTAGデバッガ接続時のみ有効で、デバッガが接続されているPCのファイルシステムをVLINKを経由して ターゲットからアクセスすることが可能。
ファイルパスは
\VLINK\<PC上のファイルパス>
で指定します
- FAT(12/16)ファイルシステム(単独では動作しません)
ストレージデバイスのドライバは各評価ボード用のものを準備してください
ファイルパスは
\FATFS\<パス名>
で指定しますフォーマットの機能は持っていないので、FAT(12/16)でフォーマット済みのデバイスを用意してください
ユーザがファイルシステムを用意する場合、SOLIDとの繋ぎこみは2種類あります
ファイルシステムを SOLID-OS の API 経由で使えるようにする場合
SOLIDのFATFS(FAT16/12)経由で使用する場合(ストレージデバイスのドライバの繋ぎこみ)
A. の場合 ドライバの登録 を参照してファイルシステムをSOLID-OSに登録してください
B. の場合 FATファイルシステムドライバの登録 を参照してストレージのドライバをSOLID-OSに登録してください
ローディングを行う処理 (SOLID独自形式の場合)
/* モジュールロード (ロード時に名前を付けます 例では “APP1”) */
ercd = SOLID_LDR_LoadFile ("APP1", filename);
if (ercd == SOLID_ERR_OK) {
/* ロードした DLL が実行可能かチェック */
ret = SOLID_LDR_CanExec("APP1", &addr);
if (ret > 0) {
void (*pFunc)() = (void (*)())addr; /* アドレスを関数ポインタに型変換 */
pFunc(); /* ロードしたコードを実行 */
}
}
ローディングを行う処理 (DLL形式の場合)
/* モジュールロード (ロード時に名前を付けます 例では “DLL1”), 領域はmemory_map.smm の DLLAREA */
ercd = SOLID_LDR_LoadDLL ("DLL1", filename, SOLID_LDR_ADDR_DLLAREA);
if (ercd == SOLID_ERR_OK) {
/* ロードした DLL が実行可能かチェック */
ret = SOLID_LDR_CanExec("DLL1", &addr);
if (ret > 0) {
/* 呼び出したい関数のアドレスをDLL名とシンボル名から検索 (例では DllFunc) */
ret = SOLID_LDR_GetAddr("DLL1", "DllFunc", &addr);
if (ret == SOLID_ERR_OK) {
void (*pFunc)() = (void (*)())addr; /* アドレスを関数ポインタに型変換 */
pFunc(); /* ロードしたコードを実行 */
} else {
SOLID_LOG_printf("DllFunc() NOT found\n");
}
}
}
開発会社が準備すること(3) 「デバッグするための準備」
ソリューションのデバッグ設定変更
メインアプリをビルドしバイナリを適当なフォルダに格納
ローダブルアプリケーション用の PARTNERデバッガ設定ファイル作成(※)
Note
基本的にメインアプリのデバッグ設定と同じでよく、 init.mcr
は「メインアプリのバイナリをロードして実行する」よう書き換えてください。
ローダブルアプリケーションのデバッグ設定 (SOLID独自形式の場合)
赤枠内のみデフォルトから変更
CFGディレクトリ、INIT.MCRディレクトリ は、フォルダ構成に合わせる
それ以外は、例に合わせてください
エントリポイント は
__slo_start
(先頭はアンダースコア2つ)
ローダブルアプリケーションのデバッグ設定 (DLL形式の場合)
赤枠内のみデフォルトから変更
CFGディレクトリ、INIT.MCRディレクトリ は、フォルダ構成に合わせる
エントリポイント は、最初に呼び出す関数シンボルに設定します
それ以外は、例に合わせてください
フォルダ構成例 (SOLID独自形式の場合)
フォルダ構成の例です - 以下のフォルダやファイルは、ウィザードが自動生成します
loadable-app/
solid-os/
loadable-app.props
loadable-app.ptsln
loadable-app/ : ローダブルアプリケーションフォルダ
main-app/ : メインアプリバイナリフォルダ
solid_boot.bin - メインアプリバイナリ本体
partner/ : デバッグ設定フォルダ
init.mcr - デバッグマクロ
jetarm.cfg - デバッガ設定ファイル
jetarm.jpx - デバッガ設定ファイル
solid-os/ : RTOS ヘッダファイル
loadable-app.props : アプリプロパティ
loadable-app.ptsln : アプリソリューション
フォルダ構成例 (DLL形式の場合)
フォルダ構成の例です - 以下のフォルダやファイルは、ウィザードが自動生成します
dll-app/
solid-os/
dll-app.props
dll-app.ptsln
dll-app/ : DLLアプリフォルダ
main-app/ : メインアプリバイナリフォルダ
solid_boot.bin - メインアプリバイナリ本体
partner/ : デバッグ設定フォルダ
init.mcr - デバッグマクロ
jetarm.cfg - デバッガ設定ファイル
jetarm.jpx - デバッガ設定ファイル
solid-os/ : RTOS ヘッダファイル
dll-app.props : DLLプロパティ
dll-app.ptsln : DLLソリューション
init.mcr 記述例1 (SOLID独自形式, DLL形式)
ローダブルアプリケーションを VLINK やストレージデバイスからロードする場合の例
以下のコマンドを記述します
メインアプリを所定のアドレスにロード
_pc
にエントリアドレス指定
kanji utf8
rd ${SolutionDir}\main-app\solid_boot.out,0x20800000
_pc=0x20800000
Note
メインアプリのロードアドレス、_pc
(プログラムカウンタ) に設定するアドレスは物理アドレスです
Note
HWの初期化(DDR初期化、CPUリセット解除等)で必要な処理があれば追加します
init.mcr 記述例2 (SOLID独自形式, DLL形式)
メモリファイルシステムからローダブルアプリケーションをロードする例
以下のコマンドを記述します
メインアプリを所定のアドレスにロード
ローダブルアプリケーションのバイナリ (
.slo
/.so
) を所定メモリにロード_pc
にエントリアドレス指定
kanji utf8
rd ${SolutionDir}\main-app\solid_boot.out,0x20800000
_pc=0x20800000
Note
メインアプリのロードアドレス、_pc
に設定するアドレスは物理アドレスです
Note
ローダブルアプリケーションをロードしておくメモリのアドレス指定は物理アドレス。 ロード時のファイル名は仮想アドレスです。期待する仮想アドレスになるよう、メモリマップエディタで指定するか、ロードまでにマップして下さい。
Note
HWの初期化(DDR初期化、CPUリセット解除等)で必要な処理があれば追加します
開発会社が準備すること(4) 「協力会社に提供する前の動作確認」
メインアプリのソリューションでひな型だけの「ローダブルアプリケーション」がロード&実行されることを確認(必要ならデバッグ)
ローダブルアプリケーションのソリューションで、ローダブルアプリケーションの実行とデバッグが可能なことを確認
ローダブルアプリケーションソリューション単独でのデバッグ実行 (SOLID独自形式の場合)
ローダブルアプリケーションのソリューションファイル(フォルダ例では、
loadable-app.ptsln
) をダブルクリックで SOLID-IDE を起動ビルド
ローダブルアプリケーションのどこかにブレークポイントを設定
デバッグ実行
ローダブルアプリケーションソリューションでの デバッグ実行 (DLL形式の場合)
DLLのソリューションファイル(フォルダ例では、
dll-app.ptsln
) をダブルクリックで SOLID-IDE を起動ビルド
ローダブルアプリケーションのどこかにブレークポイントを設定
デバッグ実行
開発会社が準備すること(5) 「シンボルのEXPORT/IMPORT」
メインアプリがEXPORTするシンボルの登録
メインアプリが EXPORTするシンボルは
SOLID_LDR_RegisterSymbol
API で、ローダーに登録しないとローダブルアプリケーションではIMPORTできませんSOLID-OS に関する EXPORTシンボル(TOPPERSのシステムコール等)は、SOLID-OS起動時に自動的に登録するので、ユーザ開発部分のコードからローダブルアプリケーションに開示するシンボルを登録してください(ロードする前に)
シンボルのEXPORT/IMPORTのルール
メインアプリ SOLID独自形式ローダブルアプリケーション DLL形式ローダブルアプリケーション EXPORTシンボルAPP_EXP.txt
にシンボル名をリストする ソース中のシンボル定義部分にDLL_EXPORT
の属性をつける EXPORTシンボルの参照処理/IMPORT対象APP_IMP.txt
にシンボル名をリストする(SOLID-OSのシンボルは記述不要) 全ての未解決シンボルがIMPORTシンボル扱い
SOLID独自形式ローダブルアプリケーションのEXPORTシンボルは、メインアプリや他のSOLID独自形式ローダブルアプリケーションのEXPORTシンボルと同一であってはならない(ローダブルアプリケーション内部でしか参照しないシンボルは、その限りではない)
DLL形式ローダブルアプリケーションのEXPORTシンボルは、他のDLL形式ローダブルアプリケーションの EXPORTシンボルと同じ名前でも構わない。
複数のDLLが同じシンボルをEXPORTしていた場合、IMPORT処理結果はDLLのロード順序に依存します。明示的にDLLを確定したい場合は
SOLID_LDR_GetDllAddr
でアドレスを検索して使用する。
SOLID独自形式/DLL形式のソリューションひな形作成
ここでは、SOLID-IDEを使ってローダブルアプリケーションのソリューションひな形を生成する方法を説明します。
SOLID-OS 環境での、SOLID独自形式、DLL形式とは、SOLID-OS のローダーがロードし実行できる実行可能ファイルです。 これらの機能を使用することで、機能毎の分割開発や環境毎のカスタマイズが容易になります。
ローダブルアプリケーションのソリューション生成前に知っておくこと
生成可能なローダブルアプリケーション
2つの形式のローダブルアプリケーションのソリューションを生成可能
SOLID独自形式 (拡張子
.slo
)DLL形式 (拡張子
.so
)
2つの形式それぞれについて、以下の2種類(計4種類)を生成可能
メインアプリとローダブルアプリケーション、両方のソースコードがある環境用のソリューション(= SOLID-OSのソースツリー内に新規で追加したい場合(同一チーム向け) )
開発担当するローダブルアプリケーション以外のソースが無い状態で開発する環境用のソリューション(= SOLID-OSのソースツリーが無くてもビルド可能なもの(分散開発向け) )
SOLID-OSコンフィグレーションの整合
SOLID-OSのコンフィグレーション関して、メインアプリとローダブルアプリケーションで食い違いが生じると正常に動作しない可能性があります
不整合を防ぐため、ローダブルアプリケーション生成時には、メインアプリのソリューションプロパティファイル( SOLID-OSのコンフィグレーション項目等が記述された)を指定する必要があります
Note
ローダブルアプリケーションソリューション生成後に、メインアプリのソリューションプロパティを変更した場合は、ファイルの編集等で整合を取って下さい
ローダブルアプリケーションが使用するメモリ
アプリをロードするメモリ
SOLID独自形式
物理メモリ:
memory_map.smm
の 領域名RAM
から切り出す仮想メモリ: ビルド時に決めたアドレス (
config.h
中SLO_APP_PLACEMENT_ADDR
)
DLL形式
物理メモリ:
memory_map.smm
の 領域名RAM
から切り出す仮想メモリ:
memory_map.smm
の 領域名DLLAREA
中にマップする
ヒープ領域
SOLID独自形式 (2つの方法が選べます)
メインアプリのヒープ領域を共用する方法 (
config.h
中のSLO_USE_SHARED_HEAP
=1
)物理メモリ:
memory_map.smm
の 領域名RAM
から切り出す仮想メモリ:
memory_map.smm
の領域名SOLID_HEAP
中にマップする
独立したヒープ領域を使用する方法 (
config.h
中のSLO_USE_SHARED_HEAP
=0
,SLO_HEAP_SIZE
でサイズを指定)ビルド時に確保されるので、前ページの「ロードするメモリ」と同じ物理メモリ/仮想メモリが使われます
DLL形式
メインアプリのヒープ領域を共用するので独自方式のヒープ共用の場合と同じです
スタック
どちらの形式も、ローダブルアプリケーションの関数呼び出し元のコンテキストのスタックを使います。
SOLID独自形式/DLL形式ローダブルアプリケーションプロジェクトの作成
ウィザードの開始
SOLID-IDE を起動し、スタートページ中の 新規プロジェクト... をクリックするか、メニューバーから を選択します。
プロジェクト テンプレート ウィザード を選択し、 OK をクリックします。
プロジェクト名を変更したい場合は、ウィンドウ下部にある 名前 の項目を変更してください。
ウィザードの設定
ウィザードの選択 ダイアログの 設定 をクリックします。
検索パス ダイアログが開くので、 SOLID-OSディレクトリ\template
フォルダ以下の
lapp
dll
の2つのディレクトリを指定し OK をクリックします。
SOLID独自形式プロジェクトの作成
SOLID-OSのソースツリー内に新規で追加したい場合(同一チーム向け)
ウィザードの選択 ダイアログに表示されている ローダブルアプリケーション を選択し、次へ をクリックします。
Note
このウィザードで生成されたプロジェクトには、SOLID-OSのヘッダーは含まれていないので、ビルド環境にSOLID-OSのソースが必要です。
生成されたソリューションのディレクトリ移動を行った場合、 ソリューション名.props
ファイル内の SOLIDRootDir
の値を修正してソリューションを開きなおす必要があります。
Note
ウィザードの選択ダイアログに何も表示されていない場合は、ウィザードの設定 を行ってください。
生成されるプロジェクトの構成を設定します。
- プラットフォーム
プラットフォームを選択します。
- AArch64:
64bit SOLID-OS
- ARMv7-A:
32bit SOLID-OS
- 配置アドレス
ローダブルアプリケーションを配置する仮想アドレスを指定します。
- ソリューションプロパティファイル
設定を引き継ぐメインアプリの
.props
ファイルを指定します。
SOLID-OSのソースツリーが無くてもビルド可能なもの(分散開発向け)
ウィザードの選択 ダイアログに表示されている ローダブルアプリケーション + SOLID-OS を選択し、次へ をクリックします。
Note
このウィザードで生成されたプロジェクトには、SOLID-OSのヘッダーが含まれているので、ビルド環境にSOLID-OSのソースは不要です。
Note
ウィザードの選択ダイアログに何も表示されていない場合は、ウィザードの設定 を行ってください。
生成されるプロジェクトの構成を設定します。
- プラットフォーム
プラットフォームを選択します。
- AArch64:
64bit SOLID-OS
- ARMv7-A:
32bit SOLID-OS
- 配置アドレス
- ローダブルアプリケーションを配置する仮想アドレスを指定します。
config.h
ファイルから配置アドレス等を変更することができます。
- ソリューションプロパティファイル
設定を引き継ぐメインアプリの
.props
ファイルを指定します。
シンボルのエクスポート
ローダブルアプリケーションでは、APP_EXP.txt
ファイルにエクスポートするシンボルを記述することで、シンボルをエクスポートすることができます。
int g_Int;
void func1(void) {}
g_Int
func1
シンボルのインポート
ローダブルアプリケーションでは、APP_IMP.txt
ファイルにインポートするシンボルを記述することで、シンボルをインポートすることができます。
func2
ソリューション生成後にロードアドレス等を編集する方法
SOLID独自形式のローダブルアプリはビルド時に配置する仮想アドレスが確定している必要があります。また、ローダブルアプリが使用する heap については、メインのSOLID-OSとの共有の有無を選択できます。
ソリューションエクスプローラの
config.h
をダブルクリック
設定内容を記述した、
config.h
が表示されます
必要に応じて、各マクロの定義を編集します
heapの設定
SLO_USE_SHARED_HEAP
: SOLID-OSとローダブルアプリケーションがheapを共有するかどうか0
: 共有しない1
: 共有するSLO_HEAP_SIZE
: 共有しない場合のheapサイズ
ロードアドレス
SLO_APP_PLACEMENT_ADDR
アプリのロードアドレス
DLL形式プロジェクトの作成
SOLID-OSのソースツリー内に新規で追加したい場合(同一チーム向け)
ウィザードの選択 ダイアログに表示されている DLL を選択し、次へ をクリックします。
Note
このウィザードで生成されたプロジェクトには、SOLID-OSのヘッダーは含まれていないので、ビルド環境にSOLID-OSのソースが必要です。
生成されたソリューションのディレクトリ移動を行った場合、 ソリューション名.props
ファイル内の SOLIDRootDir
の値を修正してソリューションを開きなおす必要があります。
Note
ウィザードの選択ダイアログに何も表示されていない場合は、ウィザードの設定 を行ってください。
生成されるプロジェクトの構成を設定します。
- プラットフォーム
プラットフォームを選択します。
- AArch64:
64bit SOLID-OS
- ARMv7-A:
32bit SOLID-OS
- ソリューションプロパティファイル
設定を引き継ぐメインアプリの
.props
ファイルを指定します。
設定後 OK をクリックします。
SOLID-OSのソースツリーが無くてもビルド可能なもの(分散開発向け)
ウィザードの選択 ダイアログに表示されている DLL + SOLID-OS を選択し、次へ をクリックします。
Note
このウィザードで生成されたプロジェクトには、SOLID-OSのヘッダーが含まれているので、ビルド環境にSOLID-OSのソースは不要です。
Note
ウィザードの選択ダイアログに何も表示されていない場合は、ウィザードの設定 を行ってください。
生成されるプロジェクトの構成を設定します。
- プラットフォーム
プラットフォームを選択します。
- AArch64:
64bit SOLID-OS
- ARMv7-A:
32bit SOLID-OS
- ソリューションプロパティファイル
設定を引き継ぐメインアプリの
.props
ファイルを指定します。
設定後 OK をクリックします。
シンボルのエクスポート
DLL形式では、DLL_EXPORT
マクロを使用することで、シンボルをエクスポートすることができます。
DLL_EXPORT void DllFunc(void)
{
SOLID_LOG_printf("DllFunc.\n");
}
シンボルのインポート
DLL形式では、未解決シンボルはすべてインポート対象になります。
生成後にエントリ名を変更する方法
SOLID独自形式ローダブルアプリケーションの場合
ウィザードで生成した場合のローダブルアプリケーションのエントリの関数名は、
app_main
です変更する場合は、ソリューション中の以下の二カ所を変更してください
_slo_start()
@crtslo.c
中でapp_main()
を呼出している部分のシンボル名
app.h
中のapp_main()
の型定義をしている部分
DLL形式の場合
ウィザードで生成した場合のローダブルアプリケーションのエントリの関数名は、
DllFunc
です変更する場合は以下の個所を変更してください
ソリューション中で、
SOLID_LDR_GetDllAddr
を使ってDllFunc()
のアドレスを検索している個所全部