我正在使用ARM iMX6处理器的嵌入式Linux设备上进行开发。主要目的是从外部源读取传入的串行流。
由于串行流的非典型特性,我遇到了一些带有Linux serial driver imx处理器的障碍。但没有任何超出iMX6能力的东西。例如,输入串行流是反向逻辑。 iMX6具有特定的寄存器设置以反转RX信号。据我所知,Linux驱动程序没有公开它。
另一个复杂因素是输入的串行数据以3ms的突发时间到达。外部源连续发送3ms,然后3ms空闲,然后3ms数据,然后空闲等。为了与每个突发的第一个字节同步,能够检测到什么时候非常有用。线路空闲。同样,iMX6有一个寄存器值,专门用于指示RX线路空闲,但Linux驱动程序没有公开它。
我也很困惑缓冲如何在驱动程序中工作。我知道iMX6有一个32字节的FIFO缓冲区,但我无法判断驱动程序是使用该缓冲区还是使用外部RAM进行缓冲。我遇到一个问题,read
命令在阻塞模式下经常挂起一秒钟,这种情况永远不会发生,因为数据流是连续的。
作为参考,这里是我如何在C代码中配置串口并读取50个字节(我现在已将其更改为非阻塞):
#include <stropts.h>
#include <asm/termios.h>
#include <unistd.h>
#include <fcntl.h>
int main()
{
int fd;
struct termios2 terminal;
unsigned char v[50];
fd = open ("/dev/ttymxc2", O_RDONLY | O_NOCTTY | O_NONBLOCK );
ioctl(fd, TCGETS2, &terminal);
terminal.c_cflag |= (CLOCAL | CREAD) ;
terminal.c_cflag |= PARENB ; //enable parity
terminal.c_cflag &= ~PARODD ; //even parity
terminal.c_cflag |= CSTOPB ; //2 stop bits
terminal.c_cflag &= ~CSIZE ;
terminal.c_cflag |= CS8 ;
terminal.c_lflag &= ~(ICANON | IEXTEN | ECHO | ECHOE | ISIG) ;
terminal.c_oflag &= ~OPOST ;
terminal.c_cflag &= ~CBAUD;
terminal.c_cflag |= BOTHER;
terminal.c_ispeed = 100000; //100kHz baud
terminal.c_ospeed = 100000;
ioctl(fd, TCSETS2, &terminal);
...
for(i=0;i<50;i++)
{
read(fd,v+i,1)
}
...
}
所以我有两个问题:
什么是&#34;适当的&#34;如何从处理器可用的串行端口获取功能,但驱动程序没有暴露?我无法想象我是第一个想要使用处理器的基本功能的人,但我不想重新发明轮子。我是否需要编写自己的驱动程序?
是否有关于iMX串行驱动程序的综合文档?代码评论很差,我很快就迷失了,试图找到解决方法。例如,我不知道从哪里开始调查缓冲问题会导致它在接收连续数据流时挂起。
答案 0 :(得分:0)
我完全放弃了串行驱动程序,而是直接编写了一些函数来访问寄存器内存(以devmem2.c源代码为模型)。现在我可以直接设置INVR位来反转RX信号,使用IDLE位来检测线路何时空闲,并在它们到达时立即检索输入数据字节。
我在另一个关于UART DMA的论坛上发现了一些东西需要RX线在服务缓冲区之前至少闲置8ms。这显然是我遇到的1秒滞后的原因。