Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

【学習メモ#9th】12ステップで作る組込みOS自作入門

1,675 views

Published on

12ステップで作る組込みOS自作入門
http://www.amazon.co.jp/dp/4877832394/
坂井 弘亮(著)
カットシステム

Published in: Technology
  • Be the first to comment

  • Be the first to like this

【学習メモ#9th】12ステップで作る組込みOS自作入門

  1. 1. 12ステップで作る組込みOS自作入門 9thステップ @sandai
  2. 2. 【参考書籍】12ステップで作る組込みOS自作入門【内容】1ステップずつ、実際に動かしながらプログラムを発展させていく方式で無理なく学べる。OSやハードウェアに詳しくない方にも理解できるように十分な説明を提供坂井 弘亮(著)カットシステム(2010/5)【税込価格】4,410円【サポートページ】http://kozos.jp/books/makeos/
  3. 3. もくじ1.優先度ベースのスケジューリング2.優先度の実装3.プログラムの実行4.まとめ
  4. 4. 1.優先度ベースのスケジューリング
  5. 5. 優先度● 組込みのOSでは一般的に優先度をベースにスケ ジューリングが行われている● 優先度の高いスレッドが常に動作する
  6. 6. スレッドの状態● ここまでのプログラムのスレッドは常に「動作 可能」の状態。常に動いているってこと● これだと複数スレッド間で同期的な動作をさせ られない – あるスレッドが特定の処理を行うまで別スレッドが 待ち合わせする、といったことができない● そこでスレッドに「待ち」という状態を追加す る – スレッドを待ちにするシステム・コールを作る● 待ち状態にするにはレディー・キューからス レッドを抜けばいい
  7. 7. スレッドにおける状態の呼び名● スレッドが「待ち」状態に入ることをスリープ やウェイティングと呼ぶ● スレッドがキューに繋がって動作可能の状態を レディーと呼ぶ● スリープ状態のスレッドをレディー状態に戻す ことをウェイクアップと呼ぶ● 動作中のスレッドはアクティブやランニングな どと呼ぶ● このように、スレッドにはレディーとスリープ の2つの状態が存在する
  8. 8. 優先度とプリエンプション● ここまでのプログラムだと、実行可能なスレッ ドが複数ある場合はシステム・コールによって 順番に実行するようになっている● しかし、組込みシステムではあるスレッドがレ ディー状態になったとき、別のスレッドをさし おいてでも動作させたい場合がある – たとえば車のエアバック制御は、衝突を検知したら 一番に処理したい部分● ある割込みが発生した場合に、必ず一定時間内 で処理を開始するという時間保証が行えるかど うかを、OSのリアルタイム性と言う
  9. 9. リアルタイムOS● リアルタイム性を提供するOSをリアルタイムOS と呼ぶ● ハードウェア制御だと、ある割込み発生から特 定の処理を一定時間内に必ず行う必要があるな どの時間制約がある場合がある。こういったと きにOSのリアルタイム性は重要● 複数のスレッドがレディー状態のとき、どれを 動作するのか選択する必要があり、それに優先 度が利用される
  10. 10. プリエンプション● スレッドの動作が別のスレッドに強制的に切り 替わる動作を一般的にプリエンプションと呼ぶ – 優先度を持ったスレッドなら、優先度の低いスレッ ドの実行が中断され、優先度の高いスレッドが実行 されることでこのように動作する● プリエンプションが可能であることをプリエン プティブと言い(先取り可能とも言う)、スレッ ドが突然中断するようなことが無いのであれば ノンプリエンプティブと呼ぶ● KOZOSはプリエンプティブなOSとして開発して いく
  11. 11. アイドル・スレッド● スレッドに優先度がつくと、やることがないと きにCPUを省電力モードにするアイドル・ス レッドが簡単に実装できる● 今のプログラムだとレディー・キューが空にな るとシステムダウンしてしまうため、空になら ないよう一番低い優先度で「ムダななんらかの 処理」をするスレッドを常に動かしておく必要 があるwhile(1) { // なにもしない状態}
  12. 12. 省電力モード● 一般的なCPUには省電力モードという状態があ る – x86でいうところのHLT命令かな● CPUを省電力モードにすると命令の実行を停止 し、割込みが入るまで待つ状態になる – クロックが止まるので省電になるようだ● 他に動作する処理がないなら、アイドル・ス レッドを実行して待機状態にすれば良いwhile(1) { // ビジーループよりこうした命令を使うべきだね (CPUを省電力モードに遷移する命令);}
  13. 13. 2.優先度の実装
  14. 14. プログラムの修正と追加● 追加ファイル – test09_1.c,test09_2,test09_3...スレッドとなる サンプルプログラム● 修正ファイル – kozos.h,kozos.c...優先度を実装 – syscall.h,syscall.c...スレッド制御のシステム コール追加 – main.c...アイドル・スレッド追加 – Makefile
  15. 15. プログラムの修正内容● スレッドの状態を制御するシステム・コールの 追加 – kz_wait(),kz_sleep(),kz_wakeup(),kz_getid(),kz _chpri()● 優先度の追加 – 構造体に値を持たせて● readayqueを配列化 – 優先度のスレッド別にまとめる形 – ここのらへんのスケジューリングのアルゴリズムが 少し複雑かなってぐらいで、あとは8thステップの 延長
  16. 16. 3.プログラムの実行
  17. 17. ビルドの失敗(kozos.c)● パディングのサイズを変更typedef struct _kz_thread { . . kz_context context; char dummy[8]; ←dummy[16]からdummy[8]にした} kz_thread;
  18. 18. プログラムの実行/Users/sandai/12step/src/09/os% sudo cu -l /dev/tty.usbserial-FTG6PQ4Hkzload> run..test09_3 started.test09_3 wakeup in (test09_1).test09_1 sleep out.test09_1 chpri in.test09_3 wakeup out.test09_3 wakeup in (test09_2).test09_2 sleep out.test09_2 chpri in.test09_1 chpri out.test09_1 wait in.test09_3 wakeup out.test09_3 wait in.test09_2 chpri out.test09_2 wait in.test09_1 wait out.test09_1 trap in.test09_1 DOWN.test09_1 EXIT.test09_3 wait out.test09_3 exit in.test09_3 EXIT.test09_2 wait out.test09_2 exit.test09_2 EXIT.
  19. 19. 4.まとめ
  20. 20. まとめ1● 8thステップを理解していないと9thステップは 何をやっているのかわからないはず● プログラムの修正部分に難しいコードはない● システム・コールとスケジューリング部分のア ルゴリズムの処理の流れが難しいので、そこを まとめておこう
  21. 21. まとめ2● 下記のkz_run()のうち、test09_1_id = ...の 処理の流れを記述しておく● kz_start()でstart_threads()が起動した後の ことなので注意static int start_threads(int argc, char *argv[]){ test09_1_id = kz_run(test09_1_main, "test09_1", 1, 0x100, 0, . .
  22. 22. まとめ3● kz_run() – kz_syscall()に渡すデータを構造体に保存 – kz_syscall()呼び出し● kz_syscall() – current->syscall.xxxにシステムコールのタイプと kz_run()で受け取った構造体を設定 – asm volatile(“trapa #0”)で割込みが発生して thread_intr()呼び出し
  23. 23. まとめ4● thread_intr() – handlers[type]()によりsyscall_intr()呼び出し ● 最終的にthread_run()が呼び出されてp- >un.run.ret = にcurrentが代入される – schedule()呼び出し ● この部分でスケジューリングされるため、優先 順位の高い初期スレッドのidleスレッドが動作 対象。test09_1_mainには映らないので注意 – dispatch()呼び出し ● currentにあるidleスレッドのstart_threadsが 実行を再開
  24. 24. まとめ5● dispatch()が呼ばれると、割込みが発生した kz_syscall()にあるasm volatile(“trapa #0”)から続く● 特に処理がないので、kz_run()に戻り、return param.un.run.retでtest09_1_idにその値が代 入され、test09_2_id = ...と処理が同じよう に続く
  25. 25. まとめまとめ● kz_run()の流れは以上のような形● 優先順位によってschedlue()で動作するスレッ ドが決まるので、ここを気をつけてみる必要が ある● あとはkz_sleep()が難しいかも。レディー・ キューから外した場合、test09_1_idにスレッ ドIDが保存されていて、kz_sleep()ではそれを 使ってレディー・キューに再度入れていること になっている – スリープさせたスレッドの管理が微妙な気がするけ れど、こういうものなんだろうか

×