C2A_Core
command_dispatcher.c
[詳解]
1 #pragma section REPRO
6 #include "command_dispatcher.h"
8 #include "../System/TimeManager/time_manager.h"
9 #include "../System/EventManager/event_logger.h"
10 #include "packet_handler.h"
11 
12 // TODO: 本当は,不正な CDISは pl == NULL などにしておくのが良さそうだが,
13 // 現状 PL が NULL チェックをしてないので,できない
14 
20 typedef enum
21 {
26 
32 static void CDIS_clear_exec_info_(CDIS_ExecInfo* exec_info);
33 
34 
36 {
37  CommandDispatcher cdis;
38  static uint8_t init_counter = 0;
39 
40  cdis.idx = init_counter;
41  init_counter++;
42 
43  // コマンド実行情報を初期化
46 
47  // 実行エラーカウンタを0に初期化
48  cdis.error_counter = 0;
49 
50  // 実行中断フラグを無効に設定
51  cdis.lockout = 0;
52 
53  // 異常時実行中断フラグを無効に設定
54  cdis.stop_on_error = 0;
55 
56  // 処理対象とするPacketListをクリアして登録
57  if (pl == NULL)
58  {
59  // 初期化時エラーは試験時に確認され,打ち上げ後はありえないので,イベント発行のみしかしない
63  0);
64  return cdis;
65  }
67  {
68  // 初期化時エラーは試験時に確認され,打ち上げ後はありえないので,イベント発行のみしかしない
72  (uint32_t)pl);
73  return cdis;
74  }
75  PL_clear_list(pl);
76  cdis.pl = pl;
77 
78  return cdis;
79 }
80 
81 
82 static void CDIS_clear_exec_info_(CDIS_ExecInfo* exec_info)
83 {
84  OBCT_clear(&(exec_info->time));
85  exec_info->code = (CMD_CODE)0;
87 }
88 
89 
91 {
92  static CommonCmdPacket packet_; // パケットコピー用.サイズが大きいため静的変数として宣言
93 
94  // 実行有効フラグが無効化されている場合は処理打ち切り
95  if (cdis->lockout) return;
96 
97  // 実行すべきコマンドが無い場合は処理終了
98  if (cdis->pl == NULL) return; // TODO: PL 側で NULL チェックに対応したら消す
99  if (PL_is_empty(cdis->pl)) return;
100 
101  if (cdis->prev.cmd_ret.exec_sts != CCP_EXEC_SUCCESS)
102  {
103  // 直前コマンドが異常終了した場合は実行前に情報を保存
104  // 実行前にコピーすることで次コマンドが異常終了した場合は
105  // prev と prev_err で2コマンド分の異常情報を保持できる
106  cdis->prev_err = cdis->prev;
107  }
108 
109  // 実行すべきコマンドパケットを取得
110  packet_ = *(const CommonCmdPacket*)(PL_get_head(cdis->pl)->packet);
111 
112  // ここで実行種別を変更するのをやめた.
113  // - MOBCから配送される第二OBCにも,GS cmdやTL cmdを送信したいため
114  // - user_packet_handler での PH_user_cmd_router の dispatcher (AOBC_dispatch_command など) にて
115  // 第二OBCが受けたいコマンド種別へと変換させる.
116  /*
117  // 実行時は全てのコマンドの実行種別をRealTimeに設定する。
118  // タイムラインはここでリアルタイムに変換される。
119  // この処理は特に複数機器でパケットルーティングを行う場合重要。
120  // 普通はルーティング先はルーティング元のタイムラインを受け付けないはず。
121  CCP_set_exec_type(&packet_, CCP_EXEC_TYPE_RT);
122  */
123 
124  // 実行時情報を記録しつつコマンドを実行
125  cdis->prev.time = TMGR_get_master_clock();
126  cdis->prev.code = CCP_get_id(&packet_);
127  cdis->prev.cmd_ret = PH_dispatch_command(&packet_);
128 
129  // 実行したコマンドをリストから破棄
130  PL_drop_executed(cdis->pl);
131 
132  if (cdis->prev.cmd_ret.exec_sts != CCP_EXEC_SUCCESS)
133  {
134  uint32_t note;
135  // 実行時エラー情報をELにも記録. エラー発生場所(GSCD,TLCDなど)は cdis の idx で区別
136  // より重要な EL_CORE_GROUP_CDIS_EXEC_ERR_STS があとに来るように EL 発行
138  (uint32_t)cdis->prev.code,
140  cdis->prev.cmd_ret.err_code);
141  note = ((0X000000ff & cdis->idx) << 24)
142  | ((0x000000ff & cdis->prev.cmd_ret.exec_sts) << 16)
143  | (0x0000ffff & cdis->prev.cmd_ret.err_code);
145  (uint32_t)cdis->prev.code,
147  note);
148 
149  // 実行したコマンドが実行異常ステータスを返した場合
150  // エラー発生カウンタをカウントアップ
151  ++(cdis->error_counter);
152 
153  if (cdis->stop_on_error == 1)
154  {
155  // 異常時実行中断フラグが有効な場合
156  // 実行許可フラグを無効化し以降の実行を中断
157  cdis->lockout = 1;
158  }
159  }
160 }
161 
162 
164 {
165  // 保持しているリストの内容をクリア
166  if (cdis->pl == NULL) return; // TODO: PL 側で NULL チェックに対応したら消す
167  PL_clear_list(cdis->pl);
168 }
169 
170 
172 {
173  // 実行エラー状態を初期状態に復元
175 
176  // 積算エラー回数を0クリア
177  cdis->error_counter = 0;
178 }
179 
180 #pragma section
コマンド定義
void CDIS_clear_command_list(CommandDispatcher *cdis)
CDIS に登録されているコマンドキューからコマンドを削除
CDIS_EL_LOCAL_ID
CDIS 内部の event の local ID
@ CDIS_EL_LOCAL_ID_NULL_PARAM
NULL 引数
@ CDIS_EL_LOCAL_ID_UNKNOWN
@ CDIS_EL_LOCAL_ID_INVALID_PL
不正な PL
CommandDispatcher CDIS_init(PacketList *pl)
CDIS の初期化と取得
void CDIS_dispatch_command(CommandDispatcher *cdis)
CDIS に登録されているコマンドキューからコマンドを実行
static void CDIS_clear_exec_info_(CDIS_ExecInfo *exec_info)
CDIS_ExecInfo の初期化
void CDIS_clear_error_status(CommandDispatcher *cdis)
CDIS に登録されているコマンドキューのコマンド実行エラー情報を削除
各種コマンドの実行管理
@ CCP_EXEC_SUCCESS
CMD_CODE CCP_get_id(const CommonCmdPacket *packet)
CMD ID を取得
CCP_CmdRet CCP_make_cmd_ret_without_err_code(CCP_EXEC_STS exec_sts)
コマンド返り値である CCP_CmdRet を作成(エラーコード不使用版)
EL_ACK EL_record_event(EL_GROUP group, uint32_t local, EL_ERROR_LEVEL err_level, uint32_t note)
イベント (EL_Event) を記録
Definition: event_logger.c:269
@ EL_CORE_GROUP_CDIS_INTERNAL_ERR
Definition: event_logger.h:218
@ EL_CORE_GROUP_CDIS_EXEC_ERR_STS
Definition: event_logger.h:219
@ EL_CORE_GROUP_CDIS_EXEC_ERR_CODE
Definition: event_logger.h:220
@ EL_ERROR_LEVEL_HIGH
Definition: event_logger.h:262
@ EL_ERROR_LEVEL_LOW
Definition: event_logger.h:266
EL_GROUP
event_logger の Event Group の user 定義部分
void OBCT_clear(ObcTime *time)
ObcTime をクリアし全てゼロにする
Definition: obc_time.c:23
CCP_CmdRet PH_dispatch_command(const CommonCmdPacket *packet)
CCP をコマンドとして解釈して実行,ないしは別機器へ配送する
C2A 全体を流れる Common Packet の配送を制御する
void PL_clear_list(PacketList *pl)
PacketList をクリア
Definition: packet_list.c:69
PL_PACKET_TYPE PL_get_packet_type(const PacketList *pl)
PacketList で使用される packet の型情報 PL_PACKET_TYPE を返す
Definition: packet_list.c:131
const PL_Node * PL_get_head(const PacketList *pl)
PacketList の active な先頭 Node を取得
Definition: packet_list.c:150
PL_ACK PL_drop_executed(PacketList *pl)
先頭 Node を落とす
Definition: packet_list.c:236
int PL_is_empty(const PacketList *pl)
PacketList が空かどうか
Definition: packet_list.c:138
@ PL_PACKET_TYPE_CCP
CommonCmdPacket
Definition: packet_list.h:29
uint32_t err_code
各 Cmd ユニークなエラーコード.各 App で定義する enum などを入れることを想定.
CCP_EXEC_STS exec_sts
CCP_EXEC_STS.Cmd の統一的なエラーコード
コマンド実行情報
CMD_CODE code
実行コマンドID
CCP_CmdRet cmd_ret
実行結果
ObcTime time
実行時刻
Space Packet (コマンド用)
CommandDispatcher の Info 構造体
uint8_t idx
CDIS のインデックス. EL で用いる
int stop_on_error
異常時実行中断フラグ
CDIS_ExecInfo prev_err
最後にエラーが出たコマンド実行情報
int lockout
実行中断フラグ
uint32_t error_counter
エラーカウンタ
CDIS_ExecInfo prev
前回のコマンド実行情報
PacketList * pl
コマンドキュー
void * packet
片方向リストに格納される packet. どのような型でも良いように, void.(基本的には CTCP, CTP, CCP を想定)
Definition: packet_list.h:60
パケットリスト本体
Definition: packet_list.h:73
ObcTime TMGR_get_master_clock(void)
現在の master_clock_ を取得する
Definition: time_manager.c:80