いろんなものはつながっている

組み込みOS自作入門(10)システムコール

OSが持つ機能を利用するにはOSのサービス関数を呼び出す必要があるがそれは呼び出し元(アプリケーション)とは完全に独立した処理で行うようにする必要がある。ライブラリを呼ぶように行うとそれはアプリケーション下でOSのサービス関数が動くこととなりOSがアプリケーションの不具合等に影響されてしまう。

したがってOSのサービス関数も割り込み処理を使って実行され、アプリケーションがソフトウェア割り込みを発生させることでOSのサービス関数をよびだしている。

アプリケーションから呼び出すOSのサービス関数を、

kz_thread_id_t kz_run(kz_func_t func, char *name, int priority, int stacksize,
		      int argc, char *argv[])
{
    kz_syscall_param_t param;
    param.un.run.func = func;
    param.un.run.name = name;
    param.un.run.priority = priority;
    param.un.run.stacksize = stacksize;
    param.un.run.argc = argc;
    param.un.run.argv = argv;
    kz_syscall(KZ_SYSCALL_TYPE_RUN, &param);
    return param.un.run.ret;
}

int kz_wait(void)
{
    kz_syscall_param_t param;
    kz_syscall(KZ_SYSCALL_TYPE_WAIT, &param);
    return param.un.wait.ret;
}

int kz_wakeup(kz_thread_id_t id)
{
    kz_syscall_param_t param;
    param.un.wakeup.id = id;
    kz_syscall(KZ_SYSCALL_TYPE_WAKEUP, &param);
    return param.un.wakeup.ret;
}
....

といったかたちで準備し、それぞれの関数でサービス関数に渡すパラメータをセットして、kz_syscall(…)を呼び出し(以下)、割り込みを明示的に発生させる。同時に、サービス関数に渡すパラメータや呼び出したいサービス関数のタイプをカレントタスクにセットしている。

void kz_syscall(kz_syscall_type_t type, kz_syscall_param_t *param)
{
  current->syscall.type  = type;
  current->syscall.param = param;
  asm volatile ("trapa #0");
}

明示的に発生させたソフトウェア割り込みによってあらかじめ登録しておいたソフトウェア割り込み用の関数がよばれる。

static void syscall_intr(void)
{
  syscall_proc(current->syscall.type, current->syscall.param);
}

syscall_proc(..)が最終的には以下のようにタイプにおうじてそれぞれのサービス関数を呼び出す。

static void call_functions(kz_syscall_type_t type, kz_syscall_param_t *p)
{
  switch (type) {
  case KZ_SYSCALL_TYPE_RUN: /* kz_run() */
    p->un.run.ret = thread_run(p->un.run.func, p->un.run.name,
			       p->un.run.priority, p->un.run.stacksize,
			       p->un.run.argc, p->un.run.argv);
    break;
  case KZ_SYSCALL_TYPE_WAIT: /* kz_wait() */
    p->un.wait.ret = thread_wait();
    break;
  ....
}

関連記事

コメント

  1. この記事へのコメントはありません。

  1. この記事へのトラックバックはありません。

スポンサード リンク

カテゴリー

スポンサード リンク