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

Исходное сообщение
"Проблемы с COM портом"

Отправлено Hem , 06-Дек-05 20:01 
Есть один девайс, для которого в свое время я написал интерфейс для взаимодействия с PC, под Linux с ядром 2.4 (Debian), используя низкоуровневый интерфейс для работы с COM портом. (Работа через физический адрес порта, регистры COM порта, inb...)
Все прекрасно работало в течении полугода, но затем, после перехода на ядро 2.6 часто стали возникать ошибки при работе с COM портом, которые полностью отсутствовали под ядром 2.4. Ошибки заключались в появлении неожиданных байт со стороны девайса. (Пробовал вновь переключаться на 2.4 - никаких ошибок)
Нечто подобное было и на ядре 2.4, но тогда проблему удалось решить отключением модуля SERIAL из ядра. Под 2.6 отключение модуля не помогло...

Содержание

Сообщения в этом обсуждении
"Проблемы с COM портом"
Отправлено ACCA , 07-Дек-05 07:49 
>Нечто подобное было и на ядре 2.4, но тогда проблему удалось решить
>отключением модуля SERIAL из ядра. Под 2.6 отключение модуля не помогло...

Похоже на проблемы с обработкой прерываний. Я бы ушёл на более высокий уровень - ну их на фиг, эти регистры, пусть у Линуса башка болит.


"Проблемы с COM портом"
Отправлено Hem , 08-Дек-05 06:51 
>Похоже на проблемы с обработкой прерываний. Я бы ушёл на более высокий
>уровень - ну их на фиг, эти регистры, пусть у Линуса
>башка болит.

С termios есть проблема...
Устройство должно работать на скорости 9600 с 1 стоп битом, с space parity  без flow control.
Вот текст программы:

#include <stdio.h>   /* Standard input/output definitions */
#include <string.h>  /* String function definitions */
#include <unistd.h>  /* UNIX standard function definitions */
#include <fcntl.h>   /* File control definitions */
#include <errno.h>   /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */
#include <iostream>

using namespace std;

int main(void)
{
    int n;
    int fd; /* File descriptor for the port */
    char buf[200];
    struct termios options;
    
  fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NONBLOCK);
    if (fd == -1)
    {perror("open_port: Unable to open /dev/ttyS0 - ");}
    
    else fcntl(fd, F_SETFL, 0);

    
    /************************************************************************/
    //c_iflag
    //options.c_iflag = 0;
    options.c_iflag = IGNBRK; // Ignore BREAK condition on input.
    options.c_iflag &= ~IXON; // Enable XON/XOFF flow control on output.
    options.c_iflag &= ~IXOFF; // Enable XON/XOFF flow control on input.

    
    /************************************************************************/
    // c_oflag
    options.c_oflag =  0;
    
    /************************************************************************/
    // c_cflag
    options.c_cflag =  CS8; // Число бит под 1 байт
    options.c_cflag &= ~PARENB; // Не исползовать бит четности
    options.c_cflag &= ~CSTOPB; // Использовать 1 стоп-бит
    options.c_cflag |=  CREAD; // Enable Receiver
    options.c_cflag |= CLOCAL; // Ignore modem control lines.
        
    /************************************************************************/
    // clflag
    options.c_lflag = ISIG; // Не генерировать сигналы при получении данных
    options.c_lflag &= ~ICANON; //Запретить EOF и прочие спец символы
    options.c_lflag &= ~XCASE;    // (not in POSIX; not supported under Linux) If ICANON is also set, terminal is uppercase only. Input is converted to lowercase, except for characters preceded by \. On output, uppercase characters are preceded by \ and lowercase characters are converted to uppercase.
    options.c_lflag &= ~ECHO; //Echo input characters.

    
    /************************************************************************/
    
    cfsetispeed(&options, B9600);
    cfsetospeed(&options, B9600);
    
    
    tcflush(fd, TCIOFLUSH);
    
    tcsetattr(fd, TCSAFLUSH, &options);
        
    // Main code
    buf[0]=0xA;
    n = write(fd, buf, 1);
    usleep(150000);
    cout << "Written:" <<  n  <<  '\n';
    usleep (150000);
    cout << "Readen:" << read(fd,buf,1); << '\n';
    close(fd);
}

После ее запуска происходит запись в порт, но считывание не происходит. Аналогичные программы, написаная под низкоуровневый интерфейс и под Win32 работают без проблем. Пробовал запускать данную программу и под ядром 2.4 и под ядром 2.6 - не работает...



"Проблемы с COM портом"
Отправлено Mr.Link , 09-Фев-06 11:00 
>> options.c_cflag |= CLOCAL; // Ignore modem control lines.

Ты уверен что правильно написано? ИМХО совсем наоборот.
И проверяй параметры порта stty


"Проблемы с COM портом"
Отправлено Kompot , 15-Фев-06 14:40 
Попробуйте так

int open_serial_port( void )
{
    struct termios options;
    int fd;
    int fcntl_ret;


    // open the port
    if( ( fd = open( MY_TTY, O_RDWR | O_NOCTTY | O_NDELAY) ) == -1 )
    {
        return -1;
    }

    // Set exclusive use flag to block other open calls with EBUSY
    if ( ioctl(fd, TIOCEXCL, 0) == -1 )
    {
        return -1;
    }


    // Blocking read
    // fcntl(fd, F_SETFL, 0);

    // Non blocking read
    fcntl(fd, F_SETFL, FNDELAY );


    // get the current options
    tcgetattr(fd, &options);

    cfsetispeed(&options, B9600);
    cfsetospeed(&options, B9600);

    // Control Flags
        // enable the receiver and set local mode...
        options.c_cflag |= (CLOCAL | CREAD);

        // data : 8 bit, stop : 1 bit, parity : none
        options.c_cflag &= ~PARENB;
        options.c_cflag &= ~CSTOPB;
        options.c_cflag &= ~CSIZE;
        options.c_cflag |= CS8;

        // disable hardware flow control
        //options.c_cflag &= ~CNEW_RTSCTS;
        options.c_cflag &= ~CRTSCTS;
    

    options.c_lflag = 0;
    options.c_iflag = IGNBRK;
    options.c_oflag = 0;         // turn off all output processing
    
    options.c_cc[VMIN] = 1;    
    options.c_cc[VTIME] = 0;

    // set the options
    tcsetattr(fd, TCSANOW, &options);


    return fd;
}


"Проблемы с COM портом"
Отправлено axel , 09-Фев-06 15:50 
А обрабатываешь ты прерывания точно только по приёму символа или все вподряд?