Zig版ASP3カーネルのCRE_TSK
こんにちは、めのんです!
Zig版ASP3カーネルについては木曜日以来ですね。 ずっとこのブログを読んでくださっている方でも、数日間を空けると忘却の彼方かもしれませんのでリンクを貼っておきますね。
前回は静的APIについてZeig版ASP3カーネルのコードをざっと眺めたところで終わっていました。 今回は静的APIの代表格であるCRE_TSKについて、もう少し深掘りしていくことにしましょう!
静的APIそのものの定義はkernel/static_api.zigにあります。 その中のCRE_TSKに関する部分はここです。
// タスクの生成 pub fn CRE_TSK(comptime p_self: *CfgData, comptime tsk_name: []const u8, comptime ctsk: T_CTSK) void { comptime var p_tsk = addItem(T_TSK, &p_self.tsk_list); p_tsk.name = tsk_name; p_tsk.inib = comptime task.cre_tsk(ctsk) catch |err| reportError("CRE_TSK", err); }
この関数は無名構造体の中に定義されていますが、その無名構造体はCfgDataという定数を初期化するのに使われています。
CRE_TSK関数の引数を順に見ていくと、1番目の引数であるp_selfはCfgData自信へのポインタですね。
Zigでは仮引数の型はコロンに続けて後ろに書くんでした。 また、ポインタ型はCとは違って*を前に書きます。 前後がCとはすっかり逆になっていますね。
2番目の引数tsk_nameはタスク名を文字列として渡します。 Cと同様、Zigの文字列も単なる配列ですが、Cよりはやや扱いやすくなっているように思います。
comptimeというのはコンパイル時という意味で、文字列を定数として扱われるということでしょう。 C++のconstexprと似ているんでしょうか?
task_nameの型は符合無し8ビット整数型の配列です。 Cとは本当に逆順に []const u8 と書かれています。
最後の引数はctskです。 C版のASP3カーネルやμITON 4.0をご存じの型であればおなじみのT_CTSK型になります。 T_CTSK型はinclude/kernel.zigで次のように定義されています。
/// /// パケット形式の定義 /// pub const T_CTSK = struct { tskatr: ATR = TA_NULL, // タスク属性 exinf: EXINF = castToExinf(0), // タスクの拡張情報 task: TASK, // タスクのメインルーチンの先頭番地 itskpri: PRI, // タスクの起動時優先度 stksz: usize, // タスクのスタック領域のサイズ stk: ?[*]u8 = null, // タスクのスタック領域 };
構造体のフィールドの型も、仮引数と同じように後置していますね。
気になるポイントはいくつかあります。 ひとつはexinfです。 これはμITRONではVP_INT型で、void*か整数型をどちらでも格納できる型です。 C版のASP3カーネルではC99から導入されたintptr_t型が使われています。 これに関してはやや複雑ですので今夜に回します。
次にtaskです。 これもC版では関数へのポインタを渡すことになっていましたがZigではどうなっているのか気になります。 これも今夜回しにします。
そしてstkです。 これはスタック領域の配列を渡すのですが、C版であればNULLの場合はカーネルが内部で自動的に領域を割り付けます。 型も複雑で?[*]u8となっていますね。 これは、8ビット符合無し整数型の任意の長さの配列またはnullを渡せるということだと思います。
先頭に?を付けるとnullableになるようです。 C#やPHPではうしろに?を付けましたし、PHPはZigと同様に前に?を付けます。 言語によっていろいろなので混乱してしまいそうです。
ここまでで随分長くなってしまいましたので、続きは今夜の投稿に回したいと思います。
それでは!!