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

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

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

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

シリアルポート

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

C++

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

Q&A

解決済

2回答

6327閲覧

c/c++によるシリアル通信の実装について

NEWBIEEBIEE

総合スコア62

Linux

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

シリアルポート

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

C++

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

0グッド

0クリップ

投稿2017/01/06 11:43

編集2017/01/06 11:44

現在、こちらのサイト(https://gist.github.com/zonque/0ae2dc8cedbcdbd9b933)のコードをもとに自作関数を実装しています。
自作している関数はXMODEMを受け取る関数について自作しています。
名前は xmodem_receiveです。
しかし、main関数内で実行すると送信を待たず、エラーもなくすぐに終了してしまいます。
どうしてなのでしょうか。

static_cast<uint8_t*>"を使ているのでタグはc/c++とさせて頂きます。

実装している自作関数

C/C++

1static int xmodem_receive(int serial_fd, char* filename){ 2 int skip = 0; 3 uint8_t sdACK = X_ACK; 4 uint8_t eof = X_EOF; 5 uint8_t sdNAK = X_NAK; 6 uint8_t recSTX; // receive SOH from chunk 7 uint8_t recBlk; // receive blk from chunk 8 uint8_t recNegBlk; // receive blk negative from chunk 9 uint8_t recData[1024]; // receive data from chunk 10 uint16_t recChksum; 11 FILE *fp; 12 int ret, fd; 13 struct stat stat; 14 // If we want to receive, We have to send NAK to Sendor. 15 16 17 18 /* binary write */ 19 fp = fopen(filename, "wb"); 20 //Send NAK still read SOH that header of one data chunks 21 while(1){ 22 printf("Waiting for receiver ping ..."); 23 fflush(stdout); 24 // 25 do { 26 // send NAK before read SOH 27 ret = write(serial_fd, &sdNAK, sizeof(sdNAK)); 28 // after sending NAK,receiving SOH from chunk 29 ret = read(serial_fd, &recSTX, sizeof(recSTX)); 30 if (ret != sizeof(recSTX)) { 31 perror("read"); 32 return -errno; 33 } 34 } while (recSTX != X_STX); 35 36 //So next, receiving blk 37 ret = read(serial_fd, &recBlk, sizeof(recBlk)); 38 if (ret != sizeof(recBlk)) { 39 perror("read"); 40 return -errno; 41 } 42 ret = read(serial_fd, &recNegBlk, sizeof(recNegBlk)); 43 if (ret != sizeof(recNegBlk)) { 44 perror("read"); 45 return -errno; 46 } 47 ret = read(serial_fd, &recData, sizeof(recData)); 48 if (ret != sizeof(recData)) { 49 perror("read"); 50 return -errno; 51 } 52 ret = read(serial_fd, &recChksum, sizeof(recChksum)); 53 if (ret != sizeof(recChksum)) { 54 perror("read"); 55 return -errno; 56 } 57 // data block number check 58 if(recBlk == 0xff - recNegBlk){ 59 perror("read"); 60 return -errno; 61 } 62 // data integrity check 63 if(recChksum == swap16(crc16(recData, sizeof(recData)))){ 64 perror("read"); 65 return -errno; 66 } 67 // check of appended "0xff" from end of data to end of chunk in chunk 68 unsigned char *ptr = recData; 69 ptr += sizeof(recData); 70 while(*ptr == 0xff){ 71 ptr--; 72 } 73 fwrite(recData, (ptr - recData),1,fp); // write Datas bytes from our buffer 74 // set skip flag or end connect 75 ret = write(serial_fd, &eof, sizeof(uint8_t)); 76 if (ret != sizeof(eof) || ret != sizeof(X_STX)){ 77 return -errno; 78 }else{ 79 if(ret == X_STX){ 80 skip = 1; 81 }else if(ret == EOF){ 82 printf("EOF ..."); 83 ret = write(serial_fd, &sdACK, sizeof(sdACK)); 84 break; 85 }else{ 86 return -errno; 87 } 88 } 89 90 } 91 printf("done.\n"); 92 fclose(fp); 93 return 0; 94 95}

main関数内での呼び出し

c/c++

1 2int main(int argc, char **argv) 3{ 4 int a, ret, serial_fd; 5 6 serial_fd = open_serial("/dev/ttyUSB0", 115200); 7 if (serial_fd < 0) 8 return -errno; 9 10 11 if(argv[2] == "0" || argv[2] == NULL){ 12 ret = xymodem_send(serial_fd, argv[1], PROTOCOL_XMODEM, 1); 13 if (ret < 0) 14 return ret; 15 } 16 17 if(argv[2] == "1"){ 18 ret = xmodem_receive(serial_fd, argv[1]); 19 if (ret < 0) 20 return ret; 21 } 22 23 24 return 0; 25}

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

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

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

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

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

guest

回答2

0

ベストアンサー

こんにちは。

argv[2]にはコマンドライン引数の文字列が格納されているメモリへのポインタが入っています。
また、文字列定数の"0"や"1"はこれらの文字列が記録されているメモリへのポインタです。

仮にargv[2]の指す先の文字列が"1"だったとしても、それが格納されているメモリは文字列定数"1"が記録されているメモリとは別ものですから、argv[2] == "1"がtrueになることは期待できません。
int i=1, j=1;とした時、(i == j)ですが、(&i == &j)にならないのと同じ話です。
ですので、xmodem_receive()が呼ばれることはありません。

さて、せっかくC++を使うのでしたら、std::string(argv[2]) == "1"とすれば簡単に比較できます。
C言語に対するC++の便利良さの最大の1つはstd::stringと思います。

投稿2017/01/06 14:36

編集2017/01/06 14:38
Chironian

総合スコア23272

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

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

NEWBIEEBIEE

2017/01/06 14:39

ありがとうございます。今すぐとりかかります。
MasahikoHirata

2017/01/06 15:21

的確な回答ですね。以後の回答に参考になります。ありがとうございます。
guest

0

まず初歩的ですが、

C

1argv[2] == "0" 2

C

1argv[2] == "1"

が間違えではないでしょうか?
なぜ
strcmpを使用していないのですか?
文字列の比較は==では出来ません。

投稿2017/01/06 14:24

MasahikoHirata

総合スコア3747

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

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

NEWBIEEBIEE

2017/01/06 14:41

回答ありがとうございます。c++なら・・と浅はかでした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問