我需要创建一个无调制解调器模拟来测试各种软件。我一直在使用socat来做这个:
socat -d -d pty,raw,echo=0 pty,raw,echo=0 &
但是我还需要模拟串口的基本波特率和各种长度的UART缓冲区的效果。在进行这种类型的pty环回时,cat的波特率(b####)、isspeed和ospeed参数似乎没有任何影响。例如:
socat -d -d pty,raw,echo=0,b50,ispeed=50,ospeed=50 pty,raw,echo=0,b50,ispeed=50,ospeed=50 &
应该导致非常慢的数据速率。然而,当通过这个环回传递数据时,数据以最大的机器速度传输。这并不让我感到惊讶,因为在循环中没有真正的硬件。
那么,有没有一种方法来模拟UART时间短编写自定义代码?
我的最终目标是模拟大型以太网到串行设备,如Moxa 5600(16端口),以及串行吞吐量如何影响TCP套接字流等…等等…
谢谢,
我不认为这是一个实用的解决方案,但它是一个有趣的解决方案。当您可以模拟真实的调制解调器时,为什么要模拟空调制解调器呢?. Minimodem在某些发行版中作为软件包提供,可以将数据转换为调制解调器音频音调,反之亦然。要尝试一下,只需以波特率10和0.1的音量听这个音频:
$ echo 'the quick brown fox' | minimodem -v 0.1 --tx 10
运行大约需要20秒。如果你直接输出到一个文件,它是即时的,但是你可以"播放"。使用sox
创建文件,并将音调解释回数据:
$ echo 'the quick brown fox' | minimodem -v 0.1 --tx 10 -f out.wav
$ file out.wav
out.wav: RIFF (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, mono 48000 Hz
$ sox out.wav -t wav - | minimodem -f - --rx 10
### CARRIER 10.00 @ 1590.0 Hz ###
the quick brown fox
### NOCARRIER ndata=20 confidence=33.775 ampl=0.064 bps=10.00 (rate perfect) ###
这仍然是瞬时的,但表明它可以工作。
要以正确的速度播放wav文件中的音调,需要通过音频设备播放。但是我们可以使用软件环回设备来实现:
$ sudo modprobe snd-aloop
$ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: PCH [HDA Intel PCH], device 0: ALC662 rev1 Analog [ALC662 rev1 Analog]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: PCH [HDA Intel PCH], device 3: HDMI 0 [HDMI 0]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 1: Loopback [Loopback], device 0: Loopback PCM [Loopback PCM]
Subdevices: 7/8
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
Subdevice #2: subdevice #2
Subdevice #3: subdevice #3
Subdevice #4: subdevice #4
Subdevice #5: subdevice #5
Subdevice #6: subdevice #6
Subdevice #7: subdevice #7
card 1: Loopback [Loopback], device 1: Loopback PCM [Loopback PCM]
Subdevices: 8/8
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
Subdevice #2: subdevice #2
Subdevice #3: subdevice #3
Subdevice #4: subdevice #4
Subdevice #5: subdevice #5
Subdevice #6: subdevice #6
Subdevice #7: subdevice #7
我们现在有8个环回设备(模块有一个参数来请求更多)。例如,我们现在可以在卡片1,设备1,子设备2上播放声音,并在卡片1,设备0,子设备2上收听声音。播放,耗时20秒:
$ sox out.wav -t alsa hw:1,1,2
out.wav:
File Size: 1.96M Bit Rate: 768k
Encoding: Signed PCM
Channels: 1 @ 16-bit
Samplerate: 48000Hz
Replaygain: off
Duration: 00:00:20.40
In:47.7% 00:00:09.73 [00:00:10.67] Out:467k [ -=|=- ] Clip:0
听:
$ sox -q -t alsa hw:1,0,2 -t wav -c 1 - | minimodem --rx 10 -f -
### CARRIER 10.00 @ 1590.0 Hz ###
the quick brown fox
### NOCARRIER ndata=21 confidence=10.265 ampl=0.060 bps=10.00 (rate perfect) ###
字符一个接一个出现需要20秒。
我记得expect
有一个模拟人类打字的选项,并且对于一些没有输入fifo并且非常挑剔的硬件设备,也可以逐个缓慢地输出字符。手册页(已编辑):
send_slow接受一个包含两个元素的列表。第一个元素是描述要自动发送的字节数的整数。第二个元素是一个实数,用来描述的个数原子发送的秒数必须分开。例如,set send_slow {10.001}"发送间隔1毫秒的字符串每10个字符发送。
这是一个期望脚本,slowly
,使用复制标准输入到标准输出的功能,慢慢地。
#!/usr/bin/expect
# 8890 bd
set send_slow {1 .001}
# 17740
set send_slow {2 .001}
# 95970
set send_slow {10 .001}
# 143660
set send_slow {15 .001}
# 123210
set send_slow {14 .001}
# 107770
set send_slow {12 .001}
# time the run. get eg: 1866426 microseconds per iteration
set total 0
set runtime [time {
while {1} {
if {[eof stdin]} { break }
set data [read stdin 99]
send_user -s $data
set total [expr $total + [string bytelength $data]]
}
}]
set runtime [lindex $runtime 0]
set bps [expr $total * 1000 * 1000 / $runtime]
set baud [expr $bps * 10]
puts stderr "$runtime usecs $total bytes $bps bytes/sec $baud baud"
尝试一下,让文件可执行并给它一些数据,例如:
yes abcdefghijklmnopqrstuvwxyz | dd bs=27 count=1000 status=none >input
./slowly <input >output
通过上面的操作,我得到了大约107520的波特率:
2510973 usecs 27000 bytes 10752 bytes/sec 107520 baud
通过将send_slow
参数更改为1 .001
(并减小数据文件大小!),它可以降低到大约9000波特率。为了变得更慢,1 .008
将达到大约1230波特。
send_human
类型的输出对于模拟某种类型的"抖动"也很有用。像人一样的数据流,并清除一些错误。