先ほどは以下のサービスを並列に実現する方法を模索しました。
1.LEDを点滅させる
2.1sに1回、液晶パネルに時刻表示を行う
3.シリアルからのコマンドに応答する
実行する処理をサービスの単位で区切ってみることにします。というか既に3つに区切られていますが。。
これらのサービス単位をここではタスクと呼ぶことにします。
また、キーワードになっているスレッドについてです。
プログラムをタスクごとに独立して動作するできるようにする仕組みをスレッドと呼ぶようです。
具体的に独立しているとは以下のようなプログラム実装イメージができることのようです。
たしかに【問題点】の内容は実装イメージ中には含まれていないようです。
①他の機能へ処理を明け渡すために、時間のかかる処理に対して中断・再開といった記述を追加する必要がある。
②プログラムが複雑化するとバグが出やすくなる。要はメインの処理に集中しにくくなる。
本番の実装が楽しみです。
int main()
{
....kz_start(start_threads,...);
....return 0;
}
int start_threads()
{
....kz_run(led_main,"led",1,...);
....kz_run(timer_main,"timer",2,...);
....kz_run(command_main,"command",3,...);
....while(1)
....{
....asm volatile("sleep");
....}
....return 0;
}
int led_main()
{
....while(1)
....{
........kz_recv(...);
........led_turn();
....}
}
int timer_main()
{
....while(1)
....{
........kz_recv(...);
........write_time();
....}
}
int command_main()
{
....while(1)
....{
........kz_recv(...);
........command_exec();
....}
}
【関数ごとに方向性の内容確認】
・kz_run()
スレッドを生成します。
引数として関数のポインタを渡すとスレッドを作成し、その関数の実行を開始します。引数には他にスレッド名、スレッドのスタックサイズなどを渡します。
戻り値は、生成したスレッドID番号です。これをスレッドIDと呼ぶことにします。
・kz_start()
最初のスレッド(初期スレッド)を生成します。
スレッド生成はkz_run()で行いますが、これはシステムコールであるためスレッドからしか実行できません。そのためひとつめのスレッドを「スレッド生成用スレッド」としてkz_start()で生成し、そのスレッドからkz_run()によって本来必要なスレッドを生成していきます。またこの「スレッド生成用スレッド」を今後は「初期スレッド」と呼ぶことにします。引数の意味はkz_run()と同じです。
スレッド生成後はそのスレッドの動作に入るので、この関数が戻ってくることはありません。このため戻り地はなしにしています。
1.LEDを点滅させる
2.1sに1回、液晶パネルに時刻表示を行う
3.シリアルからのコマンドに応答する
実行する処理をサービスの単位で区切ってみることにします。というか既に3つに区切られていますが。。
これらのサービス単位をここではタスクと呼ぶことにします。
また、キーワードになっているスレッドについてです。
プログラムをタスクごとに独立して動作するできるようにする仕組みをスレッドと呼ぶようです。
具体的に独立しているとは以下のようなプログラム実装イメージができることのようです。
たしかに【問題点】の内容は実装イメージ中には含まれていないようです。
①他の機能へ処理を明け渡すために、時間のかかる処理に対して中断・再開といった記述を追加する必要がある。
②プログラムが複雑化するとバグが出やすくなる。要はメインの処理に集中しにくくなる。
本番の実装が楽しみです。
int main()
{
....kz_start(start_threads,...);
....return 0;
}
int start_threads()
{
....kz_run(led_main,"led",1,...);
....kz_run(timer_main,"timer",2,...);
....kz_run(command_main,"command",3,...);
....while(1)
....{
....asm volatile("sleep");
....}
....return 0;
}
int led_main()
{
....while(1)
....{
........kz_recv(...);
........led_turn();
....}
}
int timer_main()
{
....while(1)
....{
........kz_recv(...);
........write_time();
....}
}
int command_main()
{
....while(1)
....{
........kz_recv(...);
........command_exec();
....}
}
【関数ごとに方向性の内容確認】
・kz_run()
スレッドを生成します。
引数として関数のポインタを渡すとスレッドを作成し、その関数の実行を開始します。引数には他にスレッド名、スレッドのスタックサイズなどを渡します。
戻り値は、生成したスレッドID番号です。これをスレッドIDと呼ぶことにします。
・kz_start()
最初のスレッド(初期スレッド)を生成します。
スレッド生成はkz_run()で行いますが、これはシステムコールであるためスレッドからしか実行できません。そのためひとつめのスレッドを「スレッド生成用スレッド」としてkz_start()で生成し、そのスレッドからkz_run()によって本来必要なスレッドを生成していきます。またこの「スレッド生成用スレッド」を今後は「初期スレッド」と呼ぶことにします。引数の意味はkz_run()と同じです。
スレッド生成後はそのスレッドの動作に入るので、この関数が戻ってくることはありません。このため戻り地はなしにしています。