1

C を使用して Linux で ttyS0 シリアル ポートをプログラムする方法を学習しようとしています。別のマシンがシリアル ポートに接続されており、約 2 秒ごとに 5f と 6f の 16 進値を交互に送信しています。これらの値がポートに表示されていることを他のポート監視アプリで確認しました。私のコードでは、ブロッキングread()を 10 文字の長さのバッファに使用しています。私の他のマシンはまだデータを送信していますが、read()は永遠にブロックされます。行fcntl(fd, F_SETFL, FNDELAY);を含めた場合read() を非ブロッキング read() に設定すると、常に -1 の値が返されます。これは、UART バッファーにデータがなく、for ループ コードがバッファーにあるランダムな値を出力することを意味します。要するに、私のコードは ttyS0 を読み取っていないということであり、その理由はわかりません。以下は私のコードです。うまくいけば、誰かが私の問題の原因を見つけて、私をまっすぐにしてくれることを願っています。ちなみに、私は Scientific Linux を使用しています。RedHat や Fedora と同様に、ttyS0 は com ポート 1 だと思います。以下は、コードを実行したときの出力です。COM ポートへの書き込みは問題なく行われているようですが、読み取りの場合は使用不可と表示されます。また、私が出力しているバッファは、読み込まれたデータではなく単なるランダムな値であることは明らかです。ありがとう

コンソール出力

hello world
hi again
write error: : Success
 wrote 4 bytes
number of bytes read is -1
read error:: Resource temporarily unavailable
4  8  120  -99  -73  -65  41  -120  4  8  
should of put something out

コード

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <unistd.h>

int main()
{
    printf("hello world\n");
    int n;
    int fd;
    char c;
    int bytes;

    char buffer[10];
    char *bufptr;
    int nbytes;
    int tries;
    int x;
    struct termios options;


    fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
    if(fd == -1)
    {
        perror("open_port: Unable to open:");
    }
    else
    {
        fcntl(fd, F_SETFL, 0);
        printf("hi again\n");
    }

    tcgetattr(fd, &options);

    cfsetispeed(&options, B115200);
    cfsetospeed(&options, B115200);
    options.c_cflag |= (CLOCAL | CREAD);
    options.c_cflag &= ~PARENB;
    options.c_cflag &= ~CSTOPB;
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS8;
    options.c_cflag &= ~( ICANON | ECHO | ECHOE |ISIG );
    options.c_iflag &= ~(IXON | IXOFF | IXANY );
    options.c_oflag &= ~OPOST;

    tcsetattr(fd, TCSANOW, &options);


    write(fd, "ATZ\r",4);
    printf(" wrote\n");
    bufptr = buffer;


    fcntl(fd, F_SETFL, FNDELAY);
     bytes = read(fd, bufptr, sizeof(buffer));
    printf("number of bytes read is %d\n", bytes);
    perror ("read error:");

    for (x = 0; x < 10 ; x++)
    {
        c = buffer[x];
        printf("%d  ",c);
    }
    close(fd);

    //puts(buffer[0]);
    printf("\nshould of put something out \n");

    return (0);
}
4

1 に答える 1

0

MINおよび/またはTIME値を設定してみてください:

/*...*/
options.c_cc[VMIN] = 1; //read() will return after receiving 1 character
options.c_cc[VTIME] = 0; // == 0 - infinite timeout, != 0 - sets timeout in deciseconds
/*...*/
tcsetattr(fd, TCSANOW, &options);

与えられた例では、シンボルを取得した後に戻り、入力を無期限に待機するように read() を設定します。もちろん、必要に応じてこれらのパラメータを変更することもできます (たとえば、必要に応じて MIN を 10 に設定します)。

fcntl(fd, F_SETFL, FNDELAY);ただし、これを機能させるには呼び出しを削除することをお勧めします。

プログラムを終了する前に、以前の termios 設定を保存して復元することも賢明です。

于 2012-04-21T05:16:05.553 に答える