Поэтому я использую два Xbee ZB (S2B) в проекте для передачи данных от одного к другому. Это 8 бит данных, без контроля четности и 1 стоп-бит (8N1).Последовательное программирование: отправитель и получатель
У меня есть два вопроса.
1.Поскольку я сопряжения с RS232 (DB9 разъем) интерфейс для адаптера USB на моем ноутбуке, при скорости передачи B230400 бы системные вызовы FWRITE/Fread/Еореп/fclose быть лучше чем написать/прочитать/открыть/закрыть? (я предполагаю, что Fread() не будет работать должным образом, так как не имеют конфигурации скорости передачи, насколько я знаю.)
2. я имея один компьютер под управлением одной программы (программа передатчика), и другая программа (программа-получатель). Обе программы должны иметь возможность читать и писать, так как я хотел бы знать с передающей и принимающей стороны различные наборы информации.
Как принимающая сторона (если я вижу букву Q, остановку и закрытие порта) или передающую сторону (подождите, пока сторона чтения отправит букву G, чтобы начать запись и закрыть, когда закончите запись).
Используя некоторый код из (http://tldp.org/HOWTO/Serial-Programming-HOWTO/x115.html) под неканонической обработкой ввода, я попытался установить базовый шаблон для записи и чтения с USB-порта с обеих сторон. Мой вопрос:
* Если и делает там должны быть разные параметры конфигурации (c_cflag, c_iflag, c_oflag, c_lflag) к termios структуры (newtio) для передающих и приемных программ *
Мой код:
#include <stdio.h>
#include <strings.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <errno.h>
#include <termios.h>
int open_port(char *path, int modes)
{
int fd; // File descriptor for port
fd = open(path, modes); // Open the path
if(fd == -1) return -1; // Could not be opened
printf("Port %s opened successfully.\n", path);
return fd; // Return fd
}
int setBaud(struct termios *termios_p, int baud)
{
int ires = 0; int ores = 0;
switch(baud)
{
0:
ires = cfsetispeed(&termios_p, B0);
ores = cfsetispeed(&termios_p, B0);
break;
50:
ires = cfsetispeed(&termios_p, B50);
ores = cfsetispeed(&termios_p, B50);
break;
75:
ires = cfsetispeed(&termios_p, B75);
ores = cfsetispeed(&termios_p, B75);
break;
110:
ires = cfsetispeed(&termios_p, B110);
ores = cfsetispeed(&termios_p, B110);
break;
134:
ires = cfsetispeed(&termios_p, B134);
ores = cfsetispeed(&termios_p, B134);
break;
150:
ires = cfsetispeed(&termios_p, B150);
ores = cfsetispeed(&termios_p, B150);
break;
200:
ires = cfsetispeed(&termios_p, B200);
ores = cfsetispeed(&termios_p, B200);
break;
300:
ires = cfsetispeed(&termios_p, B300);
ores = cfsetispeed(&termios_p, B300);
break;
600:
ires = cfsetispeed(&termios_p, B600);
ores = cfsetispeed(&termios_p, B600);
break;
1200:
ires = cfsetispeed(&termios_p, B1200);
ores = cfsetispeed(&termios_p, B1200);
break;
1800:
ires = cfsetispeed(&termios_p, B1800);
ores = cfsetispeed(&termios_p, B1800);
break;
2400:
ires = cfsetispeed(&termios_p, B2400);
ores = cfsetispeed(&termios_p, B2400);
break;
4800:
ires = cfsetispeed(&termios_p, B4800);
ores = cfsetispeed(&termios_p, B4800);
break;
9600:
ires = cfsetispeed(&termios_p, B9600);
ores = cfsetispeed(&termios_p, B9600);
break;
19200:
ires = cfsetispeed(&termios_p, B19200);
ores = cfsetispeed(&termios_p, B19200);
break;
38400:
ires = cfsetispeed(&termios_p, B38400);
ores = cfsetispeed(&termios_p, B38400);
break;
57600:
ires = cfsetispeed(&termios_p, B57600);
ores = cfsetispeed(&termios_p, B57600);
break;
115200:
ires = cfsetispeed(&termios_p, B115200);
ores = cfsetispeed(&termios_p, B115200);
break;
230400:
ires = cfsetispeed(&termios_p, B230400);
ores = cfsetispeed(&termios_p, B230400);
break;
default:
ires = cfsetispeed(&termios_p, B9600);
ores = cfsetispeed(&termios_p, B9600);
break;
}
if(ires == -1 | ores == -1) return -1; // ISpeed or OSpeed could not be set
else { printf("Baud set successfully to %d\n", baud); return 0; }
}
char* readIt(int fd)
{
char buf;
char *tmp;
tmp = calloc(2, sizeof(char);
if(read(fd, buf, 1) == 1) { tmp[0] = buf; tmp[1] = 0; } // Return char in tmp[0]
else { tmp[0] = 0x45; tmp[1] = 0x52; } // Return ER in char meaning error
return tmp;
}
int writeIt(int fd, char *str, int bytes)
{
if(write(fd, str, bytes) == bytes) return 0; // Write success
else return -1; // Failed write
}
int main (int argc, char **argv)
{
int usb;
volatile int STOP = 0;
if(argc == 1) { printf("Must enter usb port path.\n"); exit(EXIT_FAILURE); } // No second argument
else if (argc > 1) { usb = open_port(argv[1], O_RDWR | O_NOCTTY); }
struct termios oldterm, newterm;
tcgetattr(fd, &oldtio); // Save old terminal settings
bzero(&newtio, sizeof(newtio)); // Clear out struct
if(setBaud(&newtio, 230400) != 0) { printf("Baud could not be set\n"); exit (EXIT_FAILURE); } // Set up baud rate
newtio.c_cflag = CS8 | CREAD | CLOCAL; // 8 data bits, enable receiver, local line
newtio.c_cflag &= ~PARENB | ~CSTOPB; // No parity, one stop bit
newtio.c_iflag &= ~(IXON | IXOFF | IXANY); // Disable software flow control
newtio.c_oflag = 0;
newtio.c_lflag = 0;
newtio.c_cc[VTIME] = 0; // No timeout clock for read
newtio.c_cc[VMIN] = 1; // Wait for one character before reading another
tcflush(fd, TCIFLUSH);
tcsetattr(fd, TCSANOW, &newtio); // Set fd with new settings immediately
/* Do writing or reading from port in here - readIt or writeIt*/
tcsetattr(fd, TCSANOW, &oldtio); // Set fd with old settings immediately
close(fd); // Close fd
return 0;
}
Если возможно, я ищу наиболее оптимальные скорости записи и чтения без обработки обработки данных на этом этапе. Оптимальным я говорю о лучших настройках флагов конфигурации для termios struct.
Благодарим за помощь.
* «Я ищу наиболее оптимальные скорости записи и чтения без обработки данных» * - После того, как данные попадают в приемник, единственная возможность потери данных - это переполнение приемника или буфера. Ваш медленный способ чтения только одного байта за раз может привести к переполнению буфера. Это, безусловно, неэффективное использование ** read() ** syscall. – sawdust