2014-01-09 2 views
1

Поэтому я использую два 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.

Благодарим за помощь.

+0

* «Я ищу наиболее оптимальные скорости записи и чтения без обработки данных» * - После того, как данные попадают в приемник, единственная возможность потери данных - это переполнение приемника или буфера. Ваш медленный способ чтения только одного байта за раз может привести к переполнению буфера. Это, безусловно, неэффективное использование ** read() ** syscall. – sawdust

ответ

0

Что касается пункта 1, легко получить FILE* из файлового дескриптора, используя fdopen. Однако вы должны помнить, что по умолчанию FILE* буферизуется, поэтому то, что вы пишете, не может быть отправлено немедленно.

0

Посмотрите на это ANSI C Host Library для связи с модулями XBee. Файл xbee_serial_posix.c включает в себя полный последовательный интерфейс, а более высокие уровни в драйвере обеспечивают разбор и диспетчеризацию фреймов API. Множество примеров программ.

Вы можете либо использовать библиотеку напрямую, либо ссылаться на последовательный уровень для написания собственного кода termios.

Он предназначен, главным образом, для использования модулей XBee в «режиме API» (ATAP=1), но есть также некоторые части для «режима AT» (например, образец xbee_term).

Смежные вопросы