オリジナルOS「MicrOS」の設計と実装(1) ―― MicrOSの概要とソースの概観
次に現れるのはメモリ・ブロックです.これは固定長メモリ・ブロックのサービスです(リスト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));
続いて,セマフォ制御,イベント・コントロール,メールボックスなど,μITRONでおなじみの機能が並んでいます.これらの関数の処理量は画面1ページに収まるものばかりです.
970行あたり,インターバル・タイマのサービス(リスト8)に入って,__delayはタスクのディレイ関数です.その次に__setTimerという関数があります(リスト9).この関数の引き数を見てください.この中に関数を持っているのが見てとれます.これはMicrOSがデマンド・コールバック関数と名付けたお勧めの関数です.これらの関数と概念はMicrOS特有のものです.連載中に詳しく解説します.
リスト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) 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: }
リスト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: }
続いてチャタリング処理(リスト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行です.