9

私はシリアルポートからデータを読み書きする必要があるプロジェクトに取り組んでいます。これは、説明しない理由で非ブロックである必要があります。select() 関数は私が使いたいもののように見えますが、機能する実装を取得するのに苦労しています。

open_port() では、ポートの設定を定義し、非ブロッキングであることを定義します。otherselect() では、記述子を open_port() に割り当て、読み取りを試みます。また、関数の最後に 1 秒のスリープ コールを設定して、読み取りがハードウェアにとって速すぎるのを回避しようとしています。

実行すると、メッセージを送信する前に「利用可能なデータがありません」というメッセージが毎秒出力され、メッセージを送信した後に出力されますが、通常はバイナリ文字と一緒にバラバラです。たとえば、「buffer」という単語を送信すると、「ffer」に続いてバイナリ文字が出力されます。

私はtermiosやselectの経験がほとんどないので、何か提案をいただければ幸いです。

#include <iostream>
#include "stdio.h"
#include "termios.h"
#include "errno.h"
#include "fcntl.h"
#include "string.h"
#include "time.h"
#include "sys/select.h"

using namespace std;

int open_port(){
struct termios oldtio,newtio;
int serial_fd;
if ((serial_fd = open("/dev/ttyS0", O_RDWR | O_EXCL | O_NDELAY)) == -1) {
    cout << "unable to open" << endl;
    return -1;
}
if (tcgetattr(serial_fd, &oldtio) == -1) {
    cout << "tcgetattr failed" << endl;
    return -1;
}
cfmakeraw(&newtio); // Clean all settings
newtio.c_cflag = (newtio.c_cflag & ~CSIZE) | CS8 | B115200; // 8 databits
newtio.c_cflag |= (CLOCAL | CREAD);
newtio.c_cflag &= ~(PARENB | PARODD); // No parity
newtio.c_cflag &= ~CRTSCTS; // No hardware handshake
newtio.c_cflag &= ~CSTOPB; // 1 stopbit
newtio.c_iflag = IGNBRK;
newtio.c_iflag &= ~(IXON | IXOFF | IXANY); // No software handshake
newtio.c_lflag = 0;
newtio.c_oflag = 0;
newtio.c_cc[VTIME] = 1;
newtio.c_cc[VMIN] = 60;
if (tcsetattr(serial_fd, TCSANOW, &newtio) == -1) {
    cout << "tcsetattr failed" << endl;
    return -1;
}
tcflush(serial_fd, TCIOFLUSH); // Clear IO buffer
return serial_fd;
}

void otherselect(){
fd_set readfs;
timeval tv;
tv.tv_sec = 1;
tv.tv_usec = 0;
char * buffer = new char[15];
int _fd = open_port();
FD_ZERO(&readfs);
FD_SET(_fd, &readfs);
select(_fd+1, &readfs, NULL, NULL, &tv /* no timeout */);
if (FD_ISSET(_fd, &readfs))
{
    int r = read(_fd, buffer, 15);
    if(r == -1){
        cout << strerror(errno) << endl;
    }
    cout << buffer << endl;
}
else{
    cout << "data not available" << endl;
}
close(_fd);
sleep(1);
}

int main() {
    while(1){
        otherselect();
    }
}
4

1 に答える 1

1

read() を使用すると、null で終了する文字列が得られないため、

cout<<buffer<<endl

明らかに悪い考えです。して、

buffer[r]='\0'  #(provided r<15)

印刷する前に。

于 2012-07-31T23:38:52.320 に答える