USB-ftdi周辺機器から生のシリアルデータを読み取ってデータパケットに処理できるように、組み込みLinuxを実行しているTI CortexベースのPengwynボードを使用しています。
これを行うために、簡単なプログラム (Qt を使用) と termios フレームワークを作成しました。これは私のデスクトップ (Ubuntu VM) マシンでは問題なく動作します。/dev/ttyUSB0 を開き、シリアル ポートを構成し、問題なくデータを読み取って処理します。
pengwyn ボードで同じプログラム (明らかに arm 用にクロスコンパイル) を実行すると問題が発生します...読み取られたバイト???
(さらに、pengwyn ボード用の Linux カーネルを再構築して、USB-ftdi シリアル ドライバを含める必要がありました。)
ターゲット構成の問題であると思われますが、両方のプラットフォーム間でファイルのアクセス許可と termios の設定を比較したところ、問題ないようです。私はこのプラットフォームとシリアル/termiosのことは初めてなので、間違いなく何かを見落としましたが、「POSIXオペレーティングシステムのシリアルプログラミングガイド」に目を通し、armおよびusb-ftdi読み取りの問題に関する同様の投稿を検索しましたが、まだ何も見つかりません。
提案/観察はありますか?
テスト プログラムからの関連する抜粋:
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);
}