Ответ UART включает в себя предыдущую команду? - PullRequest
0 голосов
/ 18 декабря 2018

Я пытаюсь читать с устройства UART в среде Linux с помощью программы на C, но у меня возникают разные результаты в отношении связи с UART с помощью экрана.

Код C, который я использую для проверки UARTсообщение выглядит следующим образом:

#include <stdio.h>
#include <stdlib.h>
#include <libgen.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <getopt.h>
#include <stdbool.h>
#include <sys/stat.h>
#include <termios.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/file.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/select.h>
#include <signal.h>
#include <ctype.h>

bool loop;

void sigHandler(int32_t sig)
{   
    if(sig == SIGINT)
    {
        printf("Catched SIGINT");
        loop = false;
    }
}

int main(int argc, char *argv[])
{
    char *devname = argv[1];
    int fd = -1;

    int nread = -1;
    int nwrite = -1;

    int ret;

    struct termios t_new = {0};
    struct termios t_old = {0};


    signal(SIGINT, sigHandler);


    fd = open(devname, O_RDWR | O_NOCTTY |O_NONBLOCK);
    if(fd > 0)
    {   
        printf("TTY open ! Configuring TTY"); 
    }
    else
    {
        fd = -1;
        return 1;
    }

    ret = tcgetattr(fd, &t_old);
    if(ret < 0)
    {
        perror("tcgetattr ");
        close(fd);
        fd = -1;
        return 1;
    }

    t_new = t_old;
    t_new.c_cflag = (B9600 | CS8 | CREAD );
    t_new.c_oflag = 0;
    t_new.c_iflag = 0;
    t_new.c_lflag = 0;

    ret = tcsetattr(fd, TCSANOW, &t_new);

    loop = true;
    while(loop)
    {
        char s[] = "at+gmi=?\r\n";
        nwrite = write(fd, s, strlen(s));
        if(nwrite == strlen(s))
        {
            fd_set rfd;
            struct timeval tm = {.tv_sec = 0, .tv_usec = 500000};
            FD_ZERO(&rfd);
            FD_SET(fd, &rfd);

            char buffer[64] = {0};

            if(select(fd + 1, &rfd, NULL, NULL, &tm) > 0)
                nread = read(fd, buffer, sizeof(buffer));

            if(nread > 0)
                printf("Reply is: %s\n", buffer);
        }

        usleep(500000);
    }
}

Но когда я читаю ответ, он всегда включает отправленную мною строку.Я не испытываю этой проблемы при использовании screen.

Каков наилучший способ чтения из UART в C с использованием Linux?Может ли мультиплексированный способ (с использованием select) вызвать проблемы?

РЕДАКТИРОВАТЬ Для полноты вывод:

Reply is: at+gmi=?

OK

Кроме того, иногда я непрочитай что угодно.

1 Ответ

0 голосов
/ 19 декабря 2018

Но когда я читаю ответ, он всегда включает отправленную мною строку.

Поскольку ваша конфигурация termios уничтожила атрибуты локального эха, и вы отправляете команду AT модема, попробуйте отправить команду ATE0, чтобы отключить эхо-сигнал от модема.

Я не испытываю этой проблемы при использовании экрана.

Это наблюдение подтверждает, что на подключенном модеме включено эхо.

Команда AT отображается (по модему) при вводе, но вы не возражаете против полученных данных в этой ситуации (потому что хотите увидеть, что вы печатаете).
Если модемне было включено эхо, тогда вы бы жаловались, что то, что вы вводите на экране , не было видно .

IOW эхо требуется при использовании программы эмулятора терминала (например, экрана )), но эхо должно быть отключено при отправке данных программой.

Каков наилучший способ чтения из UART в C с использованием Linux?

(Технически вы не читаете из "UART" , а скорее из последовательного терминала, который полностью буферизует весь ввод и вывод.)
Код, соответствующий POSIXстандартный, как описано в Правильная настройка режимов работы терминала и Руководство по последовательному программированию для операционных систем POSIX было бы намного лучше, чем у вас сейчас.
Я удивлен, что это работает вообще(например, CREAD не включен).

Может ли мультиплексный способ (с использованием select) вызывать проблемы?

Не «эхо» «проблема».
Ваша программане выполняет ничего, требующего использования select () и неблокирующего режима.

Кроме того, иногда я ничего не читаю.

Когда выписать код, который не совместим с POSIX, не следует ожидать надежного поведения программы.

...