C Чтение блокировки вызовов в операции последовательного порта

Я пытаюсь написать программу C в Linux для отправки и получения данных из микроконтроллера по последовательному порту. В качестве теста я настроил микроконтроллер, чтобы немедленно повторил все отправленные символы. Я проверил, что это работает в Minicom, а также с использованием «CAT» и «ECHO» для отправки и получения данных.

Однако, когда я пытаюсь сделать то же самое в программе C, мои прочитанные блоки называют навсегда. Я устанавливаю последовательный порт в неконнический режим, с мин «1» и время «0». Мой Minicom Test доказывает, что микроконтроллер возвращает символы, поскольку они набираются, поэтому я ожидаю, что чтение вернется после того, как звонок записи отправил символы. Я сравнил свой код нескольким онлайн примерам, и я не нашел ничего, что мне не хватает. Я пробовал несколько перестановок кода ниже без удачи. Может кто-то заметить проблему?

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <termios.h>

#define UART_SPEED B115200

char buf[512];

void init_serial (int fd)
{
    struct termios termios;
    int res;

    res = tcgetattr (fd, &termios);
    if (res < 0) {
        fprintf (stderr, "Termios get error: %s\n", strerror (errno));
        exit (-1);
    }

    cfsetispeed (&termios, UART_SPEED);
    cfsetospeed (&termios, UART_SPEED);

    termios.c_iflag &= ~(IGNPAR | IXON | IXOFF);
    termios.c_iflag |= IGNPAR;

    termios.c_cflag &= ~(CSIZE | PARENB | CSTOPB | CREAD | CLOCAL);
    termios.c_cflag |= CS8;
    termios.c_cflag |= CREAD;
    termios.c_cflag |= CLOCAL;

    termios.c_lflag &= ~(ICANON | ECHO);
    termios.c_cc[VMIN] = 1;
    termios.c_cc[VTIME] = 0;

    res = tcsetattr (fd, TCSANOW, &termios);
    if (res < 0) {
        fprintf (stderr, "Termios set error: %s\n", strerror (errno));
        exit (-1);
    }
}

int main (int argc, char **argv)
{
    int fd;
    int res;
    int i;

    if (argc < 2) {
        fprintf (stderr, "Please enter device name\n");
        return -1;
    }

    fd = open (argv[1], O_RDWR | O_NOCTTY);
    if (fd < 0) {
        fprintf (stderr, "Cannot open %s: %s\n", argv[1], strerror(errno));
        return -1;
    }

    init_serial (fd);

    res = write (fd, "P=20\r\n", 6);
    if (res < 0) {
        fprintf (stderr, "Write error: %s\n", strerror(errno));
        return -1;
    }
    tcdrain (fd);

    res = read (fd, buf, 512);
    printf ("%d\n", res);
    if (res < 0) {
        fprintf (stderr, "Read error: %s\n", strerror(errno));
        return -1;
    }

    for (i=0; i<res; i++) {
        printf ("%c", buf[i]);
    }

    return 0;
}
6
задан FazJaxton 13 September 2011 в 02:42
поделиться