Подключено два устройства PL2303 TX-> RX, RX-> TX и подключено к моей машине Linux
Я написал приложение на C, которое выполнит следующую операцию:
- Порт1 -> «отправляет известные данные размером 256 байт» -> Порт2
- Порт2 считывает данные и проверяет, действительно ли он получил те же данные, которые передал Порт1
- Порт2 -> «отправляет известные данные размером 256 байт, отличные от того, какой порт1 отправил» -> Порт1
- Порт1 считывает данные и проверяет, действительно ли он получил те же данные, которые передал Порт2
Использовано два потока, по одному на каждый порт
На последнем шаге, если у нас не будет «sleep + tcflush» перед чтением, буфер, считываемый Port1, будет иметь некоторые данные, которые он передал в Port2 на первом шаге.
Вот фрагмент моего кода.
// Even port number execution part
if (!(port_num % 2)) {
// Write to a given port
sem_wait(&semaphore[port_num]); // Wait until read is called for odd port
bytes_written = write(fd, write_buffer_even, size_even);
if (bytes_written == -1 || bytes_written != size_even) {
fprintf(fp, "%s: Failed to write buffer\n", port_name);
thread_params->retval = -errno;
goto exit;
}
// For some reason, I need to add a delay before flushing.
// The cause of this problem lies in using a USB serial port.
// If you use a regular serial port, you will not have this problem.
usleep(300000L); // Required to make flush work
tcflush(fd, TCIOFLUSH);
// Read from a given port
sem_post(&semaphore[port_num + 1]);
bytes_read = read(fd, read_buffer, size_even);
if (bytes_read == -1) {
fprintf(fp, "%s: Failed to read buffer\n", port_name);
thread_params->retval = -errno;
goto exit;
}
// Check for read bytes, complete & valid or not
if (size_odd != bytes_read) {
fprintf(fp, "%s: Read size mismatch - Expected %d bytes,"
"Read %zd bytes\n", port_name, size_odd, bytes_read);
thread_params->retval = -ECOMM;
thread_params->fail_count++;
} else {
if(strncmp(write_buffer_odd, read_buffer, size_odd)) {
fprintf(fp, "%s: Read data mismatch - Expected \"%s\""
"Read \"%s\"", port_name, write_buffer_odd,
read_buffer);
thread_params->retval = -ECOMM;
thread_params->fail_count++;
} else {
thread_params->success_count++;
}
}
// Odd port number execution part
} else {
// For some reason, I need to add a delay before flushing.
// The cause of this problem lies in using a USB serial port.
// If you use a regular serial port, you will not have this problem.
usleep(300000L); // Required to make flush work
tcflush(fd, TCIOFLUSH);
// Read from a given port
sem_post(&semaphore[port_num - 1]);
bytes_read = read(fd, read_buffer, size_odd);
if (bytes_read == -1) {
fprintf(fp, "%s: Failed to read buffer\n", port_name);
thread_params->retval = -errno;
goto exit;
}
// Check for read bytes, complete & valid or not
if (size_even != bytes_read) {
fprintf(fp, "%s: Read size mismatch - Expected %d bytes,"
"Read %zd bytes\n", port_name, size_even, bytes_read);
thread_params->retval = -ECOMM;
thread_params->fail_count++;
} else {
if(strncmp(write_buffer_even, read_buffer, size_even)) {
fprintf(fp, "%s: Read data mismatch - Expected \"%s\""
"Read \"%s\"", port_name, write_buffer_even,
read_buffer);
thread_params->retval = -ECOMM;
thread_params->fail_count++;
} else {
thread_params->success_count++;
}
}
// Write to a given port
sem_wait(&semaphore[port_num]); // Wait until read is called for read port
bytes_written = write(fd, write_buffer_odd, size_odd);
if (bytes_written == -1 || bytes_written != size_odd) {
fprintf(fp, "%s: Failed to write buffer\n", port_name);
thread_params->retval = -errno;
goto exit;
}
}
Я переключился на другие USB для последовательных устройств, таких как cp2104, cp2108, и поведение остается прежним. Какую ошибку я совершаю, я не хочу спать в своем приложении, так как это влияет на мою производительность.
Добавлены настройки termios:
// Open the port
sprintf(port_name, "/dev/ttyUSB%d", port_num);
fd = open(port_name, O_RDWR);
if (fd == -1) {
fprintf(fp, "%s: Failed to open %s port with status:%d\n",
__func__, port_name, -errno);
thread_params->retval = -errno;
goto exit;
}
// Set configuration for serial port
tcgetattr(fd, &config);
config.c_lflag &= ~(ECHO | ECHONL | ECHOE | ECHOK | ECHONL
| ECHOCTL | ECHOPRT | ECHOKE);
cfsetispeed(&config, B9600);
cfsetospeed(&config, B9600);
tcsetattr(fd, TCSANOW, &config);