C2A_Core
block_command_executor.c
[詳解]
1 #pragma section REPRO
11 #include <string.h>
12 
13 #include "block_command_executor.h"
14 #include "packet_handler.h"
15 #include "../Library/endian.h"
16 #include "../System/TimeManager/time_manager.h"
17 #include "common_cmd_packet_util.h"
18 
20 
23 
24 // default (SRAM, 冗長無し) の getter, setter
26 static void BCE_set_bc_exe_params_default_(const bct_id_t block, const BCE_Params* bc_exe_params);
27 
28 // BlockCmdExeFunc をラップした static getter, setter
29 // static であるので,const をつけていない
30 // user 実装次第では,三重冗長化された不揮発メモリ上の BCT を扱う可能性もあるため,
31 // 取得したポインタを介して値を更新した場合, setter を呼び出す.
32 // block の引数アサーションはしていない
33 static BCE_Params* BCE_get_bc_exe_params_(const bct_id_t block);
34 static void BCE_set_bc_exe_params_(const bct_id_t block, const BCE_Params* bc_exe_params);
35 
44 
52 
61 
68 {
70 }
71 
72 static void BCE_set_bc_exe_params_default_(const bct_id_t block, const BCE_Params* bc_exe_params)
73 {
74  if ((unsigned char*)block_command_executor_.bc_exe_params[block] == (const unsigned char*)bc_exe_params) return;
75  memcpy(block_command_executor_.bc_exe_params[block], bc_exe_params, sizeof(BCE_Params));
76 }
77 
78 static void BCE_set_bc_exe_params_(const bct_id_t block, const BCE_Params* bc_exe_params)
79 {
80  block_command_executor_.bc_exe_func[block].set_bc_exe_params_(block, bc_exe_params);
81 }
82 
84 {
86 }
87 
89 {
91 }
92 
94 {
95  bct_id_t block;
96  for (block = 0; block < BCT_MAX_BLOCKS; ++block)
97  {
100  }
101 }
102 
104 {
105  BCE_Params* bc_exe_params;
106  if (block >= BCT_MAX_BLOCKS) return BCT_INVALID_BLOCK_NO;
107 
108  bc_exe_params = BCE_get_bc_exe_params_(block);
109  bc_exe_params->is_active = 0;
110  BCE_set_bc_exe_params_(block, bc_exe_params);
111 
112  BCE_reset_rotator_info(block);
114 
115  return BCT_SUCCESS;
116 }
117 
119 {
120  BCT_ACK ack;
121  (void)packet;
122 
123  ack = BCE_activate_block();
124 
126 }
127 
129 {
131  BCE_Params* bc_exe_params;
132 
133  if (block >= BCT_MAX_BLOCKS) return BCT_INVALID_BLOCK_NO;
134 
135  bc_exe_params = BCE_get_bc_exe_params_(block);
136 
138  {
139  return BCT_DEFECTIVE_BLOCK;
140  }
141 
142  bc_exe_params->is_active = 1;
143 
144  BCE_set_bc_exe_params_(block, bc_exe_params);
145 
146  return BCT_SUCCESS;
147 }
148 
150 {
151  bct_id_t block;
152  BCT_ACK ack;
153 
154  if (CCP_get_param_len(packet) != SIZE_OF_BCT_ID_T)
155  {
156  // パラメータはブロック番号
158  }
159 
161  ack = BCE_activate_block_by_id(block);
162 
164 }
165 
167 {
168  bct_id_t block;
169  BCT_ACK ack;
170 
171  if (CCP_get_param_len(packet) != SIZE_OF_BCT_ID_T)
172  {
173  // パラメータはブロック番号
175  }
176 
178 
179  ack = BCE_inactivate_block_by_id(block);
180 
182 }
183 
185 {
186  BCE_Params* bc_exe_params;
187 
188  if (block < 0 || block >= BCT_MAX_BLOCKS) return BCT_INVALID_BLOCK_NO;
189 
190  bc_exe_params = BCE_get_bc_exe_params_(block);
191  bc_exe_params->is_active = 1;
192  BCE_set_bc_exe_params_(block, bc_exe_params);
193 
194  return BCT_SUCCESS;
195 }
196 
198 {
199  BCE_Params* bc_exe_params;
200 
201  if (block < 0 || block >= BCT_MAX_BLOCKS) return BCT_INVALID_BLOCK_NO;
202 
203  bc_exe_params = BCE_get_bc_exe_params_(block);
204  bc_exe_params->is_active = 0;
205  BCE_set_bc_exe_params_(block, bc_exe_params);
206 
207  return BCT_SUCCESS;
208 }
209 
211 {
212  bct_id_t block;
213 
214  if (CCP_get_param_len(packet) != SIZE_OF_BCT_ID_T)
215  {
216  // パラメータはブロック番号
218  }
219 
220  // パラメータを読み出し。
222 
223  return BCE_rotate_block_cmd_(block);
224 }
225 
227 {
228  BCE_Params* bc_exe_params;
229  BCT_Pos pos;
230 
232 
233  bc_exe_params = BCE_get_bc_exe_params_(block);
236 
237  ++bc_exe_params->rotate.counter;
238  if (bc_exe_params->rotate.counter < bc_exe_params->rotate.interval)
239  {
240  BCE_set_bc_exe_params_(block, bc_exe_params);
241  return CCP_make_cmd_ret_without_err_code(CCP_EXEC_SUCCESS); // スキップ
242  }
243 
244  bc_exe_params->rotate.counter = 0;
245 
246  ++bc_exe_params->rotate.next_cmd;
247  bc_exe_params->rotate.next_cmd %= BCT_get_bc_length(block);
248 
249  BCE_set_bc_exe_params_(block, bc_exe_params);
250 
251  BCT_make_pos(&pos, block, bc_exe_params->rotate.next_cmd);
252  BCT_load_cmd(&pos, &BCE_packet_);
254 }
255 
257 {
258  bct_id_t block;
259 
260  if (CCP_get_param_len(packet) != SIZE_OF_BCT_ID_T)
261  {
262  // パラメータはブロック番号
264  }
265 
266  // パラメータを読み出し。
268 
269  return BCE_combine_block_cmd_(block);
270 }
271 
273 {
274  uint8_t cmd;
275  uint8_t length;
276 
278 
279  length = BCT_get_bc_length(block);
280 
282 
283  for (cmd = 0; cmd < length; ++cmd)
284  {
285  CCP_CmdRet cmd_ret;
286  BCT_Pos pos;
287 
288  pos.block = block;
289  pos.cmd = cmd;
290  BCT_load_cmd(&pos, &BCE_packet_);
291  cmd_ret = PH_dispatch_command(&BCE_packet_);
292 
293  if (cmd_ret.exec_sts != CCP_EXEC_SUCCESS) return cmd_ret;
294  }
295 
297 }
298 
299 // 2019/10/01 追加
300 // 時間制限付きコンバイナ
301 // (時間が来たら打ち切り.したがって,必ず設定時間はすぎる)
303 {
304  const uint8_t* param = CCP_get_param_head(packet);
305  bct_id_t block;
306  step_t limit_step;
307 
308  if (CCP_get_param_len(packet) != SIZE_OF_BCT_ID_T + 1)
309  {
310  // パラメータはブロック番号 + 制限時間 [step]
312  }
313 
314  // パラメータを読み出し。
315  ENDIAN_memcpy(&block, param, SIZE_OF_BCT_ID_T);
316  limit_step = param[SIZE_OF_BCT_ID_T];
317 
318  return BCE_timelimit_combine_block_cmd_(block, limit_step);
319 }
320 
322 {
323  uint8_t cmd;
324  uint8_t length;
325  BCE_Params* bc_exe_params;
326 
327  ObcTime start = TMGR_get_master_clock();
328  ObcTime finish;
329  step_t diff;
330 
332 
333  bc_exe_params = BCE_get_bc_exe_params_(block);
335 
336  ++bc_exe_params->timelimit_combine.call_num;
337  length = BCT_get_bc_length(block);
338 
339  // TODO:
340  // ↓ちょっとこれ微妙かも...
341  // 値が増えないように,割合が変わらないように適当に下げてる感じ
342  if (bc_exe_params->timelimit_combine.call_num >= 0xFFFF - 16)
343  {
344  bc_exe_params->timelimit_combine.call_num /= 8;
345  bc_exe_params->timelimit_combine.timeover_num /= 8;
346  }
347 
348  for (cmd = 0; cmd < length; ++cmd)
349  {
350  CCP_CmdRet cmd_ret;
351  BCT_Pos pos;
352 
353  pos.block = block;
354  pos.cmd = cmd;
355  BCT_load_cmd(&pos, &BCE_packet_);
356  cmd_ret = PH_dispatch_command(&BCE_packet_);
357 
358  if (cmd_ret.exec_sts != CCP_EXEC_SUCCESS)
359  {
360  BCE_set_bc_exe_params_(block, bc_exe_params);
361  return cmd_ret;
362  }
363 
364  // 時間判定
365  finish = TMGR_get_master_clock();
366  diff = OBCT_diff_in_step(&start, &finish);
367  if (diff >= limit_step)
368  {
369  // 途中で中断
370  ++bc_exe_params->timelimit_combine.timeover_num;
371  bc_exe_params->timelimit_combine.last_timeover_cmd_pos = cmd;
372  if (bc_exe_params->timelimit_combine.last_timeover_cmd_pos < bc_exe_params->timelimit_combine.worst_cmd_pos)
373  {
375  }
376 
377  BCE_set_bc_exe_params_(block, bc_exe_params);
378  return CCP_make_cmd_ret_without_err_code(CCP_EXEC_SUCCESS); // 異常ではないのでこれを返す
379  }
380  }
381 
382  BCE_set_bc_exe_params_(block, bc_exe_params);
383 
384  // 最後まで実行できた
386 }
387 
389 {
390  BCE_Params* bc_exe_params;
391  if (block >= BCT_MAX_BLOCKS) return BCT_INVALID_BLOCK_NO;
392 
393  bc_exe_params = BCE_get_bc_exe_params_(block);
394 
395  bc_exe_params->rotate.counter = 0;
396  bc_exe_params->rotate.interval = 1;
397  bc_exe_params->rotate.next_cmd = 0;
398 
399  BCE_set_bc_exe_params_(block, bc_exe_params);
400 
401  return BCT_SUCCESS;
402 }
403 
405 {
406  BCE_Params* bc_exe_params;
407  if (block >= BCT_MAX_BLOCKS) return BCT_INVALID_BLOCK_NO;
408 
409  bc_exe_params = BCE_get_bc_exe_params_(block);
410 
411  bc_exe_params->timelimit_combine.call_num = 0;
412  bc_exe_params->timelimit_combine.timeover_num = 0;
413  bc_exe_params->timelimit_combine.last_timeover_cmd_pos = 0xFF;
414  bc_exe_params->timelimit_combine.worst_cmd_pos = 0xFF;
415 
416  BCE_set_bc_exe_params_(block, bc_exe_params);
417 
418  return BCT_SUCCESS;
419 }
420 
421 uint8_t BCE_is_active(const bct_id_t block)
422 {
423  if (block >= BCT_MAX_BLOCKS) return 0;
424  return (uint8_t)BCE_get_bc_exe_params(block)->is_active;
425 }
426 
427 BCT_ACK BCE_swap_address(const bct_id_t block_a, const bct_id_t block_b)
428 {
429  BCE_Func tmp_bce_func;
430  BCE_Params* tmp_params_pointer;
431 
432  if (block_a >= BCT_MAX_BLOCKS || block_b >= BCT_MAX_BLOCKS) return BCT_INVALID_BLOCK_NO;
433  if (BCE_is_active(block_a) || BCE_is_active(block_b)) return BCT_DEFECTIVE_BLOCK;
434 
435  tmp_params_pointer = block_command_executor_.bc_exe_params[block_a];
437  block_command_executor_.bc_exe_params[block_b] = tmp_params_pointer;
438 
439  memcpy(&tmp_bce_func, &block_command_executor_.bc_exe_func[block_a], sizeof(BCE_Func));
441  memcpy(&block_command_executor_.bc_exe_func[block_b], &tmp_bce_func, sizeof(BCE_Func));
442 
443  return BCT_SUCCESS;
444 }
445 
446 BCT_ACK BCE_swap_contents(const bct_id_t block_a, const bct_id_t block_b)
447 {
448  BCE_Params* params_a;
449  BCE_Params* params_b;
450  BCE_Params tmp_params;
451 
452  if (block_a >= BCT_MAX_BLOCKS || block_b >= BCT_MAX_BLOCKS) return BCT_INVALID_BLOCK_NO;
453  if (BCE_is_active(block_a) || BCE_is_active(block_b)) return BCT_DEFECTIVE_BLOCK;
454 
455  params_a = BCE_get_bc_exe_params_(block_a);
456  params_b = BCE_get_bc_exe_params_(block_b);
457 
458  memcpy(&tmp_params, params_a, sizeof(BCE_Params));
459  BCE_set_bc_exe_params_(block_a, params_b);
460  BCE_set_bc_exe_params_(block_b, &tmp_params);
461 
462  return BCT_SUCCESS;
463 }
464 
466 {
467  bct_id_t block;
468 
469  if (CCP_get_param_len(packet) != SIZE_OF_BCT_ID_T)
470  {
471  // パラメータはブロック番号
473  }
474 
475  // パラメータを読み出し。
477 
479 }
480 
482 {
483  bct_id_t block;
484 
485  if (CCP_get_param_len(packet) != SIZE_OF_BCT_ID_T)
486  {
487  // パラメータはブロック番号
489  }
490 
491  // パラメータを読み出し。
493 
495 }
496 
498 {
499  const unsigned char* param = CCP_get_param_head(packet);
500  bct_id_t block;
501  uint16_t interval;
502  BCE_Params* bc_exe_params;
503 
504  if (CCP_get_param_len(packet) != (SIZE_OF_BCT_ID_T + 2))
505  {
506  // パラメータはブロック番号2Byte+周期2Byte = 4Bytes
508  }
509 
510  // パラメータを読み出し。
511  ENDIAN_memcpy(&block, param, SIZE_OF_BCT_ID_T);
512  ENDIAN_memcpy(&interval, param + SIZE_OF_BCT_ID_T, 2);
513 
514  if (interval == 0 || block >= BCT_MAX_BLOCKS)
515  {
516  // 0で割りに行くのでここではじく
518  }
519 
520  bc_exe_params = BCE_get_bc_exe_params_(block);
521  bc_exe_params->rotate.interval = interval;
522  BCE_set_bc_exe_params_(block, bc_exe_params);
523 
525 }
526 
527 #pragma section
BCT_ACK BCE_reset_combiner_info(const bct_id_t block)
static CommonCmdPacket BCE_packet_
BCT_ACK BCE_activate_block_by_id(bct_id_t block)
static CCP_CmdRet BCE_combine_block_cmd_(bct_id_t block)
BC をまとめて一括で実行する
CCP_CmdRet Cmd_BCE_INACTIVATE_BLOCK_BY_ID(const CommonCmdPacket *packet)
static BCE_Params * BCE_get_bc_exe_params_(const bct_id_t block)
static void BCE_set_bc_exe_params_(const bct_id_t block, const BCE_Params *bc_exe_params)
CCP_CmdRet Cmd_BCE_ACTIVATE_BLOCK_BY_ID(const CommonCmdPacket *packet)
BCT_ACK BCE_swap_address(const bct_id_t block_a, const bct_id_t block_b)
BCE の params の指すポインタ & func を入れ替える
static void BCE_set_bc_exe_params_default_(const bct_id_t block, const BCE_Params *bc_exe_params)
BCT_ACK BCE_clear_block(const bct_id_t block)
指定された block の BCE を初期化
const BlockCommandExecutor *const block_command_executor
BCT_ACK BCE_inactivate_block_by_id(bct_id_t block)
BCT_ACK BCE_reset_rotator_info(const bct_id_t block)
CCP_CmdRet Cmd_BCE_RESET_COMBINER_INFO(const CommonCmdPacket *packet)
CCP_CmdRet Cmd_BCE_TIMELIMIT_COMBINE_BLOCK(const CommonCmdPacket *packet)
const BCE_Params * BCE_get_bc_exe_params(const bct_id_t block)
BCE_Params の const getter
CCP_CmdRet Cmd_BCE_COMBINE_BLOCK(const CommonCmdPacket *packet)
uint8_t BCE_is_active(const bct_id_t block)
BCT の length の getter
static BlockCommandExecutor block_command_executor_
static BCE_Params * BCE_get_bc_exe_params_default_(const bct_id_t block)
時間制限付きの combiner
void BCE_load_default_func_pointer(void)
BCE_Params にデフォルトの関数ポインタを入れる
static CCP_CmdRet BCE_timelimit_combine_block_cmd_(bct_id_t block, step_t limit_step)
BC をまとめて一括で実行する
static CCP_CmdRet BCE_rotate_block_cmd_(bct_id_t block)
rotator の実行主体
BCT_ACK BCE_swap_contents(const bct_id_t block_a, const bct_id_t block_b)
BCE の params の指す中身を入れ替える
CCP_CmdRet Cmd_BCE_ROTATE_BLOCK(const CommonCmdPacket *packet)
CCP_CmdRet Cmd_BCE_RESET_ROTATOR_INFO(const CommonCmdPacket *packet)
CCP_CmdRet Cmd_BCE_ACTIVATE_BLOCK(const CommonCmdPacket *packet)
CCP_CmdRet Cmd_BCE_SET_ROTATE_INTERVAL(const CommonCmdPacket *packet)
BCT_ACK BCE_activate_block(void)
block_command_table->pos の BC を activate する
BCTの実行周りの関数, パラメーター
BCT_ACK BCT_make_pos(BCT_Pos *pos, const bct_id_t block, const uint8_t cmd)
BCT_Pos* を引数から作る
BCT_ACK BCT_load_cmd(const BCT_Pos *pos, CommonCmdPacket *packet)
保存データを CCP にコピーする.
const BlockCommandTable *const block_command_table
CCP_CmdRet BCT_convert_bct_ack_to_ccp_cmd_ret(BCT_ACK ack)
返り値用 enum 変換用関数
uint8_t BCT_get_bc_length(const bct_id_t block)
BCT の length の getter
#define SIZE_OF_BCT_ID_T
bct_id_t の型サイズ.メモリインパクトがそれなりにあるので,可変に
#define BCT_MAX_BLOCKS
BCのIDの最大数
uint16_t bct_id_t
BCT_ACK
BCT 関係の関数のエラーステータス
@ BCT_SUCCESS
@ BCT_INVALID_BLOCK_NO
@ BCT_DEFECTIVE_BLOCK
@ CCP_EXEC_SUCCESS
@ CCP_EXEC_ILLEGAL_LENGTH
コマンド実行時のコマンド引数長エラー
@ CCP_EXEC_ILLEGAL_PARAMETER
コマンド実行時のパラメタエラー
@ CCP_EXEC_ILLEGAL_CONTEXT
コマンド実行時のその他のエラー
uint16_t CCP_get_param_len(const CommonCmdPacket *packet)
CMD パラメタ長を取得
const uint8_t * CCP_get_param_head(const CommonCmdPacket *packet)
先頭のパラメタのポインタを取得
CCP_CmdRet CCP_make_cmd_ret_without_err_code(CCP_EXEC_STS exec_sts)
コマンド返り値である CCP_CmdRet を作成(エラーコード不使用版)
CCP の汎用 Utility
void * ENDIAN_memcpy(void *dest, const void *src, size_t size)
エンディアンを考慮した memcpy
Definition: endian.c:11
step_t OBCT_diff_in_step(const ObcTime *before, const ObcTime *after)
ObcTime の引き算を step 単位で行う
Definition: obc_time.c:146
uint32_t step_t
Definition: obc_time.h:11
CCP_CmdRet PH_dispatch_command(const CommonCmdPacket *packet)
CCP をコマンドとして解釈して実行,ないしは別機器へ配送する
C2A 全体を流れる Common Packet の配送を制御する
BCE_Params の getter, setter (private)
void(* set_bc_exe_params_)(const bct_id_t block, const BCE_Params *bc_params)
BCE_Params *(* get_bc_exe_params_)(const bct_id_t block)
BCT の実行パラメーターを保存する構造体
uint16_t call_num
Cmd_BCE_TIMELIMIT_COMBINE_BLOCKが呼ばれるたびにインクリメント
uint8_t is_active
有効かどうか.1: 有効, 0: 無効
uint8_t worst_cmd_pos
最悪ケースのcmd pos
struct BCE_Params::@18 timelimit_combine
uint16_t interval
interval[cycle] ごとに実行される (大抵1)
struct BCE_Params::@17 rotate
uint8_t next_cmd
次に実行される cmd
uint8_t last_timeover_cmd_pos
前回時間制限に引っかかったときのcmd pos
uint16_t counter
interval の計算のための counter[cycle]
uint16_t timeover_num
時間制限に引っかかったらインクリメント
BCT内での作業中の位置情報
uint8_t cmd
そのブロック内でどのコマンドを指すか
bct_id_t block
ブロックの位置情報
実行周り全体の struct
BCE_Params * bc_exe_params[BCT_MAX_BLOCKS]
パラメタ.不揮発化出来るようにポインタで確保
BCE_Func bc_exe_func[BCT_MAX_BLOCKS]
BCE_Params に対する操作関数.各 BC ごとに確保
BCT_Pos pos
登録などの作業中の位置情報
コマンド返り値
CCP_EXEC_STS exec_sts
CCP_EXEC_STS.Cmd の統一的なエラーコード
Space Packet (コマンド用)
OBCの時刻情報を保持する構造体
Definition: obc_time.h:18
ObcTime TMGR_get_master_clock(void)
現在の master_clock_ を取得する
Definition: time_manager.c:80