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

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

ただいまの
回答率

90.85%

  • Linux

    3297questions

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

  • C++

    3019questions

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

  • シリアルポート

    32questions

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

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

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 884

NEWBIEEBIEE

score 37

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

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

実装している自作関数

static int xmodem_receive(int serial_fd, char* filename){
    int skip = 0;
    uint8_t sdACK = X_ACK;
    uint8_t eof = X_EOF;
    uint8_t sdNAK = X_NAK;
    uint8_t recSTX; // receive SOH from chunk
    uint8_t recBlk; // receive blk from chunk
    uint8_t recNegBlk; // receive blk negative from chunk
    uint8_t recData[1024]; // receive data from chunk
    uint16_t recChksum;
    FILE *fp;
    int ret, fd;
    struct stat stat;
    // If we want to receive, We have to send NAK to Sendor.



        /* binary write */
    fp = fopen(filename, "wb");
    //Send NAK still read SOH that header of one data chunks
        while(1){
            printf("Waiting for receiver ping ...");
            fflush(stdout);
            //
            do {
                    // send NAK before read SOH
                    ret = write(serial_fd, &sdNAK, sizeof(sdNAK));
                    // after sending NAK,receiving SOH from chunk
                    ret = read(serial_fd, &recSTX, sizeof(recSTX));
                    if (ret != sizeof(recSTX)) {
                            perror("read");
                            return -errno;
                    }
            } while (recSTX != X_STX);

            //So next, receiving blk
            ret = read(serial_fd, &recBlk, sizeof(recBlk));
            if (ret != sizeof(recBlk)) {
                perror("read");
                return -errno;
            }
            ret = read(serial_fd, &recNegBlk, sizeof(recNegBlk));
            if (ret != sizeof(recNegBlk)) {
                perror("read");
                return -errno;
            }
            ret = read(serial_fd, &recData, sizeof(recData));
            if (ret != sizeof(recData)) {
                perror("read");
                return -errno;
            }
            ret = read(serial_fd, &recChksum, sizeof(recChksum));
            if (ret != sizeof(recChksum)) {
                perror("read");
                return -errno;
            }
            // data block number check
            if(recBlk == 0xff - recNegBlk){
                perror("read");
                return -errno;
            }
            // data integrity check
            if(recChksum == swap16(crc16(recData, sizeof(recData)))){
                perror("read");
                return -errno;
            }
            // check of appended "0xff" from end of data to  end of chunk in chunk
            unsigned char *ptr = recData;
            ptr += sizeof(recData);
            while(*ptr == 0xff){
                ptr--;
            }
            fwrite(recData, (ptr - recData),1,fp); // write Datas bytes from our buffer
            // set skip flag or end connect
            ret = write(serial_fd, &eof, sizeof(uint8_t));
            if (ret != sizeof(eof) || ret != sizeof(X_STX)){
                return -errno;
            }else{
                if(ret == X_STX){
                    skip = 1;
                }else if(ret == EOF){
                    printf("EOF ...");
                    ret = write(serial_fd, &sdACK, sizeof(sdACK));
                    break;
                }else{
                    return -errno;
                }
            }

        }
    printf("done.\n");
    fclose(fp);
    return 0;

}

main関数内での呼び出し

int main(int argc, char **argv)
{
        int a, ret, serial_fd;

        serial_fd = open_serial("/dev/ttyUSB0", 115200);
        if (serial_fd < 0)
                return -errno;


        if(argv[2] == "0" || argv[2] == NULL){
            ret = xymodem_send(serial_fd, argv[1], PROTOCOL_XMODEM, 1);
            if (ret < 0)
                return ret;
        }

        if(argv[2] == "1"){
            ret = xmodem_receive(serial_fd, argv[1]);
            if (ret < 0)
                return ret;
        }


        return 0;
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+2

こんにちは。

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 23:39

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

    キャンセル

  • 2017/01/07 00:21

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

    キャンセル

+1

まず初歩的ですが、

argv[2] == "0" 
argv[2] == "1"


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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/01/06 23:41

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

    キャンセル

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

  • ただいまの回答率 90.85%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Linux

    3297questions

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

  • C++

    3019questions

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

  • シリアルポート

    32questions

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