C2A_Core
packet_list.c
[詳解]
1 #pragma section REPRO
6 #include "packet_list.h"
7 
8 #include "../System/TimeManager/time_manager.h"
10 #include "block_command_executor.h"
11 #include "block_command_table.h"
12 #include <stdint.h>
13 #include <string.h>
14 
15 
24 
31 static PL_ACK PL_drop_head_(PacketList* pl);
32 
33 
34 PL_ACK PL_initialize(PL_Node* pl_node_stock,
35  void* packet_stock,
36  uint16_t node_num,
37  PL_PACKET_TYPE packet_type,
38  uint16_t packet_size,
39  PacketList* pl)
40 {
41  pl->total_nodes_ = node_num;
42  pl->packet_type_ = packet_type;
43  pl->packet_size_ = packet_size;
44  pl->executed_nodes_ = 0;
45 
46  switch (pl->packet_type_)
47  {
49  if (pl->packet_size_ != (uint16_t)sizeof(CommonTlmCmdPacket)) return PL_PACKET_TYPE_ERR;
50  break;
51  case PL_PACKET_TYPE_CTP:
52  if (pl->packet_size_ != (uint16_t)sizeof(CommonTlmPacket)) return PL_PACKET_TYPE_ERR;
53  break;
54  case PL_PACKET_TYPE_CCP:
55  if (pl->packet_size_ != (uint16_t)sizeof(CommonCmdPacket)) return PL_PACKET_TYPE_ERR;
56  break;
57  default:
58  // その他の場合は, assertion できない
59  break;
60  }
61 
62  pl->pl_node_stock_ = pl_node_stock;
63  pl->packet_stock_ = packet_stock;
64  PL_clear_list(pl);
65  return PL_SUCCESS;
66 }
67 
68 
70 {
71  uint16_t i;
72  const uint16_t packet_size = pl->packet_size_;
73  const uint16_t node_num = pl->total_nodes_;
74  const uint8_t* packet_stock_head = (const uint8_t*)pl->packet_stock_;
75 
76  // PL_Node と packet の関連をつける
77  for (i = 0; i < node_num; ++i)
78  {
79  pl->pl_node_stock_[i].packet = (void*)(packet_stock_head + packet_size * i);
80  }
81 
82  // PL_node の配列を連結リストとして再定義
83  for (i = 0; i < node_num - 1; ++i)
84  {
85  pl->pl_node_stock_[i].next = &(pl->pl_node_stock_[i + 1]);
86  }
87  pl->pl_node_stock_[node_num - 1].next = NULL;
88 
89  // 最初は全 node 無効化状態
90  pl->active_nodes_ = 0;
92  pl->active_list_head_ = NULL;
93  pl->active_list_tail_ = NULL;
94 }
95 
96 
98 {
99  // FIXME: HEWでWarningが出てしまう(gccではでない)ので,キャストしている
100  return (uint32_t)pl->executed_nodes_;
101 }
102 
103 
105 {
106  // FIXME: HEWでWarningが出てしまう(gccではでない)ので,キャストしている
107  return (uint16_t)pl->active_nodes_;
108 }
109 
110 
112 {
113  return (uint16_t)(pl->total_nodes_ - pl->active_nodes_);
114 }
115 
116 
118 {
119  // FIXME: HEWでWarningが出てしまう(gccではでない)ので,キャストしている
120  return (uint16_t)pl->total_nodes_;
121 }
122 
123 
124 uint16_t PL_get_packet_size(const PacketList* pl)
125 {
126  // FIXME: HEWでWarningが出てしまう(gccではでない)ので,キャストしている
127  return (uint16_t)pl->packet_size_;
128 }
129 
130 
132 {
133  // FIXME: HEWでWarningが出てしまう(gccではでない)ので,キャストしている
134  return (PL_PACKET_TYPE)pl->packet_type_;
135 }
136 
137 
138 int PL_is_empty(const PacketList* pl)
139 {
140  return (pl->active_list_head_ == NULL);
141 }
142 
143 
144 int PL_is_full(const PacketList* pl)
145 {
146  return (pl->inactive_list_head_ == NULL);
147 }
148 
149 
150 const PL_Node* PL_get_head(const PacketList* pl)
151 {
152  return pl->active_list_head_;
153 }
154 
155 
156 const PL_Node* PL_get_tail(const PacketList* pl)
157 {
158  return pl->active_list_tail_;
159 }
160 
161 
162 const PL_Node* PL_get_next(const PL_Node* node)
163 {
164  return (node != NULL) ? node->next : NULL;
165 }
166 
167 
168 PL_ACK PL_push_front(PacketList* pl, const void* packet)
169 {
170  PL_Node* new_pl_node = PL_get_free_node_(pl);
171  if (new_pl_node == NULL) return PL_LIST_FULL;
172 
173  memcpy(new_pl_node->packet, packet, pl->packet_size_);
174 
175  new_pl_node->next = pl->active_list_head_;
176  pl->active_list_head_ = new_pl_node;
177 
178  if (pl->active_list_tail_ == NULL)
179  {
180  pl->active_list_tail_ = new_pl_node;
181  }
182 
183  ++pl->active_nodes_;
184 
185  return PL_SUCCESS;
186 }
187 
188 
189 PL_ACK PL_push_back(PacketList* pl, const void* packet)
190 {
191  PL_Node* new_pl_node = PL_get_free_node_(pl);
192  if (new_pl_node == NULL) return PL_LIST_FULL;
193 
194  memcpy(new_pl_node->packet, packet, pl->packet_size_);
195 
196  new_pl_node->next = NULL;
197 
198  if (pl->active_list_tail_ == NULL)
199  {
200  pl->active_list_head_ = new_pl_node;
201  }
202  else
203  {
204  pl->active_list_tail_->next = new_pl_node;
205  }
206 
207  pl->active_list_tail_ = new_pl_node;
208  ++pl->active_nodes_;
209 
210  return PL_SUCCESS;
211 }
212 
213 
214 PL_ACK PL_insert_after(PacketList* pl, PL_Node* pos, const void* packet)
215 {
216  PL_Node* new_pl_node;
217 
218  if (pos == NULL) return PL_NO_SUCH_NODE;
219 
220  if (pos == pl->active_list_tail_) return PL_push_back(pl, packet);
221 
222  new_pl_node = PL_get_free_node_(pl);
223  if (new_pl_node == NULL) return PL_LIST_FULL;
224 
225  memcpy(new_pl_node->packet, packet, pl->packet_size_);
226 
227  new_pl_node->next = pos->next;
228  pos->next = new_pl_node;
229 
230  ++pl->active_nodes_;
231 
232  return PL_SUCCESS;
233 }
234 
235 
237 {
238  PL_ACK ack = PL_drop_head_(pl);
239  if (ack == PL_SUCCESS)
240  {
241  ++(pl->executed_nodes_);
242  }
243 
244  return ack;
245 }
246 
247 
249 {
250  if (current == NULL) return PL_NO_SUCH_NODE;
251  if (pl->active_list_head_ == NULL) return PL_LIST_EMPTY;
252  if (prev == NULL)
253  {
254  if (pl->active_list_head_ == current)
255  {
256  return PL_drop_head_(pl);
257  }
258  else
259  {
260  return PL_NO_SUCH_NODE;
261  }
262  }
263 
264  prev->next = current->next;
265  if (pl->active_list_tail_ == current)
266  {
267  pl->active_list_tail_ = prev;
268  }
269 
270  current->next = pl->inactive_list_head_;
271  pl->inactive_list_head_ = current;
272  --pl->active_nodes_;
273 
274  return PL_SUCCESS;
275 }
276 
277 
278 // FIXME: PL にあるのがおかしくて, TL 周りのどこかで検索して, insert を実行すべき
280 {
281  cycle_t head, tail;
282  cycle_t planed = CCP_get_ti(packet);
283 
285 
286  if (now > planed) return PL_TLC_PAST_TIME;
287  if (PL_is_full(pl)) return PL_LIST_FULL;
288  if (PL_is_empty(pl)) return PL_push_front(pl, packet);
289 
290  // 以下,他コマンドが登録されているとき
291  head = CCP_get_ti( (const CommonCmdPacket*)(PL_get_head(pl)->packet) );
292  tail = CCP_get_ti( (const CommonCmdPacket*)(PL_get_tail(pl)->packet) );
293 
294  if (tail < planed) // 他のどれより遅い
295  {
296  return PL_push_back(pl, packet);
297  }
298  else if (head > planed) // 他のどれより早い
299  {
300  return PL_push_front(pl, packet);
301  }
302  else if (head == planed || tail == planed) // 時刻指定が等しい
303  {
304  return PL_TLC_ALREADY_EXISTS;
305  }
306  else // 他コマンドの間に挿入操作が必要(最低でもすでに 2 個登録済みなはず)
307  {
308  uint16_t i;
309  PL_Node* prev = (PL_Node*)PL_get_head(pl); // const_cast
310  PL_Node* curr = prev->next;
311 
312  // 挿入場所探索
313  for (i = 1; i < pl->active_nodes_; ++i)
314  {
315  cycle_t curr_ti = CCP_get_ti( (const CommonCmdPacket*)(curr->packet) );
316 
317  if (curr_ti < planed)
318  {
319  prev = curr;
320  curr = prev->next;
321  }
322  else if (curr_ti > planed) // 挿入場所発見
323  {
324  PL_insert_after(pl, prev, packet);
325  return PL_SUCCESS;
326  }
327  else // 既登録コマンドと時刻指定が等しい
328  {
329  return PL_TLC_ALREADY_EXISTS;
330  }
331  }
332  }
333 
334  // NOT REACHED
335  return PL_NO_SUCH_NODE;
336 }
337 
338 
339 // FIXME: PL にあるのがおかしくて, BC 周りのどこかでやるべき
341 {
342  uint8_t i;
343  uint16_t j;
344  int is_cleared = 0; // リスト強制クリアの記録用変数
345  uint32_t adj = 0; // 時刻調整の累積量保存用変数
346  uint8_t bc_length;
347 
349 
350  if (block >= BCT_MAX_BLOCKS) return PL_BC_INACTIVE_BLOCK;
351  if (!BCE_is_active(block)) return PL_BC_INACTIVE_BLOCK;
352 
353  bc_length = BCT_get_bc_length(block);
354 
355  // リストにブロック全体を登録する余裕がない場合
356  if (PL_count_inactive_nodes(pl) < bc_length)
357  {
358  // リストをクリアし強制的に空き領域を確保する
359  PL_clear_list(pl);
360  is_cleared = 1;
361  }
362 
363  for (i = 0; i < bc_length; ++i)
364  {
365  static CommonCmdPacket temp_; // サイズが大きいため静的領域に確保
366  BCT_Pos pos;
367  PL_ACK ack = PL_SUCCESS;
368 
369  // コマンドを読みだし、TLCとして実行時刻を設定
370  BCT_make_pos(&pos, block, i);
371  BCT_load_cmd(&pos, &temp_);
372  CCP_set_ti(&temp_, (cycle_t)(start_at + adj + CCP_get_ti(&temp_)));
373  CCP_set_exec_type(&temp_, CCP_EXEC_TYPE_TL_FROM_GS); // BLC -> TLC // FIXME: TaskListやBC用TLM用もすべて CCP_EXEC_TYPE_TL_FROM_GS になってしまうので, わかりにくい
374 
375  for (j = 0; j <= pl->active_nodes_; ++j)
376  {
377  // コマンドをTLCに登録を試みる
378  ack = PL_insert_tl_cmd(pl, &temp_, start_at);
379  if (ack != PL_TLC_ALREADY_EXISTS) break; // PL_SUCCESS なはず. TODO: 一応 event 発行しておく?
380 
381  // 同一時刻で既に登録されていた場合は時刻をずらして再登録
382  CCP_set_ti(&temp_, CCP_get_ti(&temp_) + 1);
383  ++adj; // 累積調整時間を更新する
384  }
385  if (ack != PL_SUCCESS) return ack;
386  }
387 
388  // リストの強制クリアを実施した場合
389  if (is_cleared == 1) return PL_BC_LIST_CLEARED;
390  // 時刻調整を行った場合
391  if (adj != 0) return PL_BC_TIME_ADJUSTED;
392 
393  return PL_SUCCESS;
394 }
395 
396 
398 {
400 
401  if (!PL_is_empty(pl))
402  {
403  const CommonCmdPacket* packet = (const CommonCmdPacket*)(pl->active_list_head_->packet);
404  cycle_t planed = CCP_get_ti(packet);
405 
406  if (time == planed) return PL_TLC_ON_TIME;
407  if (time > planed) return PL_TLC_PAST_TIME;
408  }
409 
410  return PL_TLC_NOT_YET;
411 }
412 
413 
415 {
416  PL_Node* free_node = pl->inactive_list_head_;
417 
418  if (free_node == NULL) return NULL;
419 
421 
422  return free_node;
423 }
424 
425 
427 {
428  PL_Node* temp;
429 
430  if (pl->active_list_head_ == NULL) return PL_LIST_EMPTY;
431 
432  temp = pl->active_list_head_;
433  pl->active_list_head_ = temp->next;
434 
435  if (pl->active_list_head_ == NULL)
436  {
437  pl->active_list_tail_ = NULL;
438  }
439 
440  temp->next = pl->inactive_list_head_;
441  pl->inactive_list_head_ = temp;
442 
443  --pl->active_nodes_;
444  return PL_SUCCESS;
445 }
446 
447 #pragma section
uint8_t BCE_is_active(const bct_id_t block)
BCT の length の getter
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 にコピーする.
uint8_t BCT_get_bc_length(const bct_id_t block)
BCT の length の getter
BCTの定義, BCT周りの関数
#define BCT_MAX_BLOCKS
BCのIDの最大数
uint16_t bct_id_t
void CCP_set_ti(CommonCmdPacket *packet, cycle_t ti)
TI を設定
void CCP_set_exec_type(CommonCmdPacket *packet, CCP_EXEC_TYPE type)
EXEC_TYPE を設定
cycle_t CCP_get_ti(const CommonCmdPacket *packet)
TI を取得
@ CCP_EXEC_TYPE_TL_FROM_GS
TL : Timeline Command
CTCP 関連基本関数の宣言
uint32_t cycle_t
Definition: obc_time.h:10
static PL_Node * PL_get_free_node_(PacketList *pl)
未使用 Node を新規に取得
Definition: packet_list.c:414
const PL_Node * PL_get_tail(const PacketList *pl)
PacketList の active な末端 Node を取得
Definition: packet_list.c:156
void PL_clear_list(PacketList *pl)
PacketList をクリア
Definition: packet_list.c:69
PL_ACK PL_check_tl_cmd(const PacketList *pl, cycle_t time)
PacketList の先頭と time を比較
Definition: packet_list.c:397
PL_ACK PL_drop_node(PacketList *pl, PL_Node *prev, PL_Node *current)
指定された Node を落とす
Definition: packet_list.c:248
PL_ACK PL_push_front(PacketList *pl, const void *packet)
PacketList の先頭に packet を挿入
Definition: packet_list.c:168
uint16_t PL_get_total_node_num(const PacketList *pl)
PacketList の全 Node 数を返す
Definition: packet_list.c:117
uint16_t PL_get_packet_size(const PacketList *pl)
PacketList で使用される packet の型サイズを返す
Definition: packet_list.c:124
const PL_Node * PL_get_next(const PL_Node *node)
現 Node から次の Node を取得
Definition: packet_list.c:162
PL_ACK PL_insert_after(PacketList *pl, PL_Node *pos, const void *packet)
ある Node の直後に packet を挿入
Definition: packet_list.c:214
static PL_ACK PL_drop_head_(PacketList *pl)
先頭 Node を落とす
Definition: packet_list.c:426
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_deploy_block_cmd(PacketList *pl, const bct_id_t block, cycle_t start_at)
PacketList 上に BC を展開する
Definition: packet_list.c:340
uint16_t PL_count_active_nodes(const PacketList *pl)
PacketList で有効な(実行待ち) Node 数を返す
Definition: packet_list.c:104
PL_ACK PL_initialize(PL_Node *pl_node_stock, void *packet_stock, uint16_t node_num, PL_PACKET_TYPE packet_type, uint16_t packet_size, PacketList *pl)
static に確保された PL_Node 配列と packet 配列を受け取りその領域を使用して PL を初期化
Definition: packet_list.c:34
PL_ACK PL_insert_tl_cmd(PacketList *pl, const CommonCmdPacket *packet, cycle_t now)
CCP が時系列に並ぶように CCP を挿入する
Definition: packet_list.c:279
uint32_t PL_count_executed_nodes(const PacketList *pl)
PacketList で実行された Node 数を返す
Definition: packet_list.c:97
PL_ACK PL_drop_executed(PacketList *pl)
先頭 Node を落とす
Definition: packet_list.c:236
uint16_t PL_count_inactive_nodes(const PacketList *pl)
PacketList で使用されていない Node 数を返す
Definition: packet_list.c:111
int PL_is_full(const PacketList *pl)
PacketList が満杯かどうか
Definition: packet_list.c:144
PL_ACK PL_push_back(PacketList *pl, const void *packet)
PacketList の末尾に packet を挿入
Definition: packet_list.c:189
int PL_is_empty(const PacketList *pl)
PacketList が空かどうか
Definition: packet_list.c:138
CTCP, CTP, CCP のリストとしてのデータ構造を定義. 片方向リストとして実装されている
PL_ACK
PacketList 関連操作のエラーコード
Definition: packet_list.h:39
@ PL_TLC_NOT_YET
まだ実行時刻ではない
Definition: packet_list.h:47
@ PL_LIST_EMPTY
PacketList が空 (active 無し)
Definition: packet_list.h:42
@ PL_BC_INACTIVE_BLOCK
無効な BC
Definition: packet_list.h:48
@ PL_TLC_PAST_TIME
実行時間既に経過
Definition: packet_list.h:44
@ PL_SUCCESS
成功
Definition: packet_list.h:40
@ PL_LIST_FULL
PacketList が満杯 (inactive 無し)
Definition: packet_list.h:41
@ PL_BC_TIME_ADJUSTED
同時刻に Node があったため調整せれた
Definition: packet_list.h:50
@ PL_PACKET_TYPE_ERR
PL_PACKET_TYPE 関連エラー
Definition: packet_list.h:43
@ PL_TLC_ON_TIME
実行時刻丁度
Definition: packet_list.h:46
@ PL_BC_LIST_CLEARED
PL クリア (初期化, active 全削除) された
Definition: packet_list.h:49
@ PL_NO_SUCH_NODE
そんな Node は無い
Definition: packet_list.h:51
@ PL_TLC_ALREADY_EXISTS
同時刻に既に Node が存在
Definition: packet_list.h:45
PL_PACKET_TYPE
PacketList に格納される packet の型情報
Definition: packet_list.h:26
@ PL_PACKET_TYPE_CCP
CommonCmdPacket
Definition: packet_list.h:29
@ PL_PACKET_TYPE_CTCP
CommonTlmCmdPacket
Definition: packet_list.h:27
@ PL_PACKET_TYPE_CTP
CommonTlmPacket
Definition: packet_list.h:28
C89 環境用 stdint.h
BCT内での作業中の位置情報
Space Packet (コマンド用)
片方向リストを構成する各 Node
Definition: packet_list.h:59
void * packet
片方向リストに格納される packet. どのような型でも良いように, void.(基本的には CTCP, CTP, CCP を想定)
Definition: packet_list.h:60
struct PL_Node * next
次の Node (片方向リスト)
Definition: packet_list.h:61
パケットリスト本体
Definition: packet_list.h:73
uint16_t packet_size_
PL_Node->packet の型サイズ
Definition: packet_list.h:77
uint16_t total_nodes_
全ノード数 (static 確保)
Definition: packet_list.h:74
PL_PACKET_TYPE packet_type_
保持する packet の型情報.PL_PACKET_TYPE を参照
Definition: packet_list.h:78
PL_Node * inactive_list_head_
確保されている領域の内,使っていないものの先頭
Definition: packet_list.h:82
PL_Node * active_list_tail_
確保されている領域の内,使っているものの末端
Definition: packet_list.h:84
PL_Node * pl_node_stock_
確保されている PL_Node 領域(配列)全体の先頭
Definition: packet_list.h:80
PL_Node * active_list_head_
確保されている領域の内,使っているものの先頭
Definition: packet_list.h:83
void * packet_stock_
確保されている packet 領域(配列)全体の先頭
Definition: packet_list.h:81
uint16_t active_nodes_
現在片方向リストに入っているノード数
Definition: packet_list.h:76
uint32_t executed_nodes_
実行(コマンド) or 配送(テレメ)されたノード数 // FIXME: TODO: テレメのときもカウントアップしてるか確認
Definition: packet_list.h:75
Space Packet
Space Packet (テレメ用)