私はシリアルポートから高速転送速度で多くのデータを送信する単純なCプログラムを持っています。実際には、ポートから出てくるビットを見ると、ブロック開始の近く(6msから20msの間)にあるシリアルバイトにほぼ常に間隔があり、幅が約数バイト続きます。バイト(5us - 20us)。
ここに写真があります...
各送信で最大1つの間隔しか発生しません。一度発生すると、残りの100msの長さの送信は中断されません。ブロックを送信するとき、10番のうち9番はスペースがあります。
バイト間には常に間隔があるため、受信コンピュータに破損したバイトとして表示されず、通常のシリアル通信では問題になりません(少量のスループットを失わない限り)。これは、信号が連続する必要がある非日常的なアプリケーションでシリアルポートを使用したいからです。
最初はこれが一定の問題かもしれないと思いましたが、このプロセスを最適化してもギャップには影響しないようです。マシンで実行されている他の準備されたプロセスはありません。
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(gasp)です。
関連性がある場合を備えたコードは次のとおりです。
#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;
}