Последовательное устройство: чтение 8N1 работает, но запись одного байта не удалась - PullRequest
1 голос
/ 13 октября 2009

В моей программе я читаю с последовательного устройства (Linux, 8N1) без проблем. Но в случае, если я хочу записать один байт, я ничего не получаю на интерфейсе. Я предполагаю, что мои настройки последовательного выхода неверны. Но способов установить c_oflag не так много ...

Мой код:

#define TTYDEVICE "/dev/ttyS0"
#define BAUDRATE B9600

int openSerialDevice(const char* devTTY, struct termios oldTio) {
//----< Open serial device >----------------------------------
int fileDescriptor;
// fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
fileDescriptor = open(devTTY, O_RDWR | O_NOCTTY);
//fileDescriptor = open(devTTY, O_RDWR | O_NOCTTY /*| OPOST*/);
if (fileDescriptor == -1) {
    perror("Error while opening serial interface occurred!");
    return -99;
}

// set new parameters to the serial device
struct termios newtio;
bzero(&newtio, sizeof(newtio));
newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;

// set to 8N1
newtio.c_cflag &= ~PARENB;
newtio.c_cflag &= ~CSTOPB;
newtio.c_cflag &= ~CSIZE;
newtio.c_cflag |= CS8;

newtio.c_iflag = IGNPAR;

// output mode to
//newtio.c_oflag = 0;
newtio.c_oflag |= OPOST;

/* set input mode (non-canonical, no echo,...) */
newtio.c_lflag = 0;

newtio.c_cc[VTIME] = 10; /* inter-character timer 1 sec */
newtio.c_cc[VMIN] = 0; /* blocking read disabled  */

tcflush(fileDescriptor, TCIFLUSH);
if (tcsetattr(fileDescriptor, TCSANOW, &newtio)) {
    perror("could not set the serial settings!");
    return -99;
}

//----< / Open serial device >----------------------------------
return fileDescriptor;
}

int ACK[1] = { 6 };

int main() {
// old termios to restablish
struct termios oldTIO;
// filedescriptor
int fd;

fd = openSerialDevice(TTYDEVICE, oldTIO);

if ((fd == -1) | (fd == -99)) {
    perror("Could not open TTY-Device. Exit on failure!");
    return EXIT_FAILURE;
}

write(fd, ACK, 1);  // Problem !! 


     return 0:
}

Теперь, если я использую

screen / dev / ttyS1 9600 8n1

чтобы проверить, что выходит на / dev / ttyS0. Я ничего не вижу. То же самое, если я нюхаю с Docklight 1.8.

Есть предложения? спасибо

Ответы [ 3 ]

2 голосов
/ 13 октября 2009

Вы даете write() аргумент данных ACK, который является указателем на int. Это, вероятно, не то, что вы имеете в виду. В зависимости от порядка байтов компьютера, на котором вы работаете, это означает, что write() будет «видеть» буфер, содержащий символы { 6, 0, 0, 0 } (младший порядок) или { 0, 0, 0, 6 } (старший порядок) Это предполагает, что sizeof (int) == 4 верно, при необходимости настройте другие размеры, проблема остается.

Скорее всего, вместо этого вы должны создать буфер unsigned char. Кроме того, если вы сделали звонок так:

int wrote = write(fd, ACK, sizeof ACK);
printf("Wrote %d bytes\n", wrote);

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

2 голосов
/ 13 октября 2009

Как проверить, что ничего не выходит?

Вы можете попробовать сбросить RTSCTS и попробовать еще раз. Фактически, если вы хотите минимальных помех от tty-слоя, вы должны установить свой терминал в raw, используя это:

cfmakeraw(&newtio);
0 голосов
/ 13 октября 2009

Активированное аппаратное управление потоком (CRTSCTS) стало причиной блокировки write () и, наконец, на последовательном выходе ничего не появилось.

спасибо!

Кодовая привязка, которая работает:

int openSerialDevice(const char* devTTY, struct termios oldTio) {

    //----< Open serial device >----------------------------------
    int fileDescriptor;
    // fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
    fileDescriptor = open(devTTY, O_RDWR | O_NOCTTY);
    //fileDescriptor = open(devTTY, O_RDWR | O_NOCTTY /*| OPOST*/);
    if (fileDescriptor == -1) {
        perror("Error while opening serial interface occurred!");
        return -99;
    }

    // set new parameters to the serial device
    struct termios newtio;

    fcntl(fileDescriptor, F_SETFL, 0);
    // set everything to 0
    bzero(&newtio, sizeof(newtio));

    // again set everything to 0
    bzero(&newtio, sizeof(newtio));

    newtio.c_cflag |= BAUDRATE; // Set Baudrate first time
    newtio.c_cflag |= CLOCAL; // Local line - do not change "owner" of port
    newtio.c_cflag |= CREAD; // Enable receiver

    newtio.c_cflag &= ~ECHO; // Disable echoing of input characters
    newtio.c_cflag &= ~ECHOE;

    // set to 8N1
    newtio.c_cflag &= ~PARENB; // no parentybyte
    newtio.c_cflag &= ~CSTOPB; // 1 stop bit
    newtio.c_cflag &= ~CSIZE; // Mask the character size bits
    newtio.c_cflag |= CS8; // 8 data bits

    // output mode to
    newtio.c_oflag = 0;
    //newtio.c_oflag |= OPOST;


    // Set teh baudrate for sure
    cfsetispeed(&newtio, BAUDRATE);
    cfsetospeed(&newtio, BAUDRATE);

    newtio.c_cc[VTIME] = 10; /* inter-character timer  */
    newtio.c_cc[VMIN] = 0; /* blocking read until  */

    tcflush(fileDescriptor, TCIFLUSH); // flush pending data

    // set the new defined settings
    if (tcsetattr(fileDescriptor, TCSANOW, &newtio)) {
        perror("could not set the serial settings!");
        return -99;
    }

    //----< / Open serial device >----------------------------------
    return fileDescriptor;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...