2ちゃんねる ★スマホ版★ ■掲示板に戻る■ 全部 1- 最新50  

■ このスレッドは過去ログ倉庫に格納されています

5000行のオリジナルOS「MicrOS」

1 :Be名無しさん:2008/02/17(日) 01:39:57
MicrOSソース・コード
http://www.cqpub.co.jp/interface/download/2008/01/MicrOS0801.zip

オリジナルOS「MicrOS」の設計と実装
――第1回 MicrOSの概要とソースの概観

田口 信夫

Interface誌2007年5月号付属の
V850マイコン基板で動作する
オリジナルOS「MicrOS(マイクロス)」が登場した.

MicrOSは ITRONに似た機能をもち,
それでいてソース・コードは5000行程度と
非常にコンパクトである.

http://www.kumikomi.net/article/explanation/2008/03micr1/01.html

2 :Be名無しさん:2008/02/17(日) 07:40:33
初の2ゲット


3 :Be名無しさん:2008/02/17(日) 09:58:28
すげええ
俺もアセンブラ勉強しようかな

4 :Be名無しさん:2008/02/20(水) 18:00:00
アセンブリ学習のためにnasm入れた


5 :Be名無しさん:2008/02/22(金) 15:13:03
マクロスって読んでしまった

6 :Be名無しさん:2008/02/29(金) 18:05:01
本連載では,MicrOSを題材にして組み込み向けリアルタイムOSの設計と実装について見ていく.

(編集部)


7 :Be名無しさん:2008/02/29(金) 18:06:04
1-1.MicrOSとは何か
 この度,Interface誌2007年5月号付属V850マイコン基板で動作するオリジナルOSを作成しました.
「MicrOS」という名前で,読者の皆さんにも使える形で公開しています注1.

注1:MicrOSのソース・コードはCQ出版社のWebサイトよりダウンロードできる.


 MicrOSは本連載で扱うOSの名前です.V850で動作するように作られているので,「V850-MicrOS」と呼んでいます.MicrOSは,組み込みOSの作り方に付けた名前でもあります.なぜ組み込みOSの作り方に名前を付けたのかというと,
組み込みOSの作り方を説明したかったからです.MicrOS方式によって構造が単純化され,組み込みOSを簡単に構成することができます.

 V850-MicrOSのサービスは機能的にはμITRON 3.0に相当します.MicrOSと同じような機能をμITRONのインターフェース
に書き換えたとしても,大した作業にはなりません.現在のV850-MicrOSのシステム・コールは,μITRONの機能のうち
比較的使用すると予想される機能を取り出して,それにMicrOS独自の機能を幾つか付け加えたと思っていただければ結構です.

 MicrOSにはアプリケーション・システム(ユーザ・アプリケーション)を構成する上でぜひ利用してもらいたい機能があります.
それはMicrOSのデマンド・コールバック関数です.一言で言うと,デマンド型のシステム・コールとコールバック関数を組み合わせた機能で,
タイマ制御やUARTの入力処理に利用できます.この機能を使うとタイマを使ったアプリケーションなどが単純化され,
アプリケーション・システムの見通しをよくできます.このようにMicrOSは単なるμITRONのサブセットではなく,
組み込みアプリケーション・システムの構成方法に提案を行っている部分も持っています.


8 :Be名無しさん:2008/03/05(水) 15:27:55
1-2.V850-MicrOSの全体構成
● MicrOS.cのソース・コードを読む
 MicrOSの説明に入る前に,V850-MicrOSのソース・コードを見てみましょう.MicrOS.cをエディタで開いてみてください.

 ここにはMicrOSのシステム・コールのほとんどが収められています.各機能は,
  /*********** <機能名> ***********/
で区切られているので,各システム・コールの処理量は一目で分かるようになっています.

 最初は__aplMainという関数です(リスト1).
この関数はアプリケーション・システムの初期設定を行う関数のテンプレートです.
#if 1を #if 0に変更すればここに__aplMainの実体が展開されます.

9 :Be名無しさん:2008/03/05(水) 15:28:49
リスト1 aplMain部
MicrOS.c内.今回はApplication.c内のものを使用しているので未使用.

008: /************** Application main *****************/
009: #if 1 /*** 1: aplMain in another source, 0: in this source ***/
010:
011: #if USING_TIMERTASK
012: extern _TCB   *__aplTCBList[];
013: #define tmrTCB __aplTCBList[0]   /* Timer Task */
014: #endif
015:
016: #else
017:
018: #define NTASKS 16
019: _TCB   *__aplTCBList[NTASKS];
020: #define tmrTCB __aplTCBList[0]   /* Timer Task */
021:
022: /* Uart buffer */
023: #define UARTSSZ 256
024: #define UARTRSZ 128
025: char uartbuf[UARTSSZ+UARTSSZ];
026: /* Debug buffer */
027: #define DBGBFSZ 2048
028: char debugbuf[DBGBFSZ];
029: /*====================================================+
030: | application main |
031: +====================================================*/
032: void aplMain_template(void)
033: {

10 :Be名無しさん:2008/03/05(水) 15:29:13
 次にタイマ関係の関数があります(リスト2).これはハードウェアの違いを吸収するための関数でMicrOSのタイマ制御で用いられます.

リスト2 タイマ関連

105: #if 0
106: /** Write/Read Hardware timer & Arrenge Timervalue **/
107: /*====================================================+
108: | write Hardware Timer return:remain value |
109: +====================================================*/
110: unsigned int _writeTimerValue_template(unsigned int value)
111: {
112: #if SYSCLK_READ_OK
113: TP5CTL0 = 0; /* TMP5 reset */
114: TP5CTL1 = 0x00; /* set TMP5 to interval mode */
115: TP5OPT0 = 0x00;
 ここまでの関数はアプリケーション・システムによって変更される可能性のあるプログラムです.

11 :Be名無しさん:2008/03/05(水) 15:30:06
 その次に現れるのはMicrOSの中で比較的共通に使われる関数群(リスト3)で,アプリケーション・システムがこれらの関数
を直接コールすることはありません.この中では_SCB,_RQB,_TCBといった構造体が使われています.これらはMicrOSを
構成するときに鍵となる構造体なのですが,その説明は後回しにして,ここではさらにMicrOS.cを眺めていきましょう.

リスト3 共通関数群(FIFOの処理)

191: /****** OS function(interrupt in inhibit) *******/
192: /*====================================================+
193: | FirstIn FirstOut Link |
194: +====================================================*/
195: void fifo(void *scb, void *rqb)
196: {
197: _SCB *s;
198: _RQB *r;
199:
200: s = scb;
201: r = rqb;
202: r->next = 0;
203: if(s->head == 0){
204: s->head = r;
205: s->tail = r;
206: r->prior = (_RQB *)s;
207: } else {

12 :Be名無しさん:2008/03/05(水) 15:30:52
 この後はシステム・コールのコーディングです(リスト4).この辺りの関数は数行の小さなものばかりです.どんどん先に
進みます.しばらく進むと400行目あたりに__wait関数(リスト5)と__active関数があります.この関数はMicrOSを構成するとき
の鍵となる関数ですから名称だけを記憶しておいてください.どんどんいきます.

リスト4 システム・コールの関数(プライオリティの変更)

324: /*====================================================+
325: | Change Priority |
326: +====================================================*/
327: int __chgPri(unsigned char pri)
328: {
329: int irc;
330: _TCB *t;
331:
332: if(pri >= SYSNPRI) return(E_PRI);
リスト5 __wait関数

411: int __wait(unsigned int waitstatus)
412: {
413: _TCB *t;
414: int psw, irc;
415:
416: while(__cpumode() != 0){};
/* if(not UserMode) then eternal loop */
417: irc = E_WAITFLAG;
418: psw = __DIC();
419: if((_sysctrl->cur == (_TCB *)0)||( waitstatus == 0)) goto p9;
420: /*** set TCB status ***/

13 :Be名無しさん:2008/03/05(水) 15:31:13
 550行目あたりにメモリ・アロケーションがあります(リスト6).これは可変長のメモリ・アサインです.mallocとかfreeといった関数名が見えます.

リスト6 メモリ関連の関数(malloc)

548: /*********** Memory Allocation ************/
549: /*====================================================+
550: | Memory Allocation |
551: +====================================================*/
552: static void *malloc(unsigned int size)
553: {
554: union{
555: void *v;
556: unsigned int *pui;
557: unsigned int ui;
558: } top, lmt, adr, w;
559: unsigned int sz;
560:
561: size = (size + (3+8)) & (~0x03);

14 :Be名無しさん:2008/03/05(水) 23:48:29
お前は著作権と言うものを知らないのか

15 :Be名無しさん:2008/03/06(木) 09:16:24
 次に現れるのはメモリ・ブロックです.これは固定長メモリ・ブロックのサービスです(リスト7).μITRONの命名規則に従ったような名前の関数が出てきます.節操がないなどと思わないでください.

リスト7 固定長メモリ関連の関数(opn_mblk)

764: /*====================================================+
765: | Create memory block |
766: +====================================================*/
767: int opn_mblk(_MBLKCB *scb, int size, int n, void *buf)
768: {
769: union{
770: void *v;
771: _RQB *r;
772: unsigned int *pui;
773: unsigned int ui;
774: } b;
775:
776: if((size & 0x03) != 0) return(E_PARAM);
777: __memset(scb, 0, sizeof(_MBLKCB));

16 :Be名無しさん:2008/03/08(土) 11:46:17
 続いて,セマフォ制御,イベント・コントロール,メールボックスなど,μITRONでおなじみの機能が並んでいます.これらの関数の処理量は画面1ページに収まるものばかりです.

 970行あたり,インターバル・タイマのサービス(リスト8)に入って,__delayはタスクのディレイ関数です.
その次に__setTimerという関数があります(リスト9).この関数の引き数を見てください.
この中に関数を持っているのが見てとれます.これはMicrOSがデマンド・コールバック関数と名付けたお勧めの関数です.
これらの関数と概念はMicrOS特有のものです.連載中に詳しく解説します.

17 :Be名無しさん:2008/03/08(土) 11:46:59
リスト8 インターバル・タイマ

966: /*********** Interval Timer Control ************/
967: /*====================================================+
968: | Timer Interrupt |
969: +====================================================*/
970: #if SYSCLK_READ_OK
971: #pragma interrupt INTTP5CC0 inttp5cc0_func
972: #else
973: #pragma interrupt INTTM0EQ0 inttm0eq0_func
974: #endif
975:
976: __interrupt
977: //__multi_interrupt
978: #if SYSCLK_READ_OK
979: void inttp5cc0_func(void)

18 :Be名無しさん:2008/03/08(土) 11:47:20
980: #else
981: void inttm0eq0_func(void)
982: #endif
983: {
984: volatile _TMRCB *s;
985: _TMRRQB *p;
986: union{
987: _TCB *t;
988: unsigned int ui;
989: } u;
990: #if USING_TIMERTASK
991: #else
992: int psw;
993: #endif
994:
995: s = &_sysctrl->tmr;
996: while((p = s->head) != (_TMRRQB *)0){
997: /* check timeup of request link header */
998: if(p->timer != 0){
999: p->timer = _writeTimerValue(p->timer);
1000: break;
1001: }

19 :Be名無しさん:2008/03/08(土) 11:47:43
リスト9 __setTimer

1141: /*===================================================+
1142: | set timer |
1143: +===================================================*/
1144: int __setTimer(_TMRRQB *rqb, unsigned int tmrcnt, void (*tmover)(void *param), void *para)
1145: {
1146: int psw;
1147:
1148: if(rqb->tcb == (_TCB *)0) return(E_NOTRQB);
1149: if(((unsigned int)rqb->tcb & _TYPMASK) != _TYPRQB) return(E_NOTRQB);
1150: rqb->proc = tmover;
1151: rqb->param = para;
1152: psw = __DIC();
1153: tmrlnk(rqb, tmrcnt);
1154: __EIC(psw);
1155: return(E_OK);
1156: }

20 :Be名無しさん:2008/03/08(土) 11:48:38
 続いてチャタリング処理(リスト10)やタイマ・パターンを処理する機能がコーディングされています.
これらはラベルUSING_****の定義によって選択可能な機能になっていますが,
タイマ・デマンド・コールバックのアプリケーションです.
タイマ・パターン処理は周期的に点滅を繰り返すLEDパターンや,ADPCMを使ってオルゴールのような音のパターンを
表現するのに利用できます.その処理を行うのに一つのデマンド・コールバック関数とパターン・テーブルを登録するだけで済みます.

リスト10 チャタリング処理(chattcallback)

1202: /****** Chattering Interrupt Procedure Control *****/
1203: #if USING_CHATTERING
1204: /*===================================================+
1205: | Chattering timeout callback |
1206: +===================================================*/
1207: static void chattcallback(_CHATCB *chtcb)
1208: {
1209: int flag;
1210:
1211: flag = (*chtcb->callback)(-1);
1212: if(flag == chtcb->flag){
1213: chtcb->count--;
1214: if(chtcb->count == 0){
1215: (*chtcb->callback)(flag);
1216: return;
1217: }
1218: } else {
 この後にデバッグ関数群と__sprint関数が記述されています.この二つの処理でソース・プログラムの3分の1を占めています.

 以上がMicrOS.cです.行数は2027行です.

21 :Be名無しさん:2008/03/19(水) 17:53:47
● MicrOSbioslr.cとMicrOScmd.cのソース・コードを読む
 ついでにMicrOSbioslr.cとMicrOScmd.cも見てみましょう.

 MicrOSbioslr.cはほとんどがUARTのドライバを構成しています.この先頭にVBF制御という耳慣れない処理が入っていま
す(リスト11).これはリング・バッファの制御を行う関数群です.UARTとデバッグ関数の中で使われています.この機能で
デバッグ出力した結果をメモリにため込んでおき,後でUARTにつないで一括して出力するような機能を持ちます.

リスト11 MicrOSbioslr.cのVBF制御部

001: /*****************************************************+
002: | MicrOS Drivers Load in RAM |
003: +*****************************************************/
004: #define _MICROSBIOSLR_C_
005: #include "MicrOS.h"
006:
007: /************* Variable Buffer Control ***************/
008: /*====================================================+
009: | VBF initialize |
010: +====================================================*/
011: _VBFCTRL *_vbfinit(_VBFCTRL *vbf, char *buf, int sz)
012: {
013: vbf->org = buf;
014: vbf->lmt = buf + sz;
015: vbf->getp = buf;
016: vbf->setp = buf;
017: return(vbf);
018: }
 MicrOScmdはUARTを使ったコンソールを持っており,デバッグ用コマンドを実行できます.現在はメモリ・ダンプ・コマンドと
メモリ変更コマンドが組み込まれていますが,コマンド・ラインの解析処理を行ってくれるので,アプリケーションでコマンドを
定義して追加するのは容易です.

 MicrOSbioslr.cは444行,MicrOScmd.cは826行です.

22 :Be名無しさん:2008/03/19(水) 17:54:30
● MicrOSasm.sのソース・コードを読む
 V850-MicrOSを構成するソース・プログラムはヘッダ・ファイルを除くと,あとはアセンブリ・コードで記述されたMicrOSasm.s
だけです.これは1000行程度で,意外に大きいと思われるかもしれません.しかし,このうちの4分の3はデバッグ関数や
__sprint関数,コマンド処理で使われる編集系の関数です.CA850アセンブラに慣れるためとデバッグ出力に時間をかけたく
なかったので,アセンブリ・コードで記述しました.

 MicrOSasm.sには,C言語では記述不可能な割り込み禁止・解除の関数などとマルチプログラミングの根幹である
ディスパッチャが含まれています.__task関数もこの中にあります.これらの用語については後で説明します.

 MicrOSのソース・プログラムが,組み込みOSの機能以外のところでステップ数を稼いでいる印象を受けたかもしれません
が,これがMicrOSの実体です.

 MicrOSのソース・コード全体の構成を図1に示します.


図1 MicrOSのソース・コードの全体構成

23 :Be名無しさん:2008/03/19(水) 17:55:47
1-3.組み込みOSの基本機能とMicrOS

 組み込みOSには二つの役割があります.一つは「マルチプログラミング環境を提供すること」,
もう一つは「組み込みOSを組み込んだアプリケーション・システムに対して,サービスを行うこと」です.
この二つの役割をできるだけ短時間で,無駄なく処理することが要求されます.
MicrOSはマルチタスク制御方式によってマルチプログラミング環境を提供します.

 アプリケーション・システムは起動時にコールされる__aplMain関数(リスト12)の中で,
ハードウェアの初期設定やアプリケーション・システムの初期設定とともに,__task関数によってタスクを登録します.
__task関数に指定するパラメータはタスクの処理を行う関数と,その処理に必要なスタックのサイズ,
および処理を行うときのプライオリティ(優先順位)です.MicrOSには,
あらかじめシステム制御に必要な領域として定義されたシステム・コントロール・ブロックがあります.
__task関数はシステム・コントロール・ブロックの中にタスクを管理するのに必要な領域を確保して,
その先頭アドレスを返り値として__aplMainに通知します.この領域をTCB(Task Control Block)といいます.

24 :Be名無しさん:2008/03/19(水) 17:56:15
リスト12 aplMain関数(Application.c内)

/*=========================================================
| application main |
+=========================================================*
void aplMain(void)
{
/*** Driver Initialize(after hardware_initialize) ***/
PMCT.6 = 0; /* LED pct6 */

/*** application system initialize ***/
_initTimer();
tmcnt = __sec(1); /* LED on/off cycle default 1sec */
LEDsw = 0;
opn_sem((sem0 = &semcb0), 1);
mbx1_rqbl = 0; /* mbx_task:link set */
nrel_flag = 0; /* led_task:update */
#if USING_UART

_uartopen(_UART_1S|_UART_NP|_UART_8L|_UART_LF|_UART_EI|_UART
_RCVECHO,
9600, uartbuf, UARTSSZ, UARTRSZ);
#endif
#if USING_DEBUG
__dbginit(debugbuf, DBGBFSZ);
__dbgselect(0x00000001);
#endif
/*** Entry Task(after driver initialize) ***/
/*** System Timer Task ***/
#if USING_TIMERTASK
__aplTCBList[0] = __task(&__tmr_task, 4*64, 3);
#endif

25 :Be名無しさん:2008/03/19(水) 17:56:38
#if DEBUG_FUNC

__aplTCBList[2] = __task(&debug_task, 4*256, 5);
__aplTCBList[3] = __task(&debug_task_sub, 4*64, 6);

#else /* DEBUG_FUNC */

#if USING_CMDTASK
/*** System Console Task(128:_sprintf using stack) ***/
__aplTCBList[1] = __task(&__cmd, 4*64+128, SYSNPRI-1);
_uartsetcb(_UART_RCVCB_TASK, __aplTCBList[1]);
#endif
#if USING_CMDCB
_uartsetcb(_UART_RCVCB_CHAR, __cmdcb);
#endif
/*** entry Application Task[TCB *_task(int (*proc)(), int stkSize, int pri)] ***/
__aplTCBList[3] = __task(&mbx_task, 4*256, 6);
__aplTCBList[4] = __task(&led_task, 4*256, 4);
__aplTCBList[5] = __task(&evt_or_task, 4*256, 6);
__aplTCBList[6] = __task(&evt_and_task, 4*256, 5);
// __aplTCBList[6] = __task(&_task, 4*256, 5);

#endif /* DEBUG_FUNC */
}

26 :Be名無しさん:2008/03/19(水) 18:00:13
 TCBにはスタック領域とタスクを制御する情報が含まれます.
タスクを制御する情報はタスクの先頭部分に置かれ,TCBの上限アドレスから
タスクの制御情報に向かってスタックが使われます.
TCBというときにはタスクの制御情報の部分だけを示すことがあるので注意してください.

 通常のCプログラムはmain関数からスタートしますが,
組み込みシステムではこのmainに相当する関数が複数あることがあります.
これらがすべてmainの名称を持っていたら,システムを構成する関数を同時にビルドする組み込みシステムでは
区別ができないので,こうしたmain関数にも“main”以外の名称を付けて,タスク処理プログラム部分とします.

 _aplMain関数の処理が終了するとMicrOSの最終的な初期設定を行って,マルチプログラミングの制御が開始されます.
マルチプログラミングは日本語では並行処理といいますが,登録されたタスクが完全に並列に実行されているわけでは
ありません.タスクの処理を短い時間で切り替えながら実行しているのです.このときに処理が中断されて
その次に処理するまでの間,CPUの処理経過を保持しておかなければなりません.その保持に使われるのがTCBです.
保持する情報とは,具体的にはCPUのレジスタ類です.

 タスクが処理するときの状態を,MicrOSは次の三つで管理します(図2).

図2 タスクの実行状態
http://www.kumikomi.net/article/explanation/2008/03micr1/images/zu02_01.gif

Ready状態 :処理を実行できる状態
Run状態 :タスクが処理を行っている状態
Wait状態 :タスクが処理を中断しなければならない状態

27 :Be名無しさん:2008/03/19(水) 18:00:34
 Ready状態のタスクはシステム・コントロール・ブロックのR
eadyプール(プライオリティ・テーブルともいう)にリンクされています.タスクが登録された状態はReady状態です.

 Run状態になることを,「タスクに実行権を割り当てる」と表現することがあります.
Run状態のタスクは一つしか存在しません.
Readyプールの中から最も実行優先度の高いタスクに実行権が与えられ,
TCBにセーブされているCPUの状態が書き込まれます.
この処理を行うのがディスパッチャです.これによってタスクの処理が継続します.

 Run状態のタスクがシステム・コールを発行し,そのシステム・コールが
__wait関数を使っているときにタスクはWait状態になります.ほかのタスクからこのタスクを指定した
_active関数または割り込み処理の中で,このタスクを指定した_activex関数が実行されたときに
Wait状態は解除されます.Wait状態が解除されるとタスクはReadyに戻ります.
この動作にはハードウェアの割り込み機構が大いに寄与しています.

28 :Be名無しさん:2008/03/29(土) 08:13:37
1-4.タスクの動作
● 割り込み時の動作
 システム動作中に発生する可能性のある割り込みには次のものがあります.

 ・正常な割り込み──外部割り込み
        └内部割り込み
 ・異常割り込み
 異常割り込みは,プログラムのミスや電源・メモリの異常などが原因で発生します.
異常割り込みは適切に処理しなければなりません.
しかしその処理方法はアプリケーション・システムによって異なるので,MicrOSでは処理しません.

 外部割り込みは,周辺機器の状態の変化でRun状態のタスクの有無にかかわらず
発生します.内部割り込みはRun状態のタスクがTRAP命令を発行したときに発生します.

 外部割り込みの処理において入り口と出口の共通部分はMicrOSで処理しますが,
周辺装置固有の処理はアプリケーション側で用意して,
呼び出される構造(関数名はMicrOS側で決めている)になっています(図3).
周辺装置固有の割り込み処理で特定のタスクを起動する必要があるときに
__activex関数を使います.この関数の中でタスクを切り替える必要があるときは,
システム・コントロール・ブロックの中に保存します.周辺装置固有の処理から戻り,
割り込みがあったときにRun状態のタスクがなければ,ディスパッチャへ制御を移します.
実行中のタスクがあればタスク・スイッチの必要性をチェックして,
必要でなければRUN状態だったタスクに制御を戻します.
タスク・スイッチが必要なときは,割り込まれたときの状態をTCBにセーブしてeadyに戻されます.


図3 割り込み部の動作
http://www.kumikomi.net/article/explanation/2008/03micr1/images/zu03_01.gif

29 :Be名無しさん:2008/03/29(土) 08:14:31
● CA850の割り込み処理をそのまま利用している
 前述の説明で,割り込みの出入り口処理をMicrOSが直接行っていると書きましたが,
V850-MicrOSの外部割り込み処理の方法は多少異なっています.
これはV850-MicrOSがV850用CコンパイラCA850の外部割り込み処理を
そのまま利用しているためです.タスク起動の必要があるときは
_activex関数を使う部分まではMicrOS仕様ですが,割り込み処理から戻る直前に
__godspio関数をコールします.この関数の中でタスク・スイッチに必要性がチェックされ,
不要であればそのまま__godspioをコールした位置に戻ります.
この後,CA850の割り込みの出口処理によって割り込まれたタスクに戻ります.
タスク・スイッチを行う必要があるときはタスクをReadyに戻しますが,
次回に処理を再開するのは__godspioの戻り番地です.
TCBにセーブされるCPUはそこに合わせた内容になっています.

30 :Be名無しさん:2008/03/29(土) 08:15:35
● 内部割り込みの使用とレジスタの「非」保存
 システム・コールはタスクの状態を変化させるという点から,
「ウェイト系」,「アクティブ系」,「どちらでもない」の3種類に分類できます.
「どちらでもない」システム・コールは,処理後はアプリケーション・タスクに戻ります.

 ウェイト系のシステム・コールは,コールしたタスクがWait状態になる可能性のあるもの
です.アプリケーションの要求に応えられない状態のとき,条件が整うまで
コールしたタスクを__wait関数を使ってウェイトさせます.典型的なウェイトの処理は,
SCB(後述)にリンクしてから__wait関数をコールする,メモリ・アロケーションや
メモリ・ブロックのアサインなどのシステム・コールです.

 アクティブ系のシステム・コールは,ウェイト系のシステム・コールに対応しています.
ウェイト系のシステム・コールによってウェイトしているタスクがあり,
それを解除する条件が発生した場合,__active関数を使ってそのタスクを
Ready状態とします.Ready状態となったタスクが__active関数を使用したタスクより
高い優先順位を持つとき,タスク・スイッチを行います.

31 :Be名無しさん:2008/03/29(土) 09:58:57
このスレってコピペだらけで作者に訴えられたりしないのか?

32 :Be名無しさん:2008/03/30(日) 10:48:29
原作者本人や、原作者の承認を得ていれば
問題ないんじゃないか?

33 :Be名無しさん:2008/03/30(日) 20:35:21
承認を受けてれば・・・なwww

34 :Be名無しさん:2008/04/01(火) 01:05:20
ここまでくると引用の範疇を超えてるし、もうオワタ

35 :Be名無しさん:2008/04/29(火) 19:56:33
 MicrOSは__wait関数と__active関数の処理に内部割り込みを使用します.
この割り込み処理の中で内部割り込みを発生させたタスクは現在状態を
TCBにセーブします.このとき,コンパイラのレジスタ使用規約で,
ワーキング・レジスタかアーギュメント・レジスタとされるレジスタはセーブされません.
これらはレジスタ使用規約上,コールされた関数側ではセーブしなくても良い
レジスタになっているからです.MicrOSはこの領域を,システム・コールを処理するときのワ
ーク・エリアとして利用します.TCBに現在状態をセーブした後,
アクティブ系のシステム・コールのときはReadyプールに登録します
(ウェイト系のシステム・コールの場合は__wait関数をコールする前に
ウェイトに必要な処理は済んでいる).こうした処理の後,ディスパッチャにジャンプします.

 なお,システム・コールであってもコールされたシステム・コールの中で
複数のタスクのウェイトを解除するような処理については,
__active関数の代わりに__activex関数とこの内部割り込み関数へのコールを
組み合わせなければなりません.


36 :Be名無しさん:2009/07/29(水) 18:58:23
Minixもよろしく


26 KB
■ このスレッドは過去ログ倉庫に格納されています

★スマホ版★ 掲示板に戻る 全部 前100 次100 最新50

read.cgi ver 05.02.02 2014/06/23 Mango Mangüé ★
FOX ★ DSO(Dynamic Shared Object)