向 tty 设备发送长串行数据块时,5us-20us 延迟间隙的可能来源?

向 tty 设备发送长串行数据块时,5us-20us 延迟间隙的可能来源?

我有一个简单的 C 程序,它只是以快速波特率从串行端口发送大量数据。当查看实际从端口输出的位时,我发现串行字节中几乎总是存在一个间隙,该间隙接近块的开头(6 毫秒到 20 毫秒之间),并且持续大约几个字节的宽度。字节(5us - 20us)。

这是一张图片...

数据差距的范围视图

每次传输最多只出现 1 次间隙,一旦发生,其余 100ms 长的传输将不会中断。我发送区块时,大约十分之九会出现间隙。

间隙总是出现在字节之间,因此不会在接收计算机上显示为损坏的字节,并且对于正常的串行通信不会成为问题(除非您失去了少量的吞吐量),但它在我的应用程序中很重要,因为我想在信号需要连续的非常规应用中使用串行端口。

起初我以为这可能是一个调度问题,但优化这个过程似乎对差距没有任何影响。机器上没有其他就绪进程正在运行。

pi@raspberrypi ~ $ ps all
F   UID   PID  PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND
4     0  2101     1  20   0   3744   804 n_tty_ Ss+  tty1       0:00 /sbin/getty
4     0  2102     1  20   0   3744   804 n_tty_ Ss+  tty2       0:00 /sbin/getty
4     0  2103     1  20   0   3744   804 n_tty_ Ss+  tty3       0:00 /sbin/getty
4     0  2104     1  20   0   3744   804 n_tty_ Ss+  tty4       0:00 /sbin/getty
4     0  2105     1  20   0   3744   804 n_tty_ Ss+  tty5       0:00 /sbin/getty
4     0  2106     1  20   0   3744   804 n_tty_ Ss+  tty6       0:00 /sbin/getty
0  1000 16370 27290  20   0   4136   956 -      R+   pts/1      0:00 ps all
0  1000 27290 27289  20   0   8252  5508 wait   Ss   pts/1      1:04 -bash
pi@raspberrypi ~ $ ./sendzeros /dev/ttyAMA0
Please start with ./sendzeros /dev/ttyS1 (for example)

我正在努力找出这个差距的根源,希望能够消除它。关于可能的原因有什么想法吗?

下一步将是编写一个中断触发的设备驱动程序,直接保持 UART 缓冲区满,但如果可能的话,我更愿意留在用户区。我现在也想知道,这样我就可以更好地理解这样的延迟源可能来自内核中的何处。

该机器是运行 Raspbian 的 Raspberry Pi(喘息)。

这是代码,以防它可能相关......

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>


#define COUNT 24000             // Number of bytes to send...

int main(int argc,char** argv)
{
        struct termios tio;
        int tty_fd;

        printf("Please start with %s /dev/ttyS1 (for example)\n",argv[0]);

        tty_fd=open(argv[1], O_WRONLY );

        tcgetattr(tty_fd,&tio);

        tio.c_iflag=0;
        tio.c_oflag=0;
        tio.c_cflag=CS8|CREAD|CLOCAL;           // 8n1, see termios.h for more $
        tio.c_lflag=0;

        cfmakeraw( &tio );

        int ssr = cfsetospeed(&tio,  B2500000 );

        tcsetattr(tty_fd,TCSANOW,&tio);

        // This bit pattern makes it possible to see disruptions on an attached$

        char buffer[ COUNT ];

        memset( buffer , 0 , sizeof(buffer ) );

        write(tty_fd,&buffer,sizeof(buffer));                     // if new dat$

        close(tty_fd);

        return EXIT_SUCCESS;
}

相关内容