Ответ UART включает предыдущую команду?

Я пытаюсь читать данные с устройства 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

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

Похоже, это просто терминальное эхо. Ваш ввод определенно возвращается от UART?

Rup 18.12.2018 11:49

да. Но ECHO отключен, по крайней мере, в моем коде. Я не знаю настройки внешнего устройства UART.

simo-zz 18.12.2018 11:56
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

But when I read the reply, it always includes the string I have sent.

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

I don't experience this problem using screen.

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

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

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

What is the best way to read from an UART in C using Linux ?

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

Could the multiplexed way (using select) causing the problems ?

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

Also, sometimes I don't read anything.

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

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

simo-zz 19.12.2018 18:40

Другие вопросы по теме