Почему я не могу достичь скорости выше 9600 бод по последовательному нуль-модемному кабелю?Linux

Ответить
Anonymous
 Почему я не могу достичь скорости выше 9600 бод по последовательному нуль-модемному кабелю?

Сообщение Anonymous »

Я написал пример последовательного порта Linux на C++, который просто использует функции открытия/чтения/записи/закрытия Linux API для связи по нуль-модемному кабелю с компьютером под управлением Windows, на котором я тестирую с помощью putty.Код работает нормально при запуске на скорости 9600 бод, но на более высоких скоростях на удаленном конце принимается тарабарщина и читается с удаленного конца в Linux, а на скорости 57600 или выше передача данных вообще не осуществляется.
Это должно быть код, потому что я могу запустить minicom на Linux со скоростью 115200 бод, и связь будет такой, как ожидалось.
Что мне нужно изменить, чтобы работать на более высоких скоростях передачи данных?
Например, запуск теста на скорости 9600 бод, вывод на стороне Linux:
angus@angus-Latitude-3550:~/Documents/code$ sudo ./serial_test
Attempting to open /dev/ttyUSB0
open returned 3
Setting timeout 2000 milliseconds
write returned 14
Enter some text on remote side and press any key to read the data

read returned 8
read data:
H i g u y s !
close returned 0
End of test

and Hello World! printed on putty screen on Windows


Но если скорость передачи увеличится до 19200:
angus@angus-Latitude-3550:~/Documents/code$ sudo ./serial_test
Attempting to open /dev/ttyUSB0
open returned 3
Setting timeout 2000 milliseconds
write returned 14
Enter some text on remote side and press any key to read the data

read returned 8
read data:
� � � � � � � �
close returned 0
End of test

и тарабарщина, напечатанная на шпатлевке в Windows.
Бредовые данные содержали символы 0xFE, 0xFC, 0xF7, т. е. недопустимые символы ascii.
Нуль-модемный кабель представляет собой чип FTDI, нуль-модемный кабель USB — USB NMC-2.5M — см. ссылку:
https://uk.rs-online.com/web/p/ development-tool-accessories/0537420?searchId=bbca5b6e-3586-4f43-8c3c-85c61071c58d&gb=s
На стороне Windows я использую следующие настройки последовательного порта putty:
скорость передачи 9600
биты данных 8
стоповые биты 1
четность нет
управление потоком нет
9600 работает, но не на более высоких скоростях.
Настройка выполняется на стороне Windows: 64-разрядная версия Windows 7 установлена ​​на Dell Precision T3600 с использованием putty для проверки последовательного порта. На стороне Linux – Dell Latitude 3550 под управлением Ubuntu 22.04 LTS.
В коде активно используется этот пример:
https://blog.mbedded.ninja/programming/ ... ems/linux/ linux-serial-ports-using-c-cpp/
Я попробовал библиотеку того же автора, скачав https://blog.mbedded.ninja/programming/ ... ems/linux/ linux-serial-ports-using-c-cpp/ и все работает нормально.
Код:
#include
#include
#include

// operating system includes
#include // posix api, includes ssize_t, read, write, close
#include // file control operations, eg open
#include // terminal
#include // ssize_t

static int set_speed(struct termios tty, int speed)
{
speed_t sp;
switch(speed) {
case 1200: sp = B1200; break;
case 1800: sp = B1800; break;
case 2400: sp = B2400; break;
case 4800: sp = B4800; break;
case 9600: sp = B9600; break;
case 19200: sp = B19200; break;
case 38400: sp = B38400; break;
case 57600: sp = B57600; break;
case 115200: sp = B115200; break;
default:
return -1; // unsupported
}

int baudset = cfsetospeed(&tty, sp);
baudset = cfsetispeed(&tty, sp);
return baudset;
}

static int get_term(int fd, struct termios* ptty)
{
/* Upon successful completion, 0 shall be returned. Otherwise, -1
shall be returned and errno set to indicate the error. */
return tcgetattr(fd, ptty);
}

/* configure tty */
static int set_terminal(int fd, struct termios* ptty, int timeout_ms)
{
// setting CLOCAL disables modem specific signals such as carrier detect
// we are not using a modem, so disable
// CREAD is important - allows us to read data
ptty->c_cflag |= (CLOCAL | CREAD);
ptty->c_cflag &= ~CSIZE; /* clear all size bits and use CS8 as set below */
ptty->c_cflag |= CS8; /* 8-bit characters */
ptty->c_cflag &= ~PARENB; /* no parity bit - most serial comms don't set parity bit - check */
ptty->c_cflag &= ~CSTOPB; /* only need 1 stop bit */
ptty->c_cflag &= ~CRTSCTS; /* no hardware flowcontrol - most common */

// input modes - disable sw flow control and any special handling of specfic bytes received
ptty->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXOFF | IXANY);
// setup for non-canonical mode. Canonical mode means input is only processed when a
// newline is encountered, but we have custom protocol with no newlines
// disabling some canonical mode options, eg we don't need to echo bytes we write
// also disable signal chars - ISIG
ptty->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
// we do not need any special interpretation of output bytes, eg newline chars
ptty->c_oflag &= ~OPOST;
// same with carriage returns/linefeed chars
ptty->c_oflag &= ~ONLCR;

// we do not want to block if no data available - otherwise will block forever
ptty->c_cc[VMIN] = 0; // VMIN is minimum no. of bytes to wait for
// block until either any amount of data available or timeout occurs
ptty->c_cc[VTIME] = static_cast(timeout_ms / 100); // VTIME is time in deciseconds (10ths of a second)

if (tcsetattr(fd, TCSANOW, ptty) != 0) {
// Error from tcsetattr- use strerror(errno)
return -1;
}
return 0;
}

int main() {
termios restore_tty;
termios current_tty;

std::cout

Подробнее здесь: https://stackoverflow.com/questions/788 ... cable-link
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Linux»