Бинарное чтение последовательного порта иногда портит данные - PullRequest
0 голосов
/ 09 сентября 2018

У меня есть последовательный порт. Другая программа записывает в последовательный порт каждые 0,2 секунды. Каждый раз данные, записываемые в последовательный порт, всегда имеют длину 83 байта. Серийный порт можно правильно прочитать с помощью minicom.

У меня есть программа, которая может читать последовательный порт. Каждый раз поток байтов записывается в последовательный порт:

65 66 67 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90

В большинстве случаев данные могут быть получены правильно. Однако иногда данные путаются. Как только данные испорчены, почти все входящие сообщения испорчены.

Иногда я получаю вывод из своего кода как:

65 0 66 67 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 65 66 67

Это странно. Поскольку, по-видимому, после первых 65 есть 0. Кроме того, последние три байта равны 65 66 67, что выглядит как начало нового сообщения.

Код для открытия и настройки последовательного порта:

int serial_fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY|O_NONBLOCK);
if (serial_fd < 0) {
    return -1;
}

struct termios options;
tcgetattr(serial_fd, &options);
options.c_cflag |= (CLOCAL | CREAD);
//8N1 mode
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
options.c_cflag &= ~CSTOPB;
options.c_cflag &=~PARENB;
options.c_cflag &= ~CRTSCTS;

options.c_lflag &= ~(ICANON|ECHO|ECHONL|ISIG|IEXTEN); 
options.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
options.c_oflag &= ~OPOST;  
cfsetospeed(&options, B115200);
cfsetispeed(&options, B115200);
tcsetattr(serial_fd, TCSANOW, &options);
tcflush(serial_fd, TCIFLUSH);

Код для чтения из последовательного порта и распечатки полученного сообщения:

uint8_t *buff,buff_data[100];
buff = buff_data;
int len,fs_sel;
fd_set fs_read;

int expectedLength=83;
int len_acc = 0;

while(1){
    FD_ZERO(&fs_read); 
    FD_SET(serial_fd, &fs_read);
    fs_sel = select(serial_fd+1,&fs_read,NULL,NULL,NULL);
    if(fs_sel)   
    {
        len = read(serial_fd, buff, expectedLength-len_acc);
        if (len<=0) continue;
        len_acc += len;
        if (len_acc < expectedLength) {
            buff += len;
            continue;
        }
        len_acc = 0;
        buff = buff_data;
        for (int i=0; i<expectedLength; i++){
            std::cout <<(int)buff[i]<<" ";
        }
        std::cout<< std::endl;
    }
}

Спасибо за вашу помощь.

...