Serial port 嵌入式linux usb ftdi串行端口读取问题
我有一个基于TI Cortex的Pengwyn板,运行嵌入式Linux,我试图用它从USB ftdi外设读取原始串行数据,以便将其处理为数据包 为此,我编写了一个简单的程序(使用Qt)和termios框架。这在我的桌面(Ubuntu VM)机器上没有问题——它打开/dev/ttyUSB0,配置串行端口,读取和处理数据,没有问题 当我在pengwyn板上运行相同的程序(显然是为arm交叉编译)时,我遇到了问题。。。read()函数调用不会填充缓冲区-尽管它返回一个非错误值,指示已读取的字节数 (我还必须为pengwyn板重建linux内核,以包含USB ftdi串行驱动程序。) 我怀疑这是一个目标配置问题,但我已经比较了两个平台之间的文件权限和termios设置,它们看起来不错。我对这个平台和serial/termios之类的东西还不熟悉,所以我毫无疑问地浏览了一些东西,但我已经浏览了“POSIX操作系统的串行编程指南”,并搜索了关于arm和usb ftdi读取问题的类似帖子,但还没有找到任何东西 有什么建议/意见吗 测试计划的相关摘录:Serial port 嵌入式linux usb ftdi串行端口读取问题,serial-port,embedded-linux,usbserial,Serial Port,Embedded Linux,Usbserial,我有一个基于TI Cortex的Pengwyn板,运行嵌入式Linux,我试图用它从USB ftdi外设读取原始串行数据,以便将其处理为数据包 为此,我编写了一个简单的程序(使用Qt)和termios框架。这在我的桌面(Ubuntu VM)机器上没有问题——它打开/dev/ttyUSB0,配置串行端口,读取和处理数据,没有问题 当我在pengwyn板上运行相同的程序(显然是为arm交叉编译)时,我遇到了问题。。。read()函数调用不会填充缓冲区-尽管它返回一个非错误值,指示已读取的字节数 (我
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);
}
void测试::startRx(void)
{
bool-retval=false;
m_fd=打开(m_port.toLocal8Bit(),O_RDONLY | O|u NOCTTY | O|NDELAY);
如果(m_fd==-1)
{
qDebug()您可能希望使用终端程序验证硬件/内核驱动程序,并尝试编写一个更简单的测试程序。听起来您好像在说您根本没有填充任何数据,但您还应该注意read()可以为您提供的字节数少于您请求的字节数。串行端口设置为非规范模式,但您忘记定义VMIN和VTIME参数。由于程序将使用默认值,这可能会导致两个环境之间的差异。在更正此问题之前,请在之后打印VMIN和VTIME的值tcgetattr()
查看Ubuntu和嵌入式系统之间的默认值是否存在差异。顺便说一句,fcntl()
,tcsetattr()
和ioctl()
调用的返回值应该经过检查。感谢您的建议。不幸的是,VMIN(1)和VTIME(0)两者都是一样的。我开始认为这是驱动程序的问题,或者是我如何配置目标系统的问题。我没有访问设备上的终端程序,但我使用了:od-x
来显示十六进制转储的流量,它要么什么也不显示,要么ttyUSB0:2输入溢出