********************************************************************** セッションS4-c チュートリアル2 テーマ:組み込みLinux開発におけるエンジニアの必要知識 講師:坂上真市(NSK) 日時:2007/08/31 13:30〜15:00 参加人数:30名程度 ********************************************************************** 第1章 組み込みLinux開発における開発の種類 組み込みLinuxにおける開発の種類 ・ブートローダ、カーネルポーティング ・ドライバ開発 ・アプリケーション開発 ブートローダ、カーネルポーティング ・ドライバ開発より前段階で実施する開発 ・短期間開発をもとめられる 1ヶ月以内 ・新規ボードにポーティングする場合のリスク高 ・ポーティングのコツを習得している/いないでは生産性が大きく違う ・少人数(基本は一人)での開発 ドライバ開発 ・制御するハードにより求められる知識が違う ・短期間開発を求められる ・新規ハードに対する開発のリスク高 ・カーネルフレームワークを知らないと開発できない ・少人数での開発 アプリケーション開発 ・設計アプローチはPCアプリ開発と同じ ・PC Linuxをエミュレーション環境としてデバッグできる ・実機上でのデバッグはNFS環境を使用するケースが多い ・PC Linuxとの差分を理解しておく必要がある 第2章 組み込みLinux開発者の必要知識 組み込みLinux開発者のための必要知識 共通知識 ・Linux基礎知識 どこまで基礎というかは微妙 ・C言語知識 ・環境セットアップ知識 NFS、クロスコンパイル環境 ・Linuxカーネル知識 ブートローダ・カーネルポーティング固有必要知識 ・アセンブラ知識 ・ハードウェア知識(CPU、serial,LAN) 特にserialはコンソールメッセージ出力に必須 ・問題切り分け知識(ハード・ソフト) ・ブートローダ・カーネル起動シーケンス知識 ドライバ固有必要知識 ・対象デバイス規格知識(EX:ATA、SCSI) ・ハードウェア仕様書読解知識 すべてが書かれていないケースが多い おまじない ・ドライバ種類によるフレームワークの知識 2.6以降ドライバの抽象化が進んでいる ・ドライバ開発者常識知識 例:ドライバの初期化 動的にリソースを取得 ↓ 取得できないと動かない ↓ 初期化時に最低限静的に取得するのが常識 アプリケーション固有必要知識 ・プロセススケジューリング知識 ・プロセス状態知識 どの状態でスリープか、どの状態で死ぬか ゾンビが増える ・使用するドライバ仕様知識 ・一般アプリケーション開発知識 ・使用するミドルウェア知識 例:画像を映す Xwindow GTA ダイレクトFB 本がない。サイトでソースコードを読む 組み込みLinux開発の落とし穴 機能設計書作成能力による落とし穴 ↓ ポーティング、ドライバ開発者は、機能設計書作成時に、 フレームワークが既に決まっているため、通常アプリケーション 開発でいう所の「外部ビュー確定」という要素を含まない。 よって、ブートローダ/カーネルポーティング、ドライバ開発 のみしかプロジェクト経験していないメンバがアプリケーション 設計を実施すると、プロジェクトが正しく機能しない場合がある。 詳細仕様書レビュー方法による落とし穴 ↓ 一般的なアプリケーション開発者は詳細設計のレビューを 有知識者を揃えて実施する(ヒューマンチェック) それに対して、ポーティング、ドライバ開発者は初めに 「疎通コード」を組み、デバイス制御の根本的なことを確認し、 その後、詳細設計書を作成する(実機チェック) アプリケーション開発者がポーティング、ドライバ開発のリーダ を実施する場合、レビュー方法が正しく選択出来ず、 結果、後工程にリスクを残すことになる。 PC Linuxをエミュレーション環境の落とし穴 ↓ アプリケーション開発において、実機が使用可能になるまで PC Linuxをエミュレーション環境として使用するのは、 開発工期短縮するために有効な手段。 しかし、PC Linuxと実機とでは環境差分が多くあるため、 その点を理解して、「どこまで」PC Linux環境を使用するか 決定しないと、後で痛い目に合う。 第3章 組み込みLinux開発における開発アプローチ ・リスクマネージメント 開発の種類に応じて、リスクポイントの捉え方が重要 ・性能テスト、性能評価実施のタイミング 性能テストと性能評価は意味が違う 出来る限り前工程で性能テストは行う。遅くとも単体テストの前 どこで性能テストをやるかがプロジェクトマネージャの腕 ・適材適所の人材配置 ポーティング、ドライバ、アプリすべてを一人で行うのは無理 ・OJT ポーティング、ドライバ開発は少人数なのでOffJTで 質疑応答(前半) Q.ポーティングのもとになるものは? A.評価ボードにのっているLinux。これをカスタムボード用に変更する。 基本的にはレジスタマップと割り込みマップの変更だけで動くはずだが、 上手くいかないことが多い。 Q.ブートローダを動かす時、お勧めのツールは? A.ICEが使えるならICE。使えない場合はSerialからコンソールメッセージ。 それも出来ない場合はハード屋にリターン←守備範囲の明確化 Q.どのように送り返すのか? A.ログを返して返答待ち Q.ポーティング、ドライバ、アプリの人材配置の見極めは? A.正直使ってみないと分からない、悩みどころである。 どこでも可能な方法ではないが自社の専門学校で学生時代から見定めていく。 第4章 Linuxスケジューラ Linuxスケジューラ概要 RTOSとLinuxのスケジューリング方式 ・RTOS タスク優先度方式 最高優先度の実行タスクを実行し、タスクのリアルタイム性を保証する ・Linux TSS(タイムシェアリングシステム) あるプロセスからほかのプロセスへ短い間隔で切り替えることにより、 いかにも複数のプロセスを同時に実行しているように見せるシステム タスク優先度方式の特性 ・スケジューリングはタスクの優先度に基づいて行われ、最高優先度の実行可能 タスクを実行する ・タスクの優先度をその実行時間によって自動的に変化させたりしない ・実行中のタスクよりも高い優先度のタスクが実行可能となった場合、即座に タスク切り替えを行う TSSの特性 ・時分割でタスクを切り替えることを優先する ・スケジューリングはタスクのCPU実行時間に基づいて行われ、CPU実行時間が 残っている実行可能なタスクを実行する ・タスクが終了していなくてもCPU実行時間を使い果たしたタスクは タスク切り替えを行う ・CPU実行時間を使い果たしたタスクは新たにCPU実行時間を割り当てられるまで 実行されない Linuxスケジューラ ・Linuxでは、1つの実行単位をタスクではなくプロセスと呼ぶ ・プロセススケジューリングポリシーに応じてプロセスが実行される TSSによりプロセスを時分割で実行する リアルタイム性を意識してプロセスを実行する ・Linux2.6系列からはO(1)スケジューラを採用 Linux2.4系列からLinux2.6系列に移行する際にスケジューラが大幅に変更された 2.4系列までは絶望的なディスパッチ方式、おそい O(1)スケジューラとは? 優先度ごとに実行可能なプロセスをキューイング 最高priority の最初のキューをディスパッチ priority 0〜99 をリアルタイムプロセス priority 100〜139 を通常プロセスという 実行すべきプロセスが即座(O(1))にわかる ↓ プロセスディスパッチのオーバーヘッドが改善 スケジューリングポリシーとその特性 スケジューリングポリシー ・SCHED_OTHER ・SCHED_FIFO ・SCHED_RR SCHED_OTHER ・UNIXの伝統的なタイムシェアリングに基づくスケジューリング ・Linuxのデフォルトのポリシー ・静的優先度は100〜139 実行側が指定できる ・動的優先度を持つ Linuxが勝手に変更(瞬時的に) 実行したタスクをactiveキューからexpiredキューに移行 すべてのキューがexpiredキューに移ると全てひっくり返す リアルタイムプロセス ・スケジューリング要求が非常に厳密なプロセス ・優先度の低いプロセスに実行を妨害されることがない ・短い応答時間を保証し、また応答時間のばらつきも最小限 ・動的優先度は設定されない ・スケジューリング方針 SCHED_FIFO SCHED_RR SCHED_FIFO ・First In First Out スケジューリング ・使用するにはrootの権限が必要 ・静的優先度は 0〜98 ・リアルタイム性の要求されるアプリケーションで用いられる ・I/O待ちで停止するか、より高い優先度のプロセスが実行されるか、 明示的にCPUを明け渡すまで実行が続けられる ・expiredキューは使用しない SCHED_RR ・Round Robinスケジューリング ・使用するにはrootの権限が必要 ・静的優先度は 0〜98 ・実行時間の上限があるSCHED_FIFO ・割り当てられた実行時間(タイムスライス)を使い果たしたプロセス はrun queueの最後に置かれる ・expiredキューは使用しない 静的優先度と動的優先度 ・静的優先度 ユーザがシステムコールにて設定可能な値 通常プロセスの場合はnice値から算出する ・動的優先度 スケジューラが次に実行すべき通常プロセスを選ぶときに評価する値 プロセスの静的優先度とCPU使用状況などから算出する ユーザが値を変更することはできない 動的優先度は決まった契機で再計算される 動的優先度の計算式 動的優先度 = max(100,min(静的優先度 - ボーナス + 5,139)) 動的優先度は、プロセスが休止している間に経過した時間を考慮して決定される ↓ 待ち時間の長いプロセスほど動的優先度が高くなる スケジューラを意識したアプリケーション設計 アプリケーション設計時の注意点 ・動的優先度による優先度逆転問題 ±5の変更 それ以上差をつければ逆転しない ・nice値によって割り当てられるクォンタム時間 ・プロセスのディスパッチ契機 nice値を変更する際の注意点 ・動的優先度のより意図しない優先度逆転が発生する可能性がある ・優先度が逆転しても問題が発生しないアプリケーション設計を行う必要がある 基礎クォンタム時間の計算式 基礎クォンタム時間 = besttime*(MAX_PRIO - prio) / MAX_USER_PRIO/2 [ms] nice値 = 0 を境に基礎クォンタム時間が大幅に変化 RR型リアルタイムプロセスの基礎クォンタム時間 リアルタイム優先度 | 9 | 98 |・・・| 2 | 1 | prio | 0 | 1 |・・・| 97 | 98 | 基礎クォンタム時間 | 2800 | 2780 |・・・| 10 | 5 | 通常プロセスにおけるプロセスディスパッチ契機 ・プロセス生成時 ・プロセス終了時 ・実行プロセスが待機状態に遷移した時 ・プロセスが待機状態から復帰した時 ・実行プロセスがタイムスライスを使い切った時 ・カーネルプリエンプション時 ・システムコールによって明示的にプロセス切替を行った時(sched_yield) ・システムコールによってスケジューリングポリシーを変更した時 ・システムコールによって静的優先度を変更した時 リアルタイムプロセスにおけるプロセスディスパッチ契機 ・プロセスがリアルタイム優先度のより高い他のプロセスに実行権を奪われた ・プロセスが実行を中断する操作を行い、待ち状態で休止した ・プロセスが中断された ・プロセスが強制終了された ・プロセスが自発的にCPUを明け渡した ・ラウンドロビン型リアルタイムプロセスで、タイムスライスを使い切った まとめ OSのTSS機構に依存した設計(プロセス制御)をするのは間違っている OSの特性を活かした設計をするのは間違っていない アプリケーションの汎用性がなくなってしまう OSのTSS機構を知識として知っておく必要はある リアルタイムプロセスなどの特性を活かした設計をするには必要 性能チューニング時のボトルネックを解決するには必要 質疑応答(後半) Q.Linuxのスケジューリングの単位はスレッドでは? A.ディスパッチに関しては同一と考えてよい Q.シミュレータの購入は考えないのか? A.アプリケーションはPC Linux上で行う。また評価ボードを用いるので購入は考えていないが この分野でのシミュレータのビジネスモデルは分からない Q.実機だとデバッグできなくて困るところは? A.デバイスドライバのデバッグ。時間制約のためICEで止めることができない。 logをはいたりするようにしているが、それ自体が負荷になる場合もある。 その場合はメモリ上にlogをスタック上にためる。