URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 5821
[ Назад ]

Исходное сообщение
"Работа с Com портом. Проблема с символом 13"

Отправлено NightSpider , 16-Окт-06 13:25 
Пишу программу по передаче данных через com порт. Для отладки использую один комп, порты ttyS0 и ttyS1 соединены нуль модемным кабелем. Оба порта открываю одним и тем же способом. В целом, передача данных проходит без проблем, но возникает проблема всего с одним символом. При передаче символа с кодом 13 с ttyS0, второй порт ttyS1 упорно принимает символ с кодом 10. В обратном направлении возникает та же проблема. С другими символами проблем не возникает, если передаешь символ 10, то и принимаешь символ 10. Подскажите возможную причину проблемы здесь или вышлите на мыло witek@yandex.ru

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

Открытие:
int  TComPortFunctions::OpenPort()
{
    struct termios options;
    printf("Bus System communication device name: %s\n",devicename) ;
    printf("Befor open: handle = %d\n",handle) ;
    if(handle != -1) return -1; // Порт уже открыт нашей программой
    /* open the port */
    handle = open(devicename, O_RDWR | O_NOCTTY| O_NDELAY);
    printf("After open: handle = %d\n",handle) ;
    if(handle < 0) return -2; // Какая-то другая проблема
    
    fcntl(handle, F_SETFL, 0);

    /* get the current options */
    tcgetattr(handle, &options);
    /* Устанавливаем скорость приема и предачи */
    cfsetispeed(&options, B9600); // Установили скорость приема сообщений
    cfsetospeed(&options, B9600); // Установили скорость отправки сообщений
    /* set raw input, 1 second timeout */
    options.c_cflag     |= (CLOCAL | CREAD);
    //No parity (8N1)
    options.c_cflag        &=~PARENB;    
    options.c_cflag        &=~CSTOPB;            
    options.c_cflag        &=~CSIZE;    
    options.c_cflag        |=CS8;
    //Установка аппаратного контроля передачи данных

    options.c_cflag |=CRTSCTS;
    options.c_iflag &=~(IXON|IXOFF|IXANY);
    
//    Программное управление передачей данных
//    options.c_cflag &=~CRTSCTS;
//    options.c_iflag |=(IXON|IXOFF|IXANY);        

    //Устанавливаем RAW INPUT
    options.c_lflag     &= ~(ICANON | ECHO | ECHOE | ISIG);
    options.c_oflag     &= ~OPOST;
    options.c_cc[VMIN]  = 0; // Минимальное количество символов для чтения
    options.c_cc[VTIME] = timeout; //Время ожидания
    /* set the options */
    tcsetattr(handle, TCSANOW, &options);
    ioctl(handle,TCFLSH,2); // Сбарываем очереди ввода вывода
    return 0;
}

Функция передачи символов

//---------------------------------------------------------------------------
long TComPortFunctions::Write(unsigned char *answer, long len)
{
    if (handle==-1) return -1;
    if (write(handle, answer, len)!=len) return -2;
    printf("Write len: %d\n",len);
    return 0;    
}
Функция чтения символов

void TComPortFunctions::ReadToScreen()
{

    unsigned char block_from;
    block_len=1;

    while (block_len!=0)
    {
        block_len=read(handle, &block_from, block_len);
        if (block_len>0) printf("Resutlt: %d\n",block_from);

    }
}


Содержание

Сообщения в этом обсуждении
"Работа с Com портом. Проблема с символом 13"
Отправлено vic , 16-Окт-06 13:43 
man termios - какие есть флаги
man stty - какие стоят на порту по умолчанию.

Проблема в установке/сбросе флагов. Смотреть какие флаги установлены, какие нет.

OCRNL к примеру :)


"Работа с Com портом. Проблема с символом 13"
Отправлено NightSpider , 16-Окт-06 15:30 
Снятие флага
[SRC c++]options.c_oflag &= ~OPOST;[/SRC]
убирает возможность обработанного вывода, т.е. никаких замен не производится. На всякий случай устанавливал и снимал флажки INLCR,ONLCR, OCRNL - как и положено никаких замен не происходило. Мой символ 13 в любом случае меняется на 10.

"Работа с Com портом. Проблема с символом 13"
Отправлено vic , 16-Окт-06 16:15 
>Снятие флага
>[SRC c++]options.c_oflag &= ~OPOST;[/SRC]
>убирает возможность обработанного вывода, т.е. никаких замен не производится. На всякий случай
>устанавливал и снимал флажки INLCR,ONLCR, OCRNL - как и положено никаких
>замен не происходило. Мой символ 13 в любом случае меняется на
>10.

угу, видимо на входе транслируется, может быть:
CR
    Special character on input, which is recognized if the ICANON flag is set; it is the carriage-return character. When ICANON and ICRNL are set and IGNCR is not set, this character shall be translated into an NL, and shall have the same effect as an NL character.

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


"Работа с Com портом. Проблема с символом 13"
Отправлено NightSpider , 16-Окт-06 16:33 
Разобрался. Проблема возникала из-за поднятого флага icrnl. После его снятия передача символа13 началась без проблем.
Почему-то из моей программы флаг не снимался (запускаю под root)
options.c_cflag &=~ICRNL;

Если знаете почему это может происходить, скажите.

Флаг снимал из терминалки stty -F /dev/ttyS0 -icrnl – помогло.