• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

UART通信を用いた組み込みデバッグ用途向けメモリモニタ


Commit MetaInfo

Revisiónd3df1036ff90632609a7aeb2efbaf50c3d10775e (tree)
Tiempo2018-05-13 22:23:10
AutorYasushi Tanaka <tanaka_yasushi2008@yaho...>
CommiterYasushi Tanaka

Log Message

YMODEM実装中

Cambiar Resumen

Diferencia incremental

--- a/DebugMonitor/src/comm/ymodem.c
+++ b/DebugMonitor/src/comm/ymodem.c
@@ -11,19 +11,1415 @@
1111 #include "ymodem.h"
1212
1313 /*
14- * 定数
14+ * YMODEM定数
1515 */
1616
17+/* SOH (フレームの開始)(128バイト) */
18+#define YMODEM_SOH 0x01
19+
20+/* STX (テキストの開始)(1024バイト) */
21+#define YMODEM_STX 0x02
22+
23+/* EOT (ファイル転送の終了) */
24+#define YMODEM_EOT 0x04
25+
26+/* ACK (肯定的応答) */
27+#define YMODEM_ACK 0x06
28+
29+/* NAK (否定的応答) */
30+#define YMODEM_NAK 0x15
31+
32+/* CAN (キャンセル要求) */
33+#define YMODEM_CAN 0x18
34+
35+/* C (送信開始要求) */
36+#define YMODEM_C 0x43
37+
38+/*
39+ * タイムアウトおよびリトライ回数
40+ */
41+
42+/* 送信タイムアウト */
43+#define YMODEM_SEND_TIMEOUT 100
44+
45+/* 送信リトライ回数 */
46+#define YMODEM_SEND_RETRY 40
47+
48+/*
49+ * 状態遷移
50+ */
51+
52+/* 初期状態 */
53+#define YMODEM_TRANS_NONE 0
54+
55+/* 受信側の'C'送信待ち(1) */
56+#define YMODEM_TRANS_WAITC1 1
57+
58+/* ファイル情報送信 */
59+#define YMODEM_TRANS_SENDINFO 2
60+
61+/* ファイル情報ACK待ち */
62+#define YMODEM_TRANS_INFOACK 3
63+
64+/* 受信側の'C'送信待ち(2) */
65+#define YMODEM_TRANS_WAITC2 4
66+
67+/* データブロック送信 */
68+#define YMODEM_TRANS_SENDDATA 5
69+
70+/* データブロックACK待ち */
71+#define YMODEM_TRANS_DATAACK 6
72+
73+/* EOT送信 */
74+#define YMODEM_TRANS_SENDEOT 7
75+
76+/* EOTに対するACK待ち */
77+#define YMODEM_TRANS_EOTACK 8
78+
79+/*
80+ * YMODEMオブジェクト
81+ */
82+typedef struct _YMDOEM_OBJECT
83+{
84+ /*
85+ * 外部公開情報
86+ */
87+
88+ /* 通信ポートのインデックス */
89+ UINT comm_index;
90+
91+ /* 送信中 */
92+ BOOL sending;
93+
94+ /* 受信中 */
95+ BOOL receiving;
96+
97+ /* ステータス */
98+ UINT status;
99+
100+ /* ファイルネーム(ファイルサイズの追加分を見越し、上限長さ0x60とする) */
101+ char file_name[0x60];
102+
103+ /* ファイルサイズ */
104+ UINT file_size;
105+
106+ /* ファイルバッファ */
107+ BYTE file_buf[0x10000];
108+
109+ /*
110+ * 内部情報
111+ */
112+
113+ /* 状態遷移 */
114+ UINT state;
115+
116+ /* 開始時間 */
117+ DWORD start_time;
118+
119+ /* リトライカウンタ */
120+ UINT retry;
121+
122+ /* ブロック番号 */
123+ UINT block_no;
124+
125+ /* ブロックバッファ */
126+ BYTE block_buf[0x400 + 5];
127+
128+ /* ブロックオフセット */
129+ UINT block_offset;
130+
131+ /* バッファオフセット */
132+ UINT buf_offset;
133+
134+ /* CANカウンタ */
135+ UINT cancel;
136+
137+ /*
138+ * 参考情報(モニタ表示用)
139+ */
140+
141+ /* ACK受信回数 */
142+ UINT ack_cnt;
143+
144+ /* NAK受信回数 */
145+ UINT nak_cnt;
146+
147+ /* CAN受信回数 */
148+ UINT can_cnt;
149+
150+ /* タイムアウト回数 */
151+ UINT timeout_cnt;
152+
153+ /* リトライ回数 */
154+ UINT retry_cnt;
155+
156+ /* CRC */
157+ WORD crc;
158+} YMODEM_OBJECT;
159+
17160 /*
18161 * static変数
19162 */
20163
164+/* オブジェクト */
165+YMODEM_OBJECT g_ymodem_object;
166+
167+/*
168+ * static関数
169+ */
170+
171+/* オブジェクト状態遷移要求 */
172+static void ymodem_object_trans(YMODEM_OBJECT *object, UINT state);
173+
174+/*
175+ * YMODEM
176+ * CRCテーブル
177+ */
178+static WORD ymodem_crc_table[0x100] = {
179+ 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
180+ 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
181+ 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
182+ 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
183+ 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
184+ 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
185+ 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
186+ 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
187+
188+ 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
189+ 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
190+ 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
191+ 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
192+ 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
193+ 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
194+ 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
195+ 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
196+
197+ 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
198+ 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
199+ 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
200+ 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
201+ 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
202+ 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
203+ 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
204+ 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
205+
206+ 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
207+ 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
208+ 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
209+ 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
210+ 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
211+ 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
212+ 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
213+ 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0,
214+};
215+
216+/*
217+ * YMODEM
218+ * CRC算出
219+ */
220+static WORD ymodem_crc_calc(YMODEM_OBJECT *object)
221+{
222+ UINT size;
223+ UINT loop;
224+ WORD crc;
225+
226+ assert(NULL != object);
227+
228+ /* SOHかSTXによって、データ部分のサイズを分ける */
229+ if (YMODEM_SOH == object->block_buf[0])
230+ {
231+ /* 128バイト */
232+ size = 0x80;
233+ }
234+ else
235+ {
236+ /* 1024バイト */
237+ size = 0x400;
238+ }
239+
240+ /* CRC初期値 */
241+ crc = 0x0000;
242+
243+ /* ループ */
244+ for (loop = 0; loop < size; loop++)
245+ {
246+ /* テーブルを使う */
247+ crc = (WORD)(crc << 8) ^ ymodem_crc_table[(crc >> 8) ^ object->block_buf[3 + loop]];
248+ }
249+
250+ /* CRCを返す */
251+ return crc;
252+}
253+
254+/*
255+ * YMODEM
256+ * オブジェクト初期化
257+ */
258+static void ymodem_object_init(YMODEM_OBJECT *object, UINT comm_index)
259+{
260+ assert(NULL != object);
261+
262+ /* オブジェクトを初期化 */
263+ memset(object, 0, sizeof(YMODEM_OBJECT));
264+
265+ /* 通信ポート番号を設定 */
266+ object->comm_index = comm_index;
267+}
268+
269+/*
270+ * YMODEM
271+ * エラー(ポートがクローズされた)
272+ */
273+static void ymodem_error_closed(YMODEM_OBJECT *object)
274+{
275+ assert(NULL != object);
276+
277+ /* クローズされた */
278+ object->status = YMODEM_CLOSED;
279+
280+ /* 送信中か */
281+ if (FALSE != object->sending)
282+ {
283+ /* 送信中でない */
284+ object->sending = FALSE;
285+
286+ /* ログ */
287+ logwin_printf("ファイル送信失敗(COMポートがクローズされた)");
288+ }
289+
290+ /* 受信中か */
291+ if (FALSE != object->sending)
292+ {
293+ /* 受信中でない */
294+ object->receiving = FALSE;
295+
296+ /* ログ */
297+ logwin_printf("ファイル受信失敗(COMポートがクローズされた)");
298+ }
299+}
300+
301+/*
302+ * YMODEM
303+ * エラー(タイムアウト)
304+ */
305+static void ymodem_error_timeout(YMODEM_OBJECT *object)
306+{
307+ assert(NULL != object);
308+
309+ /* タイムアウト */
310+ object->status = YMODEM_TIMEOUT;
311+
312+ /* 送信中か */
313+ if (FALSE != object->sending)
314+ {
315+ /* 送信中でない */
316+ object->sending = FALSE;
317+
318+ /* ログ */
319+ logwin_printf("ファイル送信失敗(タイムアウト)");
320+ }
321+
322+ /* 受信中か */
323+ if (FALSE != object->sending)
324+ {
325+ /* 受信中でない */
326+ object->receiving = FALSE;
327+
328+ /* ログ */
329+ logwin_printf("ファイル受信失敗(タイムアウト)");
330+ }
331+}
332+
333+/*
334+ * YMODEM
335+ * エラー(リトライ)
336+ */
337+static void ymodem_error_retry(YMODEM_OBJECT *object)
338+{
339+ assert(NULL != object);
340+
341+ /* リトライ */
342+ object->status = YMODEM_RETRY;
343+
344+ /* 送信中か */
345+ if (FALSE != object->sending)
346+ {
347+ /* 送信中でない */
348+ object->sending = FALSE;
349+
350+ /* ログ */
351+ logwin_printf("ファイル送信失敗(リトライ回数上限)");
352+ }
353+
354+ /* 受信中か */
355+ if (FALSE != object->sending)
356+ {
357+ /* 受信中でない */
358+ object->receiving = FALSE;
359+
360+ /* ログ */
361+ logwin_printf("ファイル受信失敗(リトライ回数上限)");
362+ }
363+}
364+
365+/*
366+* YMODEM
367+* エラー(キャンセル)
368+*/
369+static void ymodem_error_cancel(YMODEM_OBJECT *object)
370+{
371+ assert(NULL != object);
372+
373+ /* キャンセル */
374+ object->status = YMODEM_CANCEL;
375+
376+ /* 送信中か */
377+ if (FALSE != object->sending)
378+ {
379+ /* 送信中でない */
380+ object->sending = FALSE;
381+
382+ /* ログ */
383+ logwin_printf("ファイル送信失敗(キャンセル要求受信)");
384+ }
385+
386+ /* 受信中か */
387+ if (FALSE != object->sending)
388+ {
389+ /* 受信中でない */
390+ object->receiving = FALSE;
391+
392+ /* ログ */
393+ logwin_printf("ファイル受信失敗(キャンセル要求受信)");
394+ }
395+}
396+
397+/*
398+ * YMODEM
399+ * 受信バッファの読み捨て
400+ */
401+static void ymodem_discard_recv(YMODEM_OBJECT *object)
402+{
403+ UINT bytes;
404+ UINT result;
405+ BYTE buf;
406+
407+ assert(NULL != object);
408+
409+ /* 無限ループ */
410+ for (;;)
411+ {
412+ /* 受信バイト数の取得 */
413+ bytes = comm_get_bytes(object->comm_index);
414+ if (0 != bytes)
415+ {
416+ /* 1バイト以上の受信バイト数があるので、1バイトだけ読み取る */
417+ result = comm_recv(object->comm_index, &buf, sizeof(buf));
418+ if (0 == result)
419+ {
420+ /* 読み取りに失敗した */
421+ ymodem_error_closed(object);
422+ break;
423+ }
424+ }
425+ }
426+}
427+
428+/*
429+ * YMODEM
430+ * タイムアウトチェック
431+ */
432+static BOOL ymodem_check_timeout(YMODEM_OBJECT *object, DWORD timeout)
433+{
434+ DWORD diff;
435+
436+ assert(NULL != object);
437+
438+ /* 差分時間を得る */
439+ diff = (DWORD)(timeGetTime() - object->start_time);
440+
441+ /* 差分時間がパラメータ以上であればタイムアウト */
442+ if (diff >= timeout)
443+ {
444+ /* タイムアウト回数++ */
445+ object->timeout_cnt++;
446+
447+ /* タイムアウトした */
448+ return TRUE;
449+ }
450+
451+ /* タイムアウトではない */
452+ return FALSE;
453+}
454+
455+/*
456+ * YMODEM
457+ * リトライチェック
458+ */
459+static BOOL ymodem_check_retry(YMODEM_OBJECT *object, UINT retry_max)
460+{
461+ assert(NULL != object);
462+
463+ /* リトライ回数++ */
464+ object->retry_cnt++;
465+
466+ /* リトライカウンタをインクリメント */
467+ object->retry++;
468+
469+ /* リトライ上限を超えていればリトライオーバー */
470+ if (object->retry > retry_max)
471+ {
472+ /* リトライオーバーした */
473+ return TRUE;
474+ }
475+
476+ /* リトライ上限を超えていない */
477+ return FALSE;
478+}
479+
480+/*
481+ * YMODEM
482+ * オフセットチェック
483+ */
484+static BOOL ymodem_check_offset(YMODEM_OBJECT *object)
485+{
486+ UINT size;
487+
488+ assert(NULL != object);
489+
490+ /* SOHかSTXによって、データ部分のサイズを分ける */
491+ if (YMODEM_SOH == object->block_buf[0])
492+ {
493+ /* 128バイトブロック */
494+ size = 0x80 + 5;
495+ }
496+ else
497+ {
498+ /* 1024バイト */
499+ size = 0x400 + 5;
500+ }
501+
502+ /* block_offsetがsizeに到達していればTRUEを返す */
503+ assert(object->block_offset <= size);
504+ if (object->block_offset == size)
505+ {
506+ /* ブロックオフセットが終端に到達した */
507+ return TRUE;
508+ }
509+
510+ /* ブロックオフセットは終端に到達していない */
511+ return FALSE;
512+}
513+
514+/*
515+ * YMODEM
516+ * キャンセルチェック
517+ */
518+static BOOL ymodem_check_cancel(YMODEM_OBJECT *object)
519+{
520+ assert(NULL != object);
521+
522+ /* キャンセルカウンタをインクリメント */
523+ object->cancel++;
524+
525+ /* 2回連続でキャンセルを受け取ったらキャンセル */
526+ if (2 <= object->cancel)
527+ {
528+ /* キャンセル */
529+ return TRUE;
530+ }
531+
532+ /* キャンセルでない */
533+ return FALSE;
534+}
535+
536+/*
537+* YMODEM
538+* 送信時の受信キャラクタ待ち
539+*/
540+static BYTE ymodem_wait_send(YMODEM_OBJECT *object)
541+{
542+ BOOL result;
543+ UINT len;
544+ UINT error;
545+ BYTE buf;
546+
547+ /* タイムアウトチェック */
548+ result = ymodem_check_timeout(object, YMODEM_SEND_TIMEOUT);
549+ if (FALSE != result)
550+ {
551+ /* タイムアウトしたので、リトライチェック */
552+ result = ymodem_check_retry(object, YMODEM_SEND_RETRY);
553+ if (FALSE != result)
554+ {
555+ /* タイムアウトエラー */
556+ ymodem_error_timeout(object);
557+ return 0;
558+ }
559+ }
560+
561+ /* 受信バッファのデータサイズを得る */
562+ len = comm_get_bytes(object->comm_index);
563+ while (len > 0)
564+ {
565+ /* 1バイト読み込み */
566+ error = comm_recv(object->comm_index, &buf, sizeof(buf));
567+ if (0 == error)
568+ {
569+ /* ポートがクローズされた */
570+ ymodem_error_closed(object);
571+ return 0;
572+ }
573+
574+ /* CAN以外であればCANカウンタをクリア */
575+ if (YMODEM_CAN != buf)
576+ {
577+ object->cancel = 0;
578+ }
579+
580+ switch (buf)
581+ {
582+ /* C */
583+ case YMODEM_C:
584+ return YMODEM_C;
585+
586+ /* ACK */
587+ case YMODEM_ACK:
588+ object->ack_cnt++;
589+ return YMODEM_ACK;
590+
591+ /* NAK*/
592+ case YMODEM_NAK:
593+ object->nak_cnt++;
594+ return YMODEM_NAK;
595+
596+ /* CAN */
597+ case YMODEM_CAN:
598+ object->can_cnt++;
599+ /* キャンセルチェック */
600+ result = ymodem_check_cancel(object);
601+ if (FALSE != result)
602+ {
603+ /* キャンセルエラー */
604+ ymodem_error_cancel(object);
605+ return 0;
606+ }
607+ }
608+ }
609+
610+ /* 有効な受信データなし */
611+ return 0;
612+}
613+
614+/*
615+ * YMODEM
616+ * ブロック送信開始(128バイト固定)
617+ */
618+static void ymodem_block_sendstart(YMODEM_OBJECT *object)
619+{
620+ WORD crc;
621+
622+ assert(NULL != object);
623+
624+ /* SOH */
625+ object->block_buf[0] = YMODEM_SOH;
626+
627+ /* ブロック番号 */
628+ object->block_buf[1] = (BYTE)object->block_no;
629+
630+ /* ブロック番号の補数 */
631+ object->block_buf[2] = (BYTE)(0xff - object->block_buf[1]);
632+
633+ /* CRC算出 */
634+ crc = ymodem_crc_calc(object);
635+
636+ /* CRC記憶 */
637+ object->crc = crc;
638+
639+ /* CRC上位 */
640+ object->block_buf[3 + 0x80 + 0] = (BYTE)(crc >> 8);
641+
642+ /* CRC下位 */
643+ object->block_buf[3 + 0x80 + 1] = (BYTE)crc;
644+
645+ /* ブロックオフセット初期化 */
646+ object->block_offset = 0;
647+}
648+
649+/*
650+ * YMODEM
651+ * ブロック送信中
652+ */
653+static void ymodem_block_senddo(YMODEM_OBJECT *object)
654+{
655+ UINT size;
656+ UINT result;
657+
658+ assert(object != NULL);
659+
660+ /* SOHかSTXによって、データ部分のサイズを分ける */
661+ if (YMODEM_SOH == object->block_buf[0])
662+ {
663+ /* 128バイトブロック */
664+ size = 0x80 + 5;
665+ }
666+ else
667+ {
668+ /* 1024バイト */
669+ size = 0x400 + 5;
670+ }
671+
672+ /* size - ブロックオフセットだけ送信する */
673+ assert((size - object->block_offset) > 0);
674+ result = comm_send(object->comm_index, &object->block_buf[object->block_offset], size - object->block_offset);
675+ if (0 == result)
676+ {
677+ /* 書き込みに失敗した */
678+ ymodem_error_closed(object);
679+ }
680+ else
681+ {
682+ /* 一部書き込めた */
683+ object->block_offset += result;
684+ assert(object->block_offset <= size);
685+ }
686+}
687+
688+/*
689+ * YMODEM
690+ * 受信側の'C'送信待ち(1)
691+ * enter
692+ */
693+static void ymodem_waitc1_enter(YMODEM_OBJECT *object)
694+{
695+ assert(NULL != object);
696+
697+ /* リトライ回数を初期化 */
698+ object->retry = 0;
699+
700+ /* 開始時間を初期化 */
701+ object->start_time = timeGetTime();
702+
703+ /* CAN受信回数を初期化 */
704+ object->cancel = 0;
705+
706+ /* 受信バッファの読み捨て */
707+ ymodem_discard_recv(object);
708+}
709+
710+/*
711+ * YMODEM
712+ * 受信側の'C'送信待ち(1)
713+ * do
714+ */
715+static void ymodem_waitc1_do(YMODEM_OBJECT *object)
716+{
717+ BYTE buf;
718+
719+ /* 送信時の受信キャラクタ待ち */
720+ buf = ymodem_wait_send(object);
721+
722+ /* 'C'であれば状態遷移 */
723+ if (YMODEM_C == buf)
724+ {
725+ ymodem_object_trans(object, YMODEM_TRANS_SENDINFO);
726+ }
727+}
728+
729+/*
730+ * YMODEM
731+ * 受信側の'C'送信待ち(1)
732+ * exit
733+ */
734+static void ymodem_waitc1_exit(YMODEM_OBJECT *object)
735+{
736+ assert(NULL != object);
737+
738+ /* リトライ回数を初期化 */
739+ object->retry = 0;
740+}
741+
742+/*
743+ * YMODEM
744+ * ファイル情報送信
745+ * enter
746+ */
747+static void ymodem_sendinfo_enter(YMODEM_OBJECT *object)
748+{
749+ assert(NULL != object);
750+ char filesize[0x80];
751+ size_t len;
752+
753+ /* ブロック番号を0に初期化 */
754+ object->block_no = 0x00;
755+
756+ /* ブロックバッファを初期化 */
757+ memset(object->block_buf, 0, sizeof(object->block_buf));
758+
759+ /* ファイルネームをブロックバッファ+3にコピー */
760+ strcpy_s((char *)&object->block_buf[3], _countof(object->block_buf) - 3, object->file_name);
761+
762+ /* ファイルネームの長さを得る */
763+ len = strlen(object->file_name);
764+
765+ /* ファイルサイズをフォーマット */
766+ sprintf_s(filesize, _countof(filesize), "%u", object->file_size);
767+
768+ /* ファイルネームの後、0x00を空けて追加 */
769+ strcpy_s((char *)&object->block_buf[3 + len + 1], _countof(object->block_buf) - 3, filesize);
770+
771+ /* ブロック送信開始 */
772+ ymodem_block_sendstart(object);
773+}
774+
775+/*
776+ * YMODEM
777+ * ファイル情報送信
778+ * do
779+ */
780+static void ymodem_sendinfo_do(YMODEM_OBJECT *object)
781+{
782+ BOOL result;
783+
784+ /* ブロック送信 */
785+ ymodem_block_senddo(object);
786+
787+ /* オフセットが末端まで到達したら、状態遷移 */
788+ result = ymodem_check_offset(object);
789+ if (FALSE != result)
790+ {
791+ /* ファイル情報ACK待ち */
792+ ymodem_object_trans(object, YMODEM_TRANS_INFOACK);
793+ }
794+}
795+
796+/*
797+ * YMODEM
798+ * ファイル情報送信
799+ * exit
800+ */
801+static void ymodem_sendinfo_exit(YMODEM_OBJECT *object)
802+{
803+}
804+
805+/*
806+ * YMODEM
807+ * ファイル情報ACK待ち
808+ * enter
809+ */
810+static void ymodem_infoack_enter(YMODEM_OBJECT *object)
811+{
812+ assert(NULL != object);
813+
814+ /* 開始時間を初期化 */
815+ object->start_time = timeGetTime();
816+}
817+
818+/*
819+ * YMODEM
820+ * ファイル情報ACK待ち
821+ * do
822+ */
823+static void ymodem_infoack_do(YMODEM_OBJECT *object)
824+{
825+ BYTE buf;
826+ BOOL result;
827+
828+ /* 送信時の受信キャラクタ待ち */
829+ buf = ymodem_wait_send(object);
830+
831+ switch (buf)
832+ {
833+ /* ACKは状態遷移 */
834+ case YMODEM_ACK:
835+ ymodem_object_trans(object, YMODEM_TRANS_WAITC2);
836+ break;
837+
838+ /* NAKはリトライチェック */
839+ case YMODEM_NAK:
840+ result = ymodem_check_retry(object, YMODEM_SEND_RETRY);
841+ if (FALSE != result)
842+ {
843+ /* リトライエラー */
844+ ymodem_error_retry(object);
845+ return;
846+ }
847+ else
848+ {
849+ /* ファイル情報を再送 */
850+ ymodem_object_trans(object, YMODEM_TRANS_SENDINFO);
851+ }
852+ break;
853+
854+ /* その他は何もしない */
855+ default:
856+ break;
857+ }
858+}
859+
860+/*
861+ * YMODEM
862+ * ファイル情報ACK待ち
863+ * exit
864+ */
865+static void ymodem_infoack_exit(YMODEM_OBJECT *object)
866+{
867+}
868+
869+/*
870+ * YMODEM
871+ * 受信側の'C'送信待ち(2)
872+ * enter
873+ */
874+static void ymodem_waitc2_enter(YMODEM_OBJECT *object)
875+{
876+ assert(NULL != object);
877+
878+ /* リトライ回数を初期化 */
879+ object->retry = 0;
880+
881+ /* 開始時間を初期化 */
882+ object->start_time = timeGetTime();
883+}
884+
885+/*
886+ * YMODEM
887+ * 受信側の'C'送信待ち(2)
888+ * do
889+ */
890+static void ymodem_waitc2_do(YMODEM_OBJECT *object)
891+{
892+ BYTE buf;
893+
894+ /* 送信時の受信キャラクタ待ち */
895+ buf = ymodem_wait_send(object);
896+
897+ /* 'C'であれば状態遷移 */
898+ if (YMODEM_C == buf)
899+ {
900+ ymodem_object_trans(object, YMODEM_TRANS_SENDDATA);
901+ }
902+}
903+
904+/*
905+ * YMODEM
906+ * 受信側の'C'送信待ち(2)
907+ * exit
908+ */
909+static void ymodem_waitc2_exit(YMODEM_OBJECT *object)
910+{
911+ assert(NULL != object);
912+
913+ /* リトライ回数を初期化 */
914+ object->retry = 0;
915+
916+ /* ブロック番号を初期化 */
917+ object->block_no = 0x01;
918+
919+ /* バッファオフセットを初期化 */
920+ object->buf_offset = 0;
921+}
922+
923+/*
924+ * YMODEM
925+ * データブロック送信
926+ * enter
927+ */
928+static void ymodem_senddata_enter(YMODEM_OBJECT *object)
929+{
930+ UINT len;
931+
932+ assert(NULL != object);
933+
934+ /* ブロックバッファを初期化 */
935+ memset(object->block_buf, 0, sizeof(object->block_buf));
936+
937+ /* コピーする長さを算出(最大0x80) */
938+ assert(object->block_offset < object->file_size);
939+ len = object->file_size - object->block_offset;
940+ if (0x80 < len)
941+ {
942+ len = 0x80;
943+ }
944+
945+ /* ブロックオフセットからデータをコピー */
946+ memcpy(&object->block_buf[3], &object->file_buf[object->block_offset], len);
947+
948+ /* ブロック送信開始 */
949+ ymodem_block_sendstart(object);
950+}
951+
952+/*
953+ * YMODEM
954+ * データブロック送信
955+ * do
956+ */
957+static void ymodem_senddata_do(YMODEM_OBJECT *object)
958+{
959+ BOOL result;
960+
961+ assert(NULL != object);
962+
963+ /* ブロック送信 */
964+ ymodem_block_senddo(object);
965+
966+ /* オフセットが末端まで到達したら状態遷移 */
967+ result = ymodem_check_offset(object);
968+ if (FALSE != result)
969+ {
970+ ymodem_object_trans(object, YMODEM_TRANS_DATAACK);
971+ }
972+}
973+
974+/*
975+ * YMODEM
976+ * データブロック送信
977+ * exit
978+ */
979+static void ymodem_senddata_exit(YMODEM_OBJECT *object)
980+{
981+}
982+
983+/*
984+ * YMODEM
985+ * データブロックACK待ち
986+ * enter
987+ */
988+static void ymodem_dataack_enter(YMODEM_OBJECT *object)
989+{
990+ assert(NULL != object);
991+
992+ /* 開始時間を初期化 */
993+ object->start_time = timeGetTime();
994+}
995+
996+/*
997+ * YMODEM
998+ * データブロックACK待ち
999+ * do
1000+ */
1001+static void ymodem_dataack_do(YMODEM_OBJECT *object)
1002+{
1003+ BYTE buf;
1004+ BOOL result;
1005+
1006+ assert(NULL != object);
1007+
1008+ /* 送信時の受信キャラクタ待ち */
1009+ buf = ymodem_wait_send(object);
1010+
1011+ switch (buf)
1012+ {
1013+ /* ACK */
1014+ case YMODEM_ACK:
1015+ /* ACKは次のブロックまたはEOT送信 */
1016+ if ((object->block_offset + 0x80) <= object->file_size)
1017+ {
1018+ /* リトライ回数を初期化 */
1019+ object->retry = 0;
1020+
1021+ /* EOT送信 */
1022+ ymodem_object_trans(object, YMODEM_TRANS_SENDEOT);
1023+ }
1024+ else
1025+ {
1026+ /* リトライ回数を初期化 */
1027+ object->retry = 0;
1028+
1029+ /* ブロック番号を進める */
1030+ object->block_no = (object->block_no + 1) & 0xff;
1031+
1032+ /* ブロックオフセットを進める */
1033+ object->block_offset += 0x80;
1034+
1035+ /* データブロック送信 */
1036+ ymodem_object_trans(object, YMODEM_TRANS_SENDDATA);
1037+ }
1038+ break;
1039+
1040+ /* NAK */
1041+ case YMODEM_NAK:
1042+ /* NAKはリトライチェック */
1043+ result = ymodem_check_retry(object, YMODEM_SEND_RETRY);
1044+ if (FALSE != result)
1045+ {
1046+ /* リトライエラー */
1047+ ymodem_error_retry(object);
1048+ return;
1049+ }
1050+ else
1051+ {
1052+ /* データブロックを再送 */
1053+ ymodem_object_trans(object, YMODEM_TRANS_SENDDATA);
1054+ }
1055+ break;
1056+
1057+ /* その他は何もしない */
1058+ default:
1059+ break;
1060+ }
1061+}
1062+
1063+/*
1064+ * YMODEM
1065+ * データブロックACK待ち
1066+ * exit
1067+ */
1068+static void ymodem_dataack_exit(YMODEM_OBJECT *object)
1069+{
1070+}
1071+
1072+/*
1073+ * YMODEM
1074+ * EOT送信
1075+ * enter
1076+ */
1077+static void ymodem_sendeot_enter(YMODEM_OBJECT *object)
1078+{
1079+}
1080+
1081+/*
1082+ * YMODEM
1083+ * EOT送信
1084+ * do
1085+ */
1086+static void ymodem_sendeot_do(YMODEM_OBJECT *object)
1087+{
1088+ UINT result;
1089+ BYTE buf;
1090+
1091+ assert(NULL != object);
1092+
1093+ /* EOT送信 */
1094+ buf = YMODEM_EOT;
1095+ result = comm_send(object->comm_index, &buf, sizeof(buf));
1096+ if (0 == result)
1097+ {
1098+ /* 書き込みに失敗した */
1099+ ymodem_error_closed(object);
1100+ }
1101+ else
1102+ {
1103+ /* 状態遷移 */
1104+ ymodem_object_trans(object, YMODEM_TRANS_EOTACK);
1105+ }
1106+}
1107+
1108+/*
1109+ * YMODEM
1110+ * EOT送信
1111+ * exit
1112+ */
1113+static void ymodem_sendeot_exit(YMODEM_OBJECT *object)
1114+{
1115+}
1116+
1117+/*
1118+ * YMODEM
1119+ * EOTに対するACK待ち
1120+ * enter
1121+ */
1122+static void ymodem_eotack_enter(YMODEM_OBJECT *object)
1123+{
1124+ assert(NULL != object);
1125+
1126+ /* 開始時間を初期化 */
1127+ object->start_time = timeGetTime();
1128+}
1129+
1130+/*
1131+ * YMODEM
1132+ * EOTに対するACK待ち
1133+ * do
1134+ */
1135+static void ymodem_eotack_do(YMODEM_OBJECT *object)
1136+{
1137+ assert(NULL != object);
1138+
1139+ BYTE buf;
1140+ BOOL result;
1141+
1142+ assert(NULL != object);
1143+
1144+ /* 送信時の受信キャラクタ待ち */
1145+ buf = ymodem_wait_send(object);
1146+
1147+ switch (buf)
1148+ {
1149+ /* ACK */
1150+ case YMODEM_ACK:
1151+ /* ACKは送信終了 */
1152+ object->sending = FALSE;
1153+ object->status = YMODEM_SUCCESS;
1154+ break;
1155+
1156+ /* NAK */
1157+ case YMODEM_NAK:
1158+ /* NAKはリトライチェック */
1159+ result = ymodem_check_retry(object, YMODEM_SEND_RETRY);
1160+ if (FALSE != result)
1161+ {
1162+ /* リトライエラー */
1163+ ymodem_error_retry(object);
1164+ return;
1165+ }
1166+ else
1167+ {
1168+ /* EOTを再送 */
1169+ ymodem_object_trans(object, YMODEM_TRANS_SENDEOT);
1170+ }
1171+ break;
1172+
1173+ /* その他は何もしない */
1174+ default:
1175+ break;
1176+ }
1177+}
1178+
1179+/*
1180+ * YMODEM
1181+ * EOTに対するACK待ち
1182+ * exit
1183+ */
1184+static void ymodem_eotack_exit(YMODEM_OBJECT *object)
1185+{
1186+}
1187+
1188+/*
1189+ * YMODEM
1190+ * オブジェクト状態遷移要求
1191+ */
1192+static void ymodem_object_trans(YMODEM_OBJECT *object, UINT state)
1193+{
1194+ assert(NULL != object);
1195+
1196+ /* exit処理 */
1197+ switch (object->state)
1198+ {
1199+ /* 初期状態 */
1200+ case YMODEM_TRANS_NONE:
1201+ break;
1202+
1203+ /* 受信側の'C'送信待ち(1) */
1204+ case YMODEM_TRANS_WAITC1:
1205+ ymodem_waitc1_exit(object);
1206+ break;
1207+
1208+ /* ファイル情報の送信 */
1209+ case YMODEM_TRANS_SENDINFO:
1210+ ymodem_sendinfo_exit(object);
1211+ break;
1212+
1213+ /* ファイル情報ACK待ち */
1214+ case YMODEM_TRANS_INFOACK:
1215+ ymodem_infoack_exit(object);
1216+ break;
1217+
1218+ /* 受信側の'C'送信待ち(2) */
1219+ case YMODEM_TRANS_WAITC2:
1220+ ymodem_waitc2_exit(object);
1221+ break;
1222+
1223+ /* データブロック送信 */
1224+ case YMODEM_TRANS_SENDDATA:
1225+ ymodem_senddata_exit(object);
1226+ break;
1227+
1228+ /* データブロックACK待ち */
1229+ case YMODEM_TRANS_DATAACK:
1230+ ymodem_dataack_exit(object);
1231+ break;
1232+
1233+ /* EOT送信 */
1234+ case YMODEM_TRANS_SENDEOT:
1235+ ymodem_sendeot_exit(object);
1236+ break;
1237+
1238+ /* EOTに対するACK待ち */
1239+ case YMODEM_TRANS_EOTACK:
1240+ ymodem_eotack_exit(object);
1241+ break;
1242+ }
1243+
1244+ /* 状態変更 */
1245+ object->state = state;
1246+
1247+ /* enter処理 */
1248+ switch (object->state)
1249+ {
1250+ /* 受信側の'C'送信待ち(1) */
1251+ case YMODEM_TRANS_WAITC1:
1252+ ymodem_waitc1_enter(object);
1253+ break;
1254+
1255+ /* ファイル情報の送信 */
1256+ case YMODEM_TRANS_SENDINFO:
1257+ ymodem_sendinfo_enter(object);
1258+ break;
1259+
1260+ /* ファイル情報ACK待ち */
1261+ case YMODEM_TRANS_INFOACK:
1262+ ymodem_infoack_enter(object);
1263+ break;
1264+
1265+ /* 受信側の'C'送信待ち(2) */
1266+ case YMODEM_TRANS_WAITC2:
1267+ ymodem_waitc2_enter(object);
1268+ break;
1269+
1270+ /* データブロック送信 */
1271+ case YMODEM_TRANS_SENDDATA:
1272+ ymodem_senddata_enter(object);
1273+ break;
1274+
1275+ /* データブロックACK待ち */
1276+ case YMODEM_TRANS_DATAACK:
1277+ ymodem_dataack_enter(object);
1278+ break;
1279+
1280+ /* EOT送信 */
1281+ case YMODEM_TRANS_SENDEOT:
1282+ ymodem_sendeot_enter(object);
1283+ break;
1284+
1285+ /* EOTに対するACK待ち */
1286+ case YMODEM_TRANS_EOTACK:
1287+ ymodem_eotack_enter(object);
1288+ break;
1289+ }
1290+}
1291+
1292+/*
1293+ * YMODEM
1294+ * オブジェクトアイドル
1295+ */
1296+static void ymodem_object_idle(YMODEM_OBJECT *object)
1297+{
1298+ assert(NULL != object);
1299+
1300+ /* 送信中または受信中のどちらでもなければ、何もしない */
1301+ if ((FALSE == object->sending) && (FALSE == object->receiving))
1302+ {
1303+ return;
1304+ }
1305+
1306+ /* do処理 */
1307+ assert(YMODEM_TRANS_NONE != object->state);
1308+ switch (object->state)
1309+ {
1310+ /* 受信側の'C'送信待ち(1) */
1311+ case YMODEM_TRANS_WAITC1:
1312+ ymodem_waitc1_do(object);
1313+ break;
1314+
1315+ /* ファイル情報の送信 */
1316+ case YMODEM_TRANS_SENDINFO:
1317+ ymodem_sendinfo_do(object);
1318+ break;
1319+
1320+ /* ファイル情報ACK待ち */
1321+ case YMODEM_TRANS_INFOACK:
1322+ ymodem_infoack_do(object);
1323+ break;
1324+
1325+ /* 受信側の'C'送信待ち(2) */
1326+ case YMODEM_TRANS_WAITC2:
1327+ ymodem_waitc2_do(object);
1328+ break;
1329+
1330+ /* データブロック送信 */
1331+ case YMODEM_TRANS_SENDDATA:
1332+ ymodem_senddata_do(object);
1333+ break;
1334+
1335+ /* データブロックACK待ち */
1336+ case YMODEM_TRANS_DATAACK:
1337+ ymodem_dataack_do(object);
1338+ break;
1339+
1340+ /* EOT送信 */
1341+ case YMODEM_TRANS_SENDEOT:
1342+ ymodem_sendeot_do(object);
1343+ break;
1344+
1345+ /* EOTに対するACK待ち */
1346+ case YMODEM_TRANS_EOTACK:
1347+ ymodem_eotack_do(object);
1348+ break;
1349+ }
1350+}
1351+
1352+/*
1353+ * YMODEM
1354+ * オブジェクト送信開始
1355+ */
1356+static BOOL ymodem_object_send(YMODEM_OBJECT *object, const char *filename, UINT filesize)
1357+{
1358+ size_t namelen;
1359+ BOOL result;
1360+
1361+ assert(NULL != object);
1362+ assert(NULL != filename);
1363+
1364+ /* 送信中または受信中であればエラー */
1365+ assert((FALSE == object->sending) && (FALSE == object->receiving));
1366+ if ((FALSE != object->sending) || (FALSE != object->receiving))
1367+ {
1368+ /* 送信中または受信中である */
1369+ return FALSE;
1370+ }
1371+
1372+ /* ファイルネームが許容値以上であればエラー */
1373+ namelen = strlen(filename);
1374+ assert(namelen < _countof(object->file_name));
1375+ if (namelen >= _countof(object->file_name))
1376+ {
1377+ /* ファイルネームが長すぎる */
1378+ return FALSE;
1379+ }
1380+
1381+ /* ファイルサイズがバッファサイズを超えていればエラー */
1382+ assert(filesize <= sizeof(object->file_buf));
1383+ if (filesize > sizeof(object->file_buf))
1384+ {
1385+ /* ファイルサイズが大きすぎる */
1386+ return FALSE;
1387+ }
1388+
1389+ /* 通信ポートがオープンできなければエラー */
1390+ result = comm_open(object->comm_index);
1391+ if (FALSE == result)
1392+ {
1393+ return FALSE;
1394+ }
1395+
1396+ /* 送信中 */
1397+ object->sending = TRUE;
1398+
1399+ /* BUSY */
1400+ object->status = YMODEM_BUSY;
1401+
1402+ /* ファイルネーム */
1403+ strcpy_s(object->file_name, _countof(object->file_name), filename);
1404+
1405+ /* ファイルサイズ */
1406+ object->file_size = filesize;
1407+
1408+ /* 状態遷移 */
1409+ ymodem_object_trans(object, YMODEM_TRANS_WAITC1);
1410+
1411+ /* 成功 */
1412+ return TRUE;
1413+}
1414+
211415 /*
221416 * YMODEM
231417 * 初期化
241418 */
251419 void ymodem_init(UINT comm_index)
261420 {
1421+ /* オブジェクト初期化 */
1422+ ymodem_object_init(&g_ymodem_object, comm_index);
271423 }
281424
291425 /*
@@ -32,6 +1428,8 @@ void ymodem_init(UINT comm_index)
321428 */
331429 void ymodem_idle(void)
341430 {
1431+ /* オブジェクトアイドル */
1432+ ymodem_object_idle(&g_ymodem_object);
351433 }
361434
371435 /*
@@ -40,7 +1438,10 @@ void ymodem_idle(void)
401438 */
411439 BOOL ymodem_send(const char* filename, UINT filesize)
421440 {
43- return FALSE;
1441+ assert(NULL != filename);
1442+
1443+ /* オブジェクト送信開始 */
1444+ return ymodem_object_send(&g_ymodem_object, filename, filesize);
441445 }
451446
461447 /*
@@ -61,9 +1462,29 @@ UINT ymodem_get_status(void)
611462 return 0;
621463 }
631464
64-/* ファイルネーム取得 */
1465+/*
1466+ * YMODEM
1467+ * ファイルネーム取得
1468+ */
651469 const char* ymodem_get_filename(void)
661470 {
671471 return NULL;
681472 }
691473
1474+/*
1475+ * YMODEM
1476+ * ファイルサイズ取得
1477+ */
1478+UINT ymodem_get_filesize(void)
1479+{
1480+ return 0;
1481+}
1482+
1483+/*
1484+ * YMODEM
1485+ * バッファポインタ取得
1486+ */
1487+BYTE* ymodem_get_filebuf(void)
1488+{
1489+ return NULL;
1490+}
--- a/DebugMonitor/src/comm/ymodem.h
+++ b/DebugMonitor/src/comm/ymodem.h
@@ -11,12 +11,14 @@
1111 * 定数
1212 */
1313
14+/* ステータス */
1415 #define YMODEM_SUCCESS 0 /* 成功 */
1516 #define YMODEM_BUSY 1 /* 動作中 */
1617 #define YMODEM_SIZEOVER 2 /* バッファサイズ溢れ */
1718 #define YMODEM_TIMEOUT 3 /* タイムアウト */
18-#define YMODEM_CANCEL 4 /* キャンセル要求受信 */
19-#define YMODEM_CLOSED 5 /* ポートクローズ */
19+#define YMODEM_RETRY 4 /* リトライオーバー */
20+#define YMODEM_CANCEL 5 /* キャンセル要求受信 */
21+#define YMODEM_CLOSED 6 /* ポートクローズ */
2022
2123 /*
2224 * グローバル関数
@@ -44,4 +46,4 @@ const char* ymodem_get_filename(void);
4446 UINT ymodem_get_filesize(void);
4547
4648 /* バッファポインタ取得 */
47-LPBYTE ymodem_get_filebuf(void);
49+BYTE* ymodem_get_filebuf(void);