質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

シリアルポート

シリアルポートは一度に一ビットごと移行される物理的なインターフェイスです。一般的には、9ピンのd-subコネクタであるRS-232を指します。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

2969閲覧

c++によるXMODEMの受信関数を作っているが、dataの読み込みする前に終了する

NEWBIEEBIEE

総合スコア62

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

シリアルポート

シリアルポートは一度に一ビットごと移行される物理的なインターフェイスです。一般的には、9ピンのd-subコネクタであるRS-232を指します。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

1グッド

0クリップ

投稿2017/01/07 04:26

編集2017/01/08 06:18

失礼します。
昨日ここのサイトでお世話になった者です。
引き続きよろしくお願いします。
こちらのコードですが、ここ(https://gist.github.com/zonque/0ae2dc8cedbcdbd9b933)のサイトのコードを元に、xmodem_receiveという関数を新たに実装し,XMODEMのデータ受信をしたいと思っております。
作成した関数なのですが、途中で何故か終了してしまいます。
受信側のxmodem_receiveは"Sending C ping..."でファイル送信の合図である'C'を送信側に対しておくることができており、その後、送信側はファイルの送信を行っているようなのですが
送信側
受信側のxmodem_receiveはそこで終了します。
受信側
データの受信を続けたいのですが、
肝心のデータ受信部分が動作しません。
データを受け取らずに終了してしまいます。
プログラムの構成がいけないのでしょうか
また、STKを
データから受信する際にprintfで出力したら
if文の(recSTX == X_STX)で通るにもかかわらず
’K’と出てくるのはなぜなのでしょうか。

ご教授お願いします

全体のコードはこちらの最下部にあります(http://stackoverflow.com/questions/41502457/my-implementation-of-xmodem-receiving-function-is-not-working)
わたしが実装した関数

c++

1 2static int xmodem_receive(int serial_fd, char* filename, int _crc){ 3 int skip = 0; 4 uint8_t sdCRC = 'C'; 5 uint8_t sdACK = X_ACK; 6 uint8_t eof = X_EOF; 7 uint8_t sdNAK = X_NAK; 8 uint8_t recSTX; // receive SOH from chunk 9 uint8_t recBlk; // receive blk from chunk 10 uint8_t recNegBlk; // receive blk negative from chunk 11 uint8_t recData[1024]; // receive data from chunk 12 uint16_t recChksum; 13 FILE *fp; 14 int ret, fd; 15 struct stat stat; 16 // If we want to receive, We have to send NAK to Sendor. 17 18 19 20 /* バイナリ書き込み読み込みモードでファイルをオープン */ 21 fp = fopen(filename, "wb"); 22 //Send NAK still read SOH that header of one data chunks 23 while(1){ 24 char status; 25 printf("Waiting for sender ping ..."); 26 fflush(stdout); 27 // 28 do { 29 if(_crc){ 30 printf("Send C ping....\n"); 31 ret = write(serial_fd, &sdCRC, sizeof(sdCRC)); 32 }else{ 33 // send NAK before read SOH 34 printf("Send NAK ping....\n"); 35 ret = write(serial_fd, &sdNAK, sizeof(sdNAK)); 36 } // after sending NAK,receiving SOH from chunk 37 fflush(stdout); 38 ret = read(serial_fd, &recSTX, sizeof(recSTX)); 39 40 41 if(recSTX == X_STX){ 42 printf("STX is %c\n", &recSTX); 43 }else{ 44 printf("Garabage payload %c\n", &recSTX); 45 } 46 fflush(stdout); 47 if (ret != sizeof(recSTX)) { 48 printf("Not working"); 49 fflush(stdout); 50 perror("read"); 51 return -errno; 52 } 53 } while (recSTX != X_STX); 54 55 //So next, receiving blk 56 ret = read(serial_fd, &recBlk, sizeof(recBlk)); 57 printf("Block Num is %d\n", recBlk); 58 fflush(stdout); 59 if (ret != sizeof(recBlk)) { 60 perror("read"); 61 return -errno; 62 } 63 ret = read(serial_fd, &recNegBlk, sizeof(recNegBlk)); 64 printf("Negative Block Num is %d\n", recNegBlk); 65 fflush(stdout); 66 if (ret != sizeof(recNegBlk)) { 67 perror("read"); 68 return -errno; 69 } 70 ret = read(serial_fd, (void *)&recData, sizeof(recData)); 71 printf("Data buffer is %c\n", &recData); 72 fflush(stdout); 73 if (ret != sizeof(recData)) { 74 perror("read"); 75 return -errno; 76 } 77 ret = read(serial_fd, &recChksum, sizeof(recChksum)); 78 printf("Check sum is %c", &recChksum); 79 fflush(stdout); 80 if (ret != sizeof(recChksum)) { 81 perror("read"); 82 return -errno; 83 } 84 // data block number check 85 if(recBlk == 0xff - recNegBlk){ 86 perror("read"); 87 return -errno; 88 } 89 // data integrity check 90 if(recChksum == swap16(crc16(recData, sizeof(recData)))){ 91 perror("read"); 92 return -errno; 93 } 94 // check of appended "0xff" from end of data to end of chunk in chunk 95 unsigned char *ptr = recData; 96 ptr += sizeof(recData); 97 while(*ptr == 0xff){ 98 ptr--; 99 } 100 fwrite(recData, (ptr - recData),1,fp); // write Datas bytes from our buffer 101 // set skip flag or end connect 102 ret = write(serial_fd, &eof, sizeof(uint8_t)); 103 if (ret != sizeof(eof) || ret != sizeof(X_STX)){ 104 return -errno; 105 }else{ 106 if(ret == X_STX){ 107 skip = 1; 108 }else if(ret == EOF){ 109 printf("EOF ..."); 110 ret = write(serial_fd, &sdACK, sizeof(sdACK)); 111 break; 112 }else{ 113 return -errno; 114 } 115 } 116 117 } 118 printf("done.\n"); 119 fclose(fp); 120 return 0; 121 122} 123

main関数

c++

1int main(int argc, char **argv) 2{ 3 int a, ret, serial_fd; 4 5 printf("STX: %c\n", X_STX); 6 7 printf("ACK: %c\n", X_ACK); 8 9 printf("NAK: %c\n", X_NAK); 10 11 printf("EOF: %c\n", X_EOF); 12 13 fflush(stdout); 14 15 serial_fd = open_serial("/dev/ttyUSB0", 115200); 16 if (serial_fd < 0) 17 return -errno; 18 19 20 if(std::string(argv[2]) == "0" || std::string(argv[2]) == "0"){ 21 ret = xymodem_send(serial_fd, argv[1], PROTOCOL_XMODEM, 1); 22 if (ret < 0) 23 return ret; 24 } 25 26 if(std::string(argv[2]) == "1"){ 27 ret = xmodem_receive(serial_fd, argv[1], 1); 28 if (ret < 0) 29 return ret; 30 } 31 32 33 return 0; 34} 35 36
退会済みユーザー👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Chironian

2017/01/07 06:58 編集

受信側に問題がありそうですので、受信側の画面を載せた方が回答しやすいです。また、デバッグ用にprintf()する時は常にfflush()しておいた方が良いです。printf()だけですとバッファに溜まって画面にでるのが遅れますので。
guest

回答2

0

こんにちは。

最初のSTX is Kは期待通りの動作でしょうか?
期待通りでないなら、それが何故なのか追跡しましょう。
どうしても分からない場合に、何故このように表示されるのか質問した方が良いと思いますよ。

皆さんポランティアですから、丸投げされると回答しづらいです。

投稿2017/01/07 08:52

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

NEWBIEEBIEE

2017/01/08 05:41

申し訳ございません。配慮の足りなさを憂いています。
guest

0

ベストアンサー

途中で何故か終了してしまいます。

stackoverflowでも指摘されていると思いますが・・・

受信側のプログラムコードの各関数の返り元が正常かどうか、どんな動きになっているかなどの情報が書かれていないので質問者さん自身のデバッグが充分に行われていないように見えます。例えばCRC/NAKをwriteした結果を変数に受けているだけでチェックしてませんし・・・

CRC/NAKのwriteが失敗するということを示唆しているわけではありません。それらも含めてコードの動作を充分に確認・把握していないように見えるという点を指摘しているつもりです。「途中で何故か終了してしまいます。 」ではなく最低限「このコードのここの関数の結果がこうなったためにプログラムが終了しているがそれがなぜそのような動きになるかわからない」という質問の仕方にすべきではないでしょうか?

投稿2017/01/07 07:21

KSwordOfHaste

総合スコア18392

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

NEWBIEEBIEE

2017/01/07 08:43

ご指摘のほどありがとうございます。
KSwordOfHaste

2017/01/08 08:52 編集

多分こうした質問をする背景には「動くはずなのに何故動かないんだ」という気持ちがあるだろうと思います。自分もプログラマーの端くれなのでその気持ちはわかるのです。しかし最小限のデバッグをするということは知識の多い少ないにかかわらずできるはずです。その結果「なぜこうなるんだろう」となったときが難しいと思うんです。そのタイミングで質問するとよい質問になると思います。デバッグ頑張ってくださいね!
NEWBIEEBIEE

2017/01/08 05:42

ありがとうございます。勉強にさせていただきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問