-->
当前位置:首页 > articles > 正文内容

Luz3个月前 (10-27)articles329

Why serial port read() return zero instead of data?

  • Anton-Vas 问题:

    •     #include <iostream>    #include <asm/termios.h>    #include <asm/ioctls.h>    #include <sys/signal.h>    #include <stropts.h>    #include <unistd.h>        using namespace std;        bool Ports::setup_port_Sbus(Info* port)    {        //> check descriptor        if (!isatty(fd)) { throw "File description is NOT a serial port!"; }            //> read fole descriptor config        struct termios2 config = { 0 };            //> for interrupt        struct sigaction saio;        sigset_t mskvar;        sigfillset(&mskvar);        sigprocmask(SIG_SETMASK, &mskvar, NULL);        sigdelset(&mskvar, SIGIO);        saio.sa_handler = signal_io_handler;        saio.sa_flags = 0;        saio.sa_restorer = NULL;        sigaction(SIGIO, &saio, NULL);            if (ioctl(fd, TCGETS2, &config) < 0) { throw "Could not read config of FD!"; }            config.c_cflag |= PARENB;  // enable parity        config.c_cflag &= ~PARODD; // even parity        config.c_cflag |= CSTOPB;  // enable 2 stop bits        config.c_cflag &= ~CSIZE;  // clear character size mask        config.c_cflag |= CS8;     // 8 bit characters        config.c_cflag &= ~CRTSCTS;  // disable hardware flow control        config.c_cflag |= CREAD;   // enable receiver        config.c_cflag |= CLOCAL;  // ignore modem lines            config.c_lflag &= ~ICANON;  // receive characters as they come in        config.c_lflag &= ~ECHO;    // do not echo        config.c_lflag &= ~ISIG;    // do not generate signals        config.c_lflag &= ~IEXTEN;  // disable implementation-defined processing            config.c_iflag &= ~(IXON | IXOFF | IXANY);  // disable XON/XOFF flow control        config.c_iflag |= IGNBRK;   // ignore BREAK condition        config.c_iflag |= INPCK;    // enable parity checking        config.c_iflag |= IGNPAR;   // ignore framing and parity errors        config.c_iflag &= ~ISTRIP;  // do not strip off 8th bit        config.c_iflag &= ~INLCR;   // do not translate NL to CR        config.c_iflag &= ~ICRNL;   // do not translate CR to NL        config.c_iflag &= ~IGNCR;   // do not ignore CR            config.c_oflag &= ~OPOST;  // disable implementation-defined processing        config.c_oflag &= ~ONLCR;  // do not map NL to CR-NL        config.c_oflag &= ~OCRNL;  // do not map CR to NL        config.c_oflag &= ~(ONOCR | ONLRET);  // output CR like a normal person        config.c_oflag &= ~OFILL;  // no fill characters            // Apply baudrate        speed_t br = 100000;        config.c_ispeed = br;        config.c_ospeed = br;        config.c_cc[VMIN] = 0;        config.c_cc[VTIME] = 0;            //> Finally, apply the configuration        if (ioctl(fd, TCSETS2, &config) < 0) { throw "Could not set configuration of fd!"; }                // Done!        return true;    }            void port_init(){                const char* _name = "/dev/ttyTHS1";        int fd = -1;                fd = open(_name, O_RDWR | O_NOCTTY );        if (fd < 0) { throw "File is not open!"; }        else{            fcntl(fd, F_SETFL, O_NONBLOCK|O_ASYNC);        }                bool setup = setup_port_Sbus(fd);            if (!setup) { throw "Could not configure port"; }        if (fd <= 0) { throw "Connection attempt to port failed, exiting"; }        }        struct Sbus_data{        bool    lost_frame;        int failsafe;        bool    ch17;        bool    ch18;        static int8_t   SBUS_NUM_CH             = 16;        int     last_ch[SBUS_NUM_CH]    = {};        int     ch[SBUS_NUM_CH]     = {};    };        int main(){                try{            port_init();        }        catch(const char* err){            cout << "ERR: " << err << endl;        }                uint8_t byte;        uint8_t sb_buf[SBUS_PACKET_LEN] = {};        const int8_t SBUS_PACKET_LEN    = 25;        const int8_t SBUS_NUM_SBUS_CH   = 16;        const uint8_t SBUS_HEADER   = 0x0F;        const uint8_t SBUS_FOOTER   = 0x00;        const uint8_t SBUS_FOOTER2  = 0x04;        const uint8_t SBUS_CH17_MASK    = 0x01;        const uint8_t SBUS_CH18_MASK    = 0x02;        const uint8_t SBUS_LOST_FRAME_MASK = 0x04;        const uint8_t SBUS_FAILSAFE_MASK = 0x08;        Sbus_data           sb_data;        int sb_state                    = 0;                do{            count_read_symb = read(port->file_descriptor, &byte, 1);            if(count_read_symb <= 0)            {                cout << "byte: " << byte << " | errno: "<< errno << endl;                continue;            }                //> wrong start            if(sb_state == 0 && byte != SBUS_HEADER)            {                continue;            }                sb_buf[sb_state++] = byte;                //> index done            if(sb_state == SBUS_PACKET_LEN)            {                sb_state = 0;                if(sb_buf[24] != SBUS_FOOTER)                {                    continue;                }                                sb_data.ch[0]  = ((sb_buf[1]    |sb_buf[2]<<8)                 & 0x07FF);                sb_data.ch[1]  = ((sb_buf[2]>>3 |sb_buf[3]<<5)                 & 0x07FF);                sb_data.ch[2]  = ((sb_buf[3]>>6 |sb_buf[4]<<2 |sb_buf[5]<<10)  & 0x07FF);                sb_data.ch[3]  = ((sb_buf[5]>>1 |sb_buf[6]<<7)                 & 0x07FF);                sb_data.ch[4]  = ((sb_buf[6]>>4 |sb_buf[7]<<4)                 & 0x07FF);                sb_data.ch[5]  = ((sb_buf[7]>>7 |sb_buf[8]<<1 |sb_buf[9]<<9)   & 0x07FF);                sb_data.ch[6]  = ((sb_buf[9]>>2 |sb_buf[10]<<6)                & 0x07FF);                sb_data.ch[7]  = ((sb_buf[10]>>5|sb_buf[11]<<3)                & 0x07FF);                sb_data.ch[8]  = ((sb_buf[12]   |sb_buf[13]<<8)                & 0x07FF);                sb_data.ch[9]  = ((sb_buf[13]>>3|sb_buf[14]<<5)                & 0x07FF);                sb_data.ch[10] = ((sb_buf[14]>>6|sb_buf[15]<<2|sb_buf[16]<<10) & 0x07FF);                sb_data.ch[11] = ((sb_buf[16]>>1|sb_buf[17]<<7)                & 0x07FF);                sb_data.ch[12] = ((sb_buf[17]>>4|sb_buf[18]<<4)                & 0x07FF);                sb_data.ch[13] = ((sb_buf[18]>>7|sb_buf[19]<<1|sb_buf[20]<<9)  & 0x07FF);                sb_data.ch[14] = ((sb_buf[20]>>2|sb_buf[21]<<6)                & 0x07FF);                sb_data.ch[15] = ((sb_buf[21]>>5|sb_buf[22]<<3)                & 0x07FF);                    ((sb_buf[23])      & 0x0001) ? sb_data.ch[16] = 2047: sb_data.ch[16] = 0;                ((sb_buf[23] >> 1) & 0x0001) ? sb_data.ch[17] = 2047: sb_data.ch[17] = 0;                    if ((sb_buf[23] >> 3) & 0x0001) { sb_data.failsafe = 1; }                else { sb_data.failsafe = 0; }                                cout << "DONE!" << endl;            }        }        while(count_read_symb > 0);    }
    • I checked ports buffer with sudo sh 'cat < /dev/ttyTHS1' and Putty, and all data was there but the read() returns zero.Port is in dialout group to which i have access, it configured for -rw-, and no error in ports initialization stage was catched.
  • 回答:
返回列表

上一篇:

下一篇:

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。