0

I have a TI Cortex-based Pengwyn board running embedded Linux that I am trying to use to read raw serial data from a USB-ftdi peripheral so I can process it into data packets.

To do this I've written a simple program (using Qt) and the termios framework. This works no problem on my desktop (Ubuntu VM) machine - it opens /dev/ttyUSB0, configures the serial port, reads and process the data without problems.

I run into problems when I run the same program (cross-compiled for arm obviously) on the pengwyn board... The read() function call does not populate the buffer - although it returns a non-error value, indicating the number of bytes that have been read???

(I also had to rebuilt the linux kernel for the pengwyn board to include teh USB-ftdi serial driver.)

I suspect it is a target configuration issue but I have compared the file permissions and termios settings between both the platforms and they look okay. I am new to this platform and serial/termios stuff so I have undoubtedly over-looked something but I've looked through the "Serial Programming Guide for POSIX Operating Systems" and searched for similar posts regarding arm and usb-ftdi read problems but have yet to find anything.

Any suggestions/observations?

Relevant excerpts from test program:

void Test::startRx(void)
{   
    bool retval = false;
    m_fd = open(m_port.toLocal8Bit(),O_RDONLY |O_NOCTTY | O_NDELAY);
    if (m_fd == -1)
    {
        qDebug() << "Unable to open: " << m_port.toLocal8Bit() << strerror(errno);
    }
    else
    {
        m_isConnected = true;
        qDebug() << m_port.toLocal8Bit() << "is open...";
        fcntl(m_fd, F_SETFL, 0);

        struct termios options;
        if (tcgetattr(m_fd, &options)!=0)
        {
           qDebug() << "tcgetattr() failed";
        }

        //Set the baud rates to 9600
        cfsetispeed(&options, B9600);
        cfsetospeed(&options, B9600);

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

        //Set character size
        options.c_cflag &= ~CSIZE; /* Mask the character size bits */
        options.c_cflag |= CS8;    /* Select 8 data bits */

        //No parity 8N1:
        options.c_cflag &= ~PARENB;
        options.c_cflag &= ~CSTOPB;
        options.c_cflag &= ~CSIZE;
        options.c_cflag |= CS8;

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

        //Disable software flow control
        options.c_iflag &= ~(IXON | IXOFF | IXANY);

        //Raw output
        options.c_oflag &= ~OPOST;

        //Raw input
        options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);

        //Set the new options for the port...
        tcsetattr(m_fd, TCSANOW, &options);

        int status;
        ioctl(m_fd, TIOCMGET, &status );
        qDebug() << "current modem status:" << status;


        QThread* m_reader_thread = new QThread;
        m_serial_port_reader = new SerialPortReader(0, m_fd);

        if (m_serial_port_reader)
        {            
            qDebug() << "creating serial port reader thread...";
            m_serial_port_reader->moveToThread(m_reader_thread);
            connect(m_serial_port_reader, SIGNAL(notifyRxPacketData(QByteArray *)), this, SLOT(processRxPacketData(QByteArray*)));

            //connect(m_serial_port_reader, SIGNAL(error(QString)), this, SLOT(errorString(QString)));
            connect(m_reader_thread, SIGNAL(started()), m_serial_port_reader, SLOT(process()));
            connect(m_serial_port_reader, SIGNAL(finished()), m_reader_thread, SLOT(quit()));
            connect(m_serial_port_reader, SIGNAL(finished()), m_serial_port_reader, SLOT(quit()));
            connect(m_reader_thread, SIGNAL(finished()), m_reader_thread, SLOT(deleteLater()));
            m_reader_thread->start();
            retval = true;
        }

....

void SerialPortReader::readData(int i)
{
    m_socket_notifier->setEnabled(false);
    if (i == m_fd)
    {
        unsigned char buf[BUFSIZE] = {0};
        int bytesRead = read(m_fd, buf, BUFSIZE);
        //qDebug() << Q_FUNC_INFO << "file decriptor:" << m_fd << ", no. bytes read:" << bytesRead;

        if (bytesRead < 0)
        {
          qDebug() << Q_FUNC_INFO << "serial port read error";
          return;
        }
        // if the device "disappeared", e.g. from USB, we get a read event for 0 bytes
        else if (bytesRead == 0)
        {
           //qDebug() << Q_FUNC_INFO << "finishing!!!";
           return;
        }
        //process data...
    }
    m_socket_notifier->setEnabled(true);
}
4

0 回答 0