Программа Raspberry Pi UART на C с использованием termios получает мусор (Rx и Tx подключены напрямую)

У меня есть простая программа, написанная на C, которая использует termios для отправки базовой строки в UART Raspberry Pi и пытается прочитать и вывести ответ. Контакты Rx и Tx на Raspberry Pi соединены перемычкой, поэтому все, что отправляется, должно быть немедленно получено.

Несмотря на то, что программа выводит, что она успешно отправила и получила 5 символов для выбранной строки («Hello»), попытка напечатать содержимое буфера просто выдает один или два символа мусора.

Программа:

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

int main(int argc, char* argv[]) {

    struct termios serial;
    char* str = "Hello";
    char buffer[10];

    if (argc == 1) {
        printf("Usage: %s [device]\n\n", argv[0]);
        return -1;
    }

    printf("Opening %s\n", argv[1]);

    int fd = open(argv[1], O_RDWR | O_NOCTTY | O_NDELAY);

    if (fd == -1) {
        perror(argv[1]);
        return -1;
    }

    if (tcgetattr(fd, &serial) < 0) {
        perror("Getting configuration");
        return -1;
    }

    // Set up Serial Configuration
    serial.c_iflag = 0;
    serial.c_oflag = 0;
    serial.c_lflag = 0;
    serial.c_cflag = 0;

    serial.c_cc[VMIN] = 0;
    serial.c_cc[VTIME] = 0;

    serial.c_cflag = B115200 | CS8 | CREAD;

    tcsetattr(fd, TCSANOW, &serial); // Apply configuration

    // Attempt to send and receive
    printf("Sending: %s\n", str);

    int wcount = write(fd, &str, strlen(str));
    if (wcount < 0) {
        perror("Write");
        return -1;
    }
    else {
        printf("Sent %d characters\n", wcount);
    }

    int rcount = read(fd, &buffer, sizeof(buffer));
    if (rcount < 0) {
        perror("Read");
        return -1;
    }
    else {
        printf("Received %d characters\n", rcount);
    }

    buffer[rcount] = '\0';

    printf("Received: %s\n", buffer);

    close(fd);
}

Выходы:

Opening /dev/ttyAMA0
Sending: Hello
Sent 5 characters
Received 5 characters
Received: [garbage]

Сам я не вижу серьезных проблем с кодом, но могу ошибаться. Я могу успешно отправлять и получать символы с помощью PuTTY, подключенного с теми же настройками, так что это не может быть аппаратной проблемой. Хотя я не пробовал это в PuTTY, попытка подключения с помощью этой программы к чему-либо со скоростью менее 115200 бод не приведет ни к чему.

Где я ошибаюсь?


person kourosh    schedule 22.06.2013    source источник
comment
Помимо применимого ответа @parkydr, у вас могут возникнуть проблемы, если вы не зациклились и не подключились к реальному устройству. Обнуление членов termios — плохая практика кодирования. Правильный метод POSIX для побитовой очистки или установки каждого необходимого флага без изменения каких-либо других битов или элементов структуры. В вашем коде вызов tcgetattr() по существу лишний. Вы должны проверять код возврата от tcsetattr() так же, как tcgetattr().   -  person sawdust    schedule 24.06.2013
comment
@sawdust Как правило, это было просто для того, чтобы убедиться, что у меня работают основы, прежде чем писать программу должным образом, но я приму во внимание ваш совет.   -  person kourosh    schedule 24.06.2013


Ответы (1)


int wcount = write(fd, &str, strlen(str));
int rcount = read(fd, &buffer, sizeof(buffer));

В этих строках buffer/str уже являются указателями. Вы передаете указатель на указатель.

Строки должны быть:

int wcount = write(fd, str, strlen(str));
int rcount = read(fd, buffer, sizeof(buffer));
person parkydr    schedule 23.06.2013
comment
Я знал, что где-то сделал глупую ошибку, работает отлично, спасибо! - person kourosh; 24.06.2013