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 FileSystem用ドライバの登録 を参照してストレージのドライバを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シンボル SOLID_LDR_RegisterSymbol() で登録 APP_EXP.txt にシンボル名をリストする ソース中のシンボル定義部分に“DLL_EXPORT” の属性をつける EXPORTシンボルの参照処理/IMPORT対象 SOLID_LDR_GetAddr() orSOLID_LDR_GetDllAddr() で検索 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() のアドレスを検索している個所全部