最終更新 2006/08/17
簡易リアルタイム処理
1 簡易とはいいながらカーネルモードになり難しい
リアルタイム関係のプログラムはカーネルモードでプログラムしなければならない。カーネルモードでの使用できる関数には制限があり、Linuxの多くの機能が使用可能ではない。例えばLAN通信でさえ使用することは難しい、多くの場合ユーザモードに回して実行することになる。この場合、ユーザプログラム+ I/Oシステムコール+デバイスドライバとなり、それなりにややこしい。
2 カーネルモードとユーザモードをシームレスにつなぐ
せっかくリアルタイムプログラムを導入したのだから、IPC であるitMessageSend/Receive() を用いてカーネルモードとユーザモードを接続する。併せて、デバイスドライバ部が itMessageSend/receive() に吸収され、構造がすっきりする。
3 デバッグが容易
ユーザモードでデバッグできるところは、ユーザモードで開発したほうが、各種ツールが使ええるので楽でである。ユーザモードとカーネルモードをシームレスにつなぐことにより、デバッグ時はユーザモードで開発し、デバッグ終了とともにカーネルモードに移行することができる。ただし、メモリ空間が異なるので、グローバル変数等は注意が必要である。
4 構造
ユーザモードとカーネルモードのプログラムは原則的に同様であるが、プロセス間通信の itMesageReceive/Send 関数を少し工夫する。
ItMessageCreate() 呼び出し時に、ItMesgaeReceive/Send 関数は ioctl() を経由して、カーネルモードの itMessageReceive/Send に接続するモードを追加する。
図示すると下記のようになる。
5 ユーザモードAPI
 ユーザモードでのAPIとしてpthread を用いて itThreadCreate 及びitMessageSend/Receive をデバイスドライバとしてインプリメントした。
 itMessageSend/Receive は2種類あり、一つはカーネルと通信するO_RDONLY/O_WRONLY モードです。他にユーザモードから使用できるMessageSend/Receive(O_RDWR) がある。
int itThreadCreate (void *entrypoint, void *arg, int tid)
priority in int タスクの優先度
entrypoint in void * タスクのエントリーポイント
arg  in void * 割り込み処理ルーチン
tid out int * 割り込み処理ルーチンへの引数
戻り値   int thread id

int itMessageCreate (int flags)
flags in int flags O_RDWR,O_RDONLY,OWRONLY
戻り値   int msgQhandle (fd)

itMessageSend/Receiveは共通。

ユーザモードからitMessageSend/Receiveの例
int msgQue=itMessageCreate(O_RDWR);
strcpy(sendbuf, "1234567890123456789");
ret = itMessageSend(msgQue, sendbuf, sizeof(sendbuf));
ret = itMessageReceive(msgQue, recvbuf, sizeof(recvbuf));
printf("data:%s\n",recvbuf);
 デバイスドライバ内にある messageSend/Receive を使えるようにしただけなんですが、ドライバ内とユーザプロセス内で共通になり、ユーザプロセスでデバッグしてから、ドライバへ移行という手が使える。
6 感想
 作り込むと、カーネルモードと通信するユーザタスクは1個で、すべての通信を賄う形になるが、それでもシステム全体はすっきりと論理的に出来上がる。
 また、ユーザモードとカーネルモードで同一ソースを#ifdefで使い分けるのであるが、これも予想とおり論理的見通しの良さに貢献している。

質問は こちら から

戻る