C2A_Core
divided_cmd_utility.c
[詳解]
1 #pragma section REPRO
14 #include "divided_cmd_utility.h"
15 #include "../TlmCmd/packet_handler.h"
16 #include "../TlmCmd/common_cmd_packet_util.h"
17 #include "../System/TimeManager/time_manager.h"
18 #include "../System/EventManager/event_logger.h"
19 
25 static void DCU_init_(void);
26 
32 static void DCU_clear_log_(void);
33 
40 static void DCU_clear_log_element_(uint8_t log_idx, CMD_CODE cmd_code);
41 
50 static DCU_LOG_ACK DCU_search_log_(CMD_CODE cmd_code, uint8_t* log_idx, uint8_t* sort_key);
51 
58 static void DCU_move_to_front_in_log_(CMD_CODE cmd_code);
59 
67 static void DCU_create_log_on_front_(CMD_CODE cmd_code);
68 
69 
72 
74 
75 
77 {
78  return AI_create_app_info("divided_cmd_utility", DCU_init_, NULL);
79 }
80 
81 
82 static void DCU_init_(void)
83 {
85 }
86 
87 
88 static void DCU_clear_log_(void)
89 {
90  uint8_t i;
91  for (i = 0; i < DCU_LOG_MAX; ++i)
92  {
95  }
96 }
97 
98 
99 static void DCU_clear_log_element_(uint8_t log_idx, CMD_CODE cmd_code)
100 {
101  divided_cmd_utility_.exec_logs[log_idx].cmd_code = cmd_code;
106 }
107 
108 
109 static DCU_LOG_ACK DCU_search_log_(CMD_CODE cmd_code, uint8_t* log_idx, uint8_t* sort_key)
110 {
111  uint8_t i;
112  *log_idx = 0;
113  *sort_key = 0;
114 
115  for (i = 0; i < DCU_LOG_MAX; ++i)
116  {
117  uint8_t idx = divided_cmd_utility_.exec_log_order[i];
118  if (divided_cmd_utility_.exec_logs[idx].cmd_code == cmd_code)
119  {
120  *log_idx = idx;
121  *sort_key = i;
122  return DCU_LOG_ACK_OK;
123  }
124  }
125 
126  return DCU_LOG_ACK_NOT_FOUND;
127 }
128 
129 
130 static void DCU_move_to_front_in_log_(CMD_CODE cmd_code)
131 {
132  uint8_t i;
133  uint8_t log_idx;
134  uint8_t sort_key;
135  DCU_LOG_ACK log_ret = DCU_search_log_(cmd_code, &log_idx, &sort_key);
136 
137  if (log_ret == DCU_LOG_ACK_NOT_FOUND)
138  {
139  // ログがないので作る
140  DCU_create_log_on_front_(cmd_code);
141  return;
142  }
143 
144  for (i = sort_key; i > 0; --i)
145  {
147  }
149 }
150 
151 
152 static void DCU_create_log_on_front_(CMD_CODE cmd_code)
153 {
154  uint8_t i;
155  uint8_t idx;
156 
157  // 最も古いログを取得
160  {
162  (uint32_t)divided_cmd_utility_.exec_logs[idx].cmd_code,
165  }
166 
167  for (i = (DCU_LOG_MAX - 1); i > 0; --i)
168  {
170  }
172 
173  DCU_clear_log_element_(idx, cmd_code);
174 }
175 
176 
177 DCU_STATUS DCU_check_in(CMD_CODE cmd_code, uint16_t* exec_counter)
178 {
179  uint8_t idx;
180  DCU_STATUS status;
181 
182  DCU_move_to_front_in_log_(cmd_code);
183  idx = divided_cmd_utility_.exec_log_order[0]; // 自身のログidx,つまり最も新しいログidxを拾う
184  status = divided_cmd_utility_.exec_logs[idx].status;
185 
186  if (status == DCU_STATUS_FINISHED)
187  {
188  DCU_clear_log_element_(idx, cmd_code);
189  }
190  else if (status == DCU_STATUS_PROGRESS)
191  {
193  }
194  else
195  {
196  // なにもしない
197  }
198 
200  *exec_counter = divided_cmd_utility_.exec_logs[idx].exec_counter;
201  return status;
202 }
203 
204 
205 DCU_ACK DCU_register_next(CMD_CODE cmd_code, const uint8_t* param, uint16_t len)
206 {
207  uint8_t idx;
208  CCP_UTIL_ACK ret;
209 
210  DCU_move_to_front_in_log_(cmd_code);
213 
214  ret = CCP_form_rtc(&DCU_packet_, cmd_code, param, len);
215  if (ret != CCP_UTIL_ACK_OK) return DCU_ACK_ERR;
217  {
218  return DCU_ACK_ERR;
219  }
220 
221  return DCU_ACK_OK;
222 }
223 
224 
225 void DCU_report_finish(CMD_CODE cmd_code, CCP_EXEC_STS last_exec_sts)
226 {
227  uint8_t idx;
228 
229  DCU_move_to_front_in_log_(cmd_code);
231 
233  divided_cmd_utility_.exec_logs[idx].last_exec_sts = last_exec_sts;
234 }
235 
236 
237 void DCU_report_err(CMD_CODE cmd_code, CCP_EXEC_STS last_exec_sts)
238 {
239  uint8_t idx;
240 
241  DCU_move_to_front_in_log_(cmd_code);
243 
245  divided_cmd_utility_.exec_logs[idx].last_exec_sts = last_exec_sts;
246 }
247 
248 
250 {
251  uint8_t idx;
252 
253  DCU_move_to_front_in_log_(cmd_code);
255 
256  DCU_clear_log_element_(idx, cmd_code);
257 }
258 
259 
260 void DCU_abort_cmd(CMD_CODE cmd_code)
261 {
262  uint8_t idx;
263 
264  DCU_move_to_front_in_log_(cmd_code);
266 
268 }
269 
270 
272 {
273  uint8_t log_idx;
274  uint8_t sort_key;
275  DCU_LOG_ACK log_ret = DCU_search_log_(cmd_code, &log_idx, &sort_key);
276 
277  if (log_ret == DCU_LOG_ACK_NOT_FOUND)
278  {
279  return DCU_LOG_ACK_NOT_FOUND;
280  }
281 
282  exec_log = &divided_cmd_utility_.exec_logs[log_idx];
283  return DCU_LOG_ACK_OK;
284 }
285 
286 
288 {
289  // CMD_CODE は u16 と想定する
290  CMD_CODE target_cmd = (CMD_CODE)CCP_get_param_from_packet(packet, 0, uint16_t);
291 
292  DCU_abort_cmd(target_cmd);
293 
295 }
296 
297 
299 {
300  // CMD_CODE は u16 と想定する
301  CMD_CODE target_cmd = (CMD_CODE)CCP_get_param_from_packet(packet, 0, uint16_t);
302 
303  DCU_donw_abort_flag(target_cmd);
304 
306 }
307 
308 
310 {
311  (void)packet;
312 
313  DCU_clear_log_();
314 
316 }
317 
318 #pragma section
AppInfo AI_create_app_info(const char *name, void(*initializer)(void), void(*entry_point)(void))
AppInfo を作る
Definition: app_info.c:9
@ Cmd_CODE_MAX
CCP_EXEC_STS
コマンド実行結果コード
@ CCP_EXEC_SUCCESS
CCP_CmdRet CCP_make_cmd_ret_without_err_code(CCP_EXEC_STS exec_sts)
コマンド返り値である CCP_CmdRet を作成(エラーコード不使用版)
CCP_UTIL_ACK CCP_form_rtc(CommonCmdPacket *packet, CMD_CODE cmd_id, const uint8_t *param, uint16_t len)
Realtime command を生成
CCP_UTIL_ACK
CCP Utility の汎用返り値
@ CCP_UTIL_ACK_OK
正常終了
#define CCP_get_param_from_packet(packet, n, type)
CCP packet から,n番目のコマンド引数を取得する
void DCU_abort_cmd(CMD_CODE cmd_code)
実行中の分割コマンドを外部から強制的に中断させる
static void DCU_move_to_front_in_log_(CMD_CODE cmd_code)
該当コマンドのログを,ログの先頭に出す
static void DCU_clear_log_(void)
ログクリア
void DCU_report_err(CMD_CODE cmd_code, CCP_EXEC_STS last_exec_sts)
DCUに,途中でエラーが発生したことを伝える
CCP_CmdRet Cmd_DCU_ABORT_CMD(const CommonCmdPacket *packet)
実行中の分割コマンドを停止する
static DCU_LOG_ACK DCU_search_log_(CMD_CODE cmd_code, uint8_t *log_idx, uint8_t *sort_key)
該当コマンドのログを検索し取得する
CCP_CmdRet Cmd_DCU_CLEAR_LOG(const CommonCmdPacket *packet)
ログをクリアする
static CommonCmdPacket DCU_packet_
DCU_ACK DCU_register_next(CMD_CODE cmd_code, const uint8_t *param, uint16_t len)
次の分割の実行を登録
const DividedCmdUtility *const divided_cmd_utility
AppInfo DCU_create_app(void)
static DividedCmdUtility divided_cmd_utility_
void DCU_donw_abort_flag(CMD_CODE cmd_code)
エラー,またはコマンドによって中断ステータスとなっているコマンドを,実行可能状態に戻す
static void DCU_create_log_on_front_(CMD_CODE cmd_code)
先頭に該当コマンドのログをつくる
DCU_STATUS DCU_check_in(CMD_CODE cmd_code, uint16_t *exec_counter)
DCUにチェックインする.分割コマンド実行時,最初に呼び出す関数.
DCU_LOG_ACK DCU_search_and_get_log(CMD_CODE cmd_code, const DCU_ExecStatus *exec_log)
ログを探して,指定したコマンドログを取得する
CCP_CmdRet Cmd_DCU_DOWN_ABORT_FLAG(const CommonCmdPacket *packet)
エラー,またはコマンドによって中断ステータスとなっているコマンドを,実行可能状態に戻す
void DCU_report_finish(CMD_CODE cmd_code, CCP_EXEC_STS last_exec_sts)
DCUに,分割コマンドが実行終了したことを伝える
static void DCU_clear_log_element_(uint8_t log_idx, CMD_CODE cmd_code)
ログクリア(1要素)
static void DCU_init_(void)
App初期化関数
コマンド分割をサポートするUtil
#define DCU_LOG_MAX
保存するログの最大数
DCU_LOG_ACK
ログ操作の返り値
@ DCU_LOG_ACK_NOT_FOUND
指定ログが見つからず
@ DCU_LOG_ACK_OK
正常終了
DCU_ACK
汎用返り値
@ DCU_ACK_OK
正常終了
@ DCU_ACK_ERR
エラー
DCU_STATUS
実行状況
@ DCU_STATUS_ABORTED_BY_ERR
エラーにより中断
@ DCU_STATUS_PROGRESS
実行中
@ DCU_STATUS_ABORTED_BY_CMD
コマンドにより中断
@ DCU_STATUS_FINISHED
実行終了 or 未実行
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_DCU
Definition: event_logger.h:213
@ EL_ERROR_LEVEL_HIGH
Definition: event_logger.h:262
EL_GROUP
event_logger の Event Group の user 定義部分
ObcTime OBCT_create(cycle_t total_cycle, cycle_t mode_cycle, step_t step)
引数から ObcTime を作成する
Definition: obc_time.c:10
PH_ACK PH_analyze_cmd_packet(const CommonCmdPacket *packet)
CCP を解析する
@ PH_ACK_SUCCESS
OK
コマンド返り値
Space Packet (コマンド用)
CMD_CODE cmd_code
実行コマンド
ObcTime last_exec_time
最終実行時刻
CCP_EXEC_STS last_exec_sts
最終実行結果
uint16_t exec_counter
実行カウンタ.何度目の実行か?
DCU_STATUS status
実行状況
DividedCmdUtility の AppInfo 構造体
DCU_ExecStatus exec_logs[DCU_LOG_MAX]
実行ログ.[exec_log_order[0]] が最も新しい.古いものは捨てられていく.
uint8_t exec_log_order[DCU_LOG_MAX]
実行ログのソートキー. exec_logs を最新順に並べ替えるために使う.
ObcTime TMGR_get_master_clock(void)
現在の master_clock_ を取得する
Definition: time_manager.c:80