Последовательный порт Linux заблокирован с помощью конфигурации termios.h

Я пишу встроенное приложение Linux, которое (1) открывает последовательное соединение с другим устройством, (2) отправляет известную команду, (3) проверяет порт на наличие входящих символов (ответ), пока не будет обнаружена ожидаемая ответная фраза или символ, (4 ) повторяет шаги 2 и 3, пока не будет отправлена ​​серия команд и не получены ответы, (5) затем закрывает порт.

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

Есть ли что-нибудь в конфигурации моего порта, что может привести к блокировке порта из-за отправки определенного байта (возможно, из-за электрических помех)?

Вот как я открываю свои порты (показывая конфигурации через termios.h):

struct termios options;

fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NONBLOCK);
if (fd == -1) {
    debug() << "Port open failed!"
    return FAIL;
}
debug() << "Port Opened Successful"
fcntl(fd, F_SETFL, 0);                                // This setting interacts with VMIN and VTIME below

// Get options
tcgetattr(fd, &options);

// Adjust Com port options

options.c_cflag |= (CLOCAL | CREAD);                  // Program will not "own" port, enable reading on port
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);   // Sets RAW input mode (does not treat input as a line of text with CR/LF ending)
options.c_oflag &= ~ OPOST;                        // Sets RAW ouput mode (avoids newline mapping to CR+LF characters)
options.c_iflag &= ~(IXON | IXOFF | IXANY);           // Turns off SW flow c

options.c_cc[VMIN] = 0;
options.c_cc[VTIME] = 10;

// Set options
tcsetattr(fd, TCSANOW, &options);

//return fd;
return SUCCEED;

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

Дополнительная информация - вот мои функции чтения и записи:

int Comm::Receive(unsigned char* rBuf)
{
    int bytes;
    ioctl(fd, FIONREAD, &bytes);
    if (bytes >= 1)
    {
        bytes = read(fd, rBuf, 1);
        if (bytes < 0)
            return READ_ERR;
        return SUCCEED;
    }
    else
        return NO_DATA_AVAILABLE;
}


int Comm::Send(int xCt, unsigned char* xBuf)
{
    int bytes;
    if (fd == -1)
        return FAIL;
    bytes = write(fd, xBuf, xCt);
    if (bytes != xCt)
        return FAIL;
    else
        return SUCCEED;
}

person user3076698    schedule 07.12.2013    source источник


Ответы (2)


Добро пожаловать в радости последовательных портов...

Мысль 1: оберните ваши вызовы чтения с помощью select ()

Мысль 2: снимите флаг ICANON в tcsetattr и установите атрибут VTIME для преднамеренного тайм-аута (а затем, очевидно, обработайте его)

Мысль 3: Ничто в последовательной связи никогда не работает идеально.

person Bandrami    schedule 07.12.2013

У меня также была аналогичная проблема с отправкой команды на устройства и чтением ответов с устройства. Пожалуйста, обратитесь к сообщению SOF ниже и ответу, который помог решить мою проблему.

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

Отправить данные на сканер штрих-кода через последовательный порт RS232

Я могу кое-что сделать для вас, если вы можете опубликовать свой полный исходный код с выводом.

Наслаждайтесь кодом. Спасибо.

person Dig The Code    schedule 17.04.2014