LINUX.ORG.RU

История изменений

Исправление Eddy_Em, (текущая версия) :

При `open` хватает же! Как-то так:

        int i, flag = 1;
        unsigned char comdev[32];
        snprintf(comdev, 32, "/dev/ttyS%d", ComPort);
        if(comfd){
                ioctl(comfd,TCSETA,&oldtty);
                close(comfd);
        }
        WARN("Открываю порт %s... ", comdev);
        if ((comfd = open(comdev,O_RDWR|O_NOCTTY|O_NONBLOCK)) < 0){ 
                WARN("Не могу использовать порт %s: %s\nОтключаюсь.", comdev, strerror(errno));
                exit(1);
        }
        WARN(" OK\nПолучаю текущие настройки порта... ");
        if(ioctl(comfd,TCGETA,&oldtty) < 0) flag = 0; // Узнаем текущие параметры порта
        tty = oldtty;
        tty.c_lflag    = 0;
        tty.c_iflag    = BRKINT;
        tty.c_oflag    = 0;
        tty.c_cflag    = B9600|CS8|CREAD|CLOCAL|PARENB;
        tty.c_cflag &= ~PARODD;
        tty.c_cc[VMIN] = 0;
        tty.c_cc[VTIME] = 5;
        if(ioctl(comfd,TCSETA,&tty) < 0) flag = 0;
        if(flag){
                WARN(" OK\n");
        }
        else{
                WARN(" Ошибка настройки порта, отлючаюсь.\n");
                exit(1);
        }

Соответственно, чтение:

        unsigned char rb; // то, что считываем
        fd_set rfds; // набор файловых дескрипторов
        struct timeval tv; // время ожидания
        int retval; // возвращаемое ф-й select значение
        tty.c_iflag &= ~PARODD; // принимаем с девятым битом = 0
        ioctl(comfd,TCSETA,&tty);
        FD_ZERO(&rfds); // очищаем набор
        FD_SET(comfd, &rfds); // теперь это - свойства порта
        tv.tv_sec = 0; tv.tv_usec = 500000; // ждем .5с
        retval = select(comfd + 1, &rfds, NULL, NULL, &tv);
        if (!retval){
                MSG("Контроллер не готов!\n");
                return (-1); // если сигнала нет, возвращаем ноль
        }
        if(FD_ISSET(comfd, &rfds)){
                if(read(comfd, &rb, 1) < 1){
                        MSG("Ошибка считывания\n");
                        return (-1); // ошибка считывания
                }
        } 
        else{
                MSG("Готов, но не COM-порт\n");
                return (-1); // ошибка 
        }
        MSG("считан сигнал: %d\n", rb);
        return (int)rb;

как опредилить что к нему подключено устройство

Пингануть.

Исходная версия Eddy_Em, :

При `open` хватает же! Как-то так:

        int i, flag = 1;
        unsigned char comdev[32];
        snprintf(comdev, 32, "/dev/ttyS%d", ComPort);
        if(comfd){
                ioctl(comfd,TCSETA,&oldtty);
                close(comfd);
        }
        WARN("Открываю порт %s... ", comdev);
        if ((comfd = open(comdev,O_RDWR|O_NOCTTY|O_NONBLOCK)) < 0){ 
                WARN("Не могу использовать порт %s: %s\nОтключаюсь.", comdev, strerror(errno));
                exit(1);
        }
        WARN(" OK\nПолучаю текущие настройки порта... ");
        if(ioctl(comfd,TCGETA,&oldtty) < 0) flag = 0; // Узнаем текущие параметры порта
        tty = oldtty;
        tty.c_lflag    = 0;
        tty.c_iflag    = BRKINT;
        tty.c_oflag    = 0;
        tty.c_cflag    = B9600|CS8|CREAD|CLOCAL|PARENB;
        tty.c_cflag &= ~PARODD;
        tty.c_cc[VMIN] = 0;
        tty.c_cc[VTIME] = 5;
        if(ioctl(comfd,TCSETA,&tty) < 0) flag = 0;
        if(flag){
                WARN(" OK\n");
        }
        else{
                WARN(" Ошибка настройки порта, отлючаюсь.\n");
                exit(1);
        }

Соответственно, чтение:

        unsigned char rb; // то, что считываем
        fd_set rfds; // набор файловых дескрипторов
        struct timeval tv; // время ожидания
        int retval; // возвращаемое ф-й select значение
        tty.c_iflag &= ~PARODD; // принимаем с девятым битом = 0
        ioctl(comfd,TCSETA,&tty);
        FD_ZERO(&rfds); // очищаем набор
        FD_SET(comfd, &rfds); // теперь это - свойства порта
        tv.tv_sec = 0; tv.tv_usec = 500000; // ждем .5с
        retval = select(comfd + 1, &rfds, NULL, NULL, &tv);
        if (!retval){
                MSG("Контроллер не готов!\n");
                return (-1); // если сигнала нет, возвращаем ноль
        }
        if(FD_ISSET(comfd, &rfds)){
                if(read(comfd, &rb, 1) < 1){
                        MSG("Ошибка считывания\n");
                        return (-1); // ошибка считывания
                }
        } 
        else{
                MSG("Готов, но не COM-порт\n");
                return (-1); // ошибка 
        }
        MSG("считан сигнал: %d\n", rb);
        return (int)rb;