LINUX.ORG.RU

Чтение запись COM порта

 , ,


0

2

Отправляю пакет в com порт функция write проходит без ошибок и если буфер com порта не пустой отвечает нормально. Но если я отправляю пакет в com порт в бесконечном цикле, с паузой в 1 секунду, то первый пакет отрабатывает нормально, далее идут ошибки ввода\вывода Ниже код программы.

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <bitset>
#include <sys/ioctl.h>
#include "rsrw.h"

int main()
{
    char *portname = "/dev/ttyAMA0";
    int fd;
    int wlen;
    int rbuf = 0;

    fd = open(portname, O_RDWR | O_NOCTTY | O_SYNC);
    if (fd < 0) {
        printf("Error opening %s: %s\n", portname, strerror(errno));
        return -1;
    }
    set_interface_attribs(fd, B57600);

//while (1){
    //sleep(1);
    const uint8_t wr[] = { 0x01, 0x01, 0x00, 0x01, 0x02, 0x03 };
    wlen = write(fd, &wr[0], sizeof(wr));
    if (wlen != sizeof(wr)) {
        printf("Error from write: %d, %d\n", wlen, errno);
    }
    tcdrain(fd);

    ioctl(fd,FIONREAD,&rbuf);
    if (rbuf > 0) {
        unsigned char buf[rbuf];
        int rdlen;
        rdlen = read(fd, buf, sizeof(buf) - 1);
        if (rdlen > 0) {
        #ifdef DISPLAY_STRING
            buf[rdlen] = 0;
            printf("Read %d: \"%s\"\n", rdlen, buf);
        #else
            unsigned char *p;
            printf("Read %d:", rdlen);
            for (p = buf; rdlen-- > 0; p++)
                printf(" 0x%x", *p);
            printf("\n");
        #endif
        } else if (rdlen < 0) {
            printf("Error from read: %d: %s\n", rdlen, strerror(errno));
        }
    }
//}
}
В файле rsrw.h описана функция set_interface_attribs();
int set_interface_attribs(int fd, int speed)
{
    struct termios tty;

    if (tcgetattr(fd, &tty) < 0) {
        printf("Error from tcgetattr: %s\n", strerror(errno));
        return -1;
    }

    cfsetospeed(&tty, (speed_t)speed);
    cfsetispeed(&tty, (speed_t)speed);

    tty.c_cflag |= (CLOCAL | CREAD);    
    tty.c_cflag &= ~CSIZE;
    tty.c_cflag |= CS8;         /* 8-bit characters */
    tty.c_cflag &= ~PARENB;     /* no parity bit */
    tty.c_cflag &= ~CSTOPB;     /* only need 1 stop bit */
    tty.c_cflag &= ~CRTSCTS;    /* no hardware flowcontrol */
    tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
    tty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
    tty.c_oflag &= ~OPOST;
    tty.c_cc[VMIN] = 1;
    tty.c_cc[VTIME] = 1;

    if (tcsetattr(fd, TCSANOW, &tty) != 0) {
        printf("Error from tcsetattr: %s\n", strerror(errno));
        return -1;
    }
    return 0;
}

Может кто знает в чем моя ошибка.



Последнее исправление: prostoR (всего исправлений: 3)

sizeof(buf) для динамического buf — так делать нельзя.

vodz ★★★★★
()
Ответ на: комментарий от Bobby_

Помогло

(IXON | IXOFF | IXANY) вроде так надо писать

Сделал так опрос идет в цикле спасибо.
По поводу потоков. У меня проверка стоит, буфер пустой или нет.

ioctl(fd,FIONREAD,&rbuf);
    if (rbuf > 0) {
        read ....
    }
Или это не правильно?
Что бы убрать динамическую переменную buf? модернизировал скрипт поставил do-while
do {
}while (???);
Думаю какое условие поставить, что бы выйте из цикла.

prostoR
() автор топика
Ответ на: комментарий от prostoR

Используй просто read, он вроде возвращает 0, когда не смог прочесть или -1 при ошибке. Только сокет должен быть открыть в небл. моде. Пишу по памяти, уточни сам.

Bobby_
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.