2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[ETロボコン] 次のコンテストに向けて技術的備忘録その1(準備~μITRON編)

Last updated at Posted at 2020-10-30

はじめに

ETロボコン2020年に恵庭戦隊トシキングで参加してた人です.
技術的に振り返りたいと思ったので記事を書いてます.また,来年度にむけて設計意図を忘れないよう備忘録としても活用します.
間違っている部分も多いと思いますが,見る方は暖かい目で見ていただけると幸いです.
ここでは,準備からμITRONの使い方を自分なりに説明しています.他はでき次第随時上げていきます・・・
アーキテクチャ編
コード全体はこちら

開発環境

  • WSL1 (Windows 10)
  • C/C++ (std=c++03)

開発準備の攻略

今年は公式(1)からシミュレータ(2)が配布されていたので,手順通りに構築してます.
去年と違ってほぼ自動だったのでとても楽ですね.

参考文献
(1) ETロボコン2020
(2) etrobo all-in-one installer/builder/launcher environment

μITRON4.0の攻略

μITRON4.0の仕様書(1)と講演会資料(2)を参考にしながら攻略していきます.1

リアルタイムオペレーティングシステム(リアルタイムOS)と聞きなれない用語が出てきますが,肝心な部分はタスク・優先度・周期ハンドラあたりを理解できれば使えるかと思います.
次に,この3つを軽く説明していきます.

μITRON4.0におけるタスク・優先度・周期ハンドラ

タスクの状態は(1)の3章2節1項内に記載されている図を抜粋します.

まず,重要なのはタスクを生成(登録)して休止状態にすることです.基本的にETロボコンでは,起動時にすべてのタスクを休止状態にしておくと生成・削除でリソースを気にする必要はなくなります.どうしてもリソース(主にメモリ)が足りないときは未登録状態を活用すればよいかと.
個人的に理想なタスクの状態遷移は休止->実行可能->実行->休止のサイクルです.複数タスクを定義するとどうしてもこの理想なサイクルにはならなくなりますが,この問題をタスクの優先度を使って解決していきます.

優先度は,実行可能状態から実行状態に移すとき,タスクに持たせることができる変数です.この変数があると,優先度の一番高いタスクは休止->実行可能->実行->休止のサイクルを保ちやすくなります.2

周期ハンドラでは,各タスクを一定周期で起動しています3.この機能により,タスク内では,いわゆるループ文(for, while)を書くことが少なくなります.
なので,不用意に時間のかかるループ文を書いてしまったり,FILEのI/Oを周期内に書いてしまうと予期せぬエラーや動作が不安定に・・・
周期ハンドラは慣れないとどこがループしているのか気づきずらくなるので公式のサンプル(3)を改造してみるのがいいです.
例示で恵庭戦隊トシキングのコード(4)を載せておくと.

app.cfg

INCLUDE("app_common.cfg");

# include "app.h"

// 休止状態のタスクを定義
DOMAIN(TDOM_APP) {
CRE_TSK( SETUP_GAME_TASK,
  { TA_NULL,  0, setup_game_task,   SETUP_GAME_PRIORITY,   STACK_SIZE, NULL });
CRE_TSK( GAME_STATE_MANAGER_TASK,
  { TA_NULL,  0, game_state_manager_task, GAME_STATE_MANAGER_PRIORITY, STACK_SIZE*8, NULL });

// 周期ハンドラを定義
CRE_CYC( SETUP_GAME_CYC,
  { TA_STA, { TNFY_ACTTSK, SETUP_GAME_TASK}, 100*1000, 1*1000});
CRE_CYC( GAME_STATE_MANAGER_CYC, 
  { TA_NULL, { TNFY_ACTTSK, GAME_STATE_MANAGER_TASK}, 20*1000, 1*1000});

ATT_MOD("app.o");

app.h

# ifdef __cplusplus
extern "C" {
# endif

# include "ev3api.h"

# define SETUP_GAME_PRIORITY (TMIN_APP_TPRI + 1)
# define GAME_STATE_MANAGER_PRIORITY (TMIN_APP_TPRI + 2)

# ifndef STACK_SIZE
# define STACK_SIZE      (512)
# endif /* STACK_SIZE */

# ifndef TOPPERS_MACRO_ONLY

    extern void setup_game_task(intptr_t exinf);
    extern void setup_game_cyc(intptr_t exinf);
    extern void game_state_manager_task(intptr_t exinf);
    extern void game_state_manager_cyc(intptr_t exinf);

# endif /* TOPPERS_MACRO_ONLY */

# ifdef __cplusplus
}
# endif

app.cpp

// 200 msec loop
void setup_game_task(intptr_t exinf)
{
  d.init("Ready");
  if (setupGame.isStarted())
  {
    gameStateManager.init();
    sta_cyc(GAME_STATE_MANAGER_CYC);
  }

  if (ev3_button_is_pressed(LEFT_BUTTON))
  {
    snprintf(syslogBuf, sizeof(syslogBuf), "push left button:stop ev3");
    syslog(LOG_NOTICE, syslogBuf);
    stp_cyc(SETUP_GAME_CYC);
    stp_cyc(GAME_STATE_MANAGER_CYC);
    gameStateManager.terminate();
  }
  ext_tsk();
}

// 20 msec loop
void game_state_manager_task(intptr_t exinf)
{
  gameStateManager.manageGameState();
  ext_tsk();
}

まとめると

  • リソースに余裕があるなら,最初にタスクは定義して休止状態にしてあげる
  • 理想は休止->実行可能->実行->休止のサイクル
  • 実行可能から実行の間には優先度でタスクの順位付けをしてあげる4
  • 周期ハンドラは実質ループ(for, while)文とみなす
  • タスク内の処理は(for, while)文を少なくして計算量を多くしない

その他タスクの定義方法や使い方についてはTOPPERSのFAQ(1)を見てみると理解が進むかもしれません.
参考文献
(1) ITRON仕様書 ホワイトペーパー
(2) 講演会テキスト
(3) sample_c4
(4) 恵庭戦隊トシキングのコード

さいごに

次は,アーキテクチャの設計意図についてまとめる予定です.
app.cfgの引数についてより知りたい方が多ければスピンオフで作るかもしれないです.

  1. ちなみにμITRONはMicro Industrial TRONです.

  2. 実際にはタスクの処理時間なども関係してくるので,絶対保てるとは言えません.特に周期ハンドラが絡んだ実行となるとなおわかりずらいです.

  3. この起動するとは、μITRONでは休止状態から実行可能状態に移行することです.

  4. ディスパッチ(dispatch ):タスクを処理の実行,プリエンプト(preemption):実行状態を一旦止める

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?