Моделирование скорости передачи

Мне нужно создать симуляцию нуль-модема для тестирования различных программ. Я использовал socat для этого:

socat -d -d pty,raw,echo=0 pty,raw,echo=0 &

Но мне также нужно смоделировать базовые скорости передачи последовательного порта и эффекты буферов UART различной длины. Параметры socat baud rate (b ####), ispeed и ospeed не имеют никакого эффекта при выполнении этого типа обратной петли pty. Например:

socat -d -d pty,raw,echo=0,b50,ispeed=50,ospeed=50 pty,raw,echo=0,b50,ispeed=50,ospeed=50 &

Это должно привести к очень низкой скорости передачи данных. Тем не менее, при передаче данных через эту петлю данные передаются с максимальной машинной скоростью. Это меня не удивляет, поскольку в шлейфе нет настоящего оборудования.

Итак, есть ли способ имитировать синхронизацию UART без написания собственного кода?

Моя конечная цель - смоделировать большое устройство Ethernet-to-Serial, такое как Moxa 5600 (16 портов), и то, как влияние последовательной пропускной способности влияет на потоки сокетов TCP и т. Д. И т. Д.

Спасибо,


person xl600    schedule 25.02.2021    source источник
comment
Существуют сетевые симуляторы (и последовательный порт можно рассматривать как сеть, содержащую одно двухточечное соединение, например поток TCP), которые вводят формирование трафика, искусственную задержку, ошибку и т. Д. Вы можете использовать один из них с последовательный порт, используя socat для копирования данных между одним pty в сетевой сокет, а второй экземпляр socat копирует между другим концом того же соединения и другим pty.   -  person Ben Voigt    schedule 25.02.2021
comment
Обратите внимание, что поведение буферизации сильно различается между разными моделями реального последовательного порта (по крайней мере, разные драйверы и подключения к шине, такие как UART 16550A, USB FTDI и USB CDC), поэтому было бы трудно иметь симулятор pty, который просто делал бы правильные вещи. , вероятно, потребуется немало настраиваемой конфигурации, даже если это не настраиваемый код.   -  person Ben Voigt    schedule 25.02.2021
comment
Я уверен, что такие устройства, как Moxa 5600, уникальны сами по себе, но мне нужно с чего-то начать, и простое моделирование базовой скорости передачи данных может быть «достаточно хорошим» для продолжения.   -  person xl600    schedule 25.02.2021
comment
Для ограничения скорости передачи данных (пропускной способности) я бы предложил добавить виртуальный сетевой интерфейс tun / tap, маршрутизируя ваш трафик socat через него, а не напрямую между ptys, а затем настроить формирование трафика на этом интерфейсе tun / tap.   -  person Ben Voigt    schedule 25.02.2021
comment
Также см. man throttle. Вы можете использовать socat для запуска этого, подключая каждый конец к другому pty (но я не думаю, что это даст вам двунаправленный трафик)   -  person Ben Voigt    schedule 25.02.2021
comment
Я пробовал подход tuntap, используя простой эхо-сервер TCP, но не смог получить никакого фактического (видимого) ограничения скорости. Например: tc qdisc replace dev mytap root tbf rate 300bit пиковая скорость 310bit limit 100 maxburst 10 minburst 10   -  person xl600    schedule 25.02.2021
comment
Я предполагаю, что tc просто задерживает целые пакеты, а не ограничивает количество в каждом пакете. socat должен быть на это способен. Попробуйте его -b вариант.   -  person Ben Voigt    schedule 25.02.2021
comment
Я также не вижу bit в списке разрешенных суффиксов для tc   -  person Ben Voigt    schedule 25.02.2021


Ответы (2)


Я не считаю это практическим решением, но это забавное решение. Зачем имитировать нуль-модем, если можно имитировать настоящий модем. 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 секунд.

person meuh    schedule 25.02.2021
comment
Очень интересно :) Никогда бы не подумал о таком. Я пытаюсь смоделировать последовательные скорости от 1200 до 115200 бод, но я собираюсь попробовать это, чтобы увидеть, как это работает. - person xl600; 25.02.2021

Я вспомнил, что у expect есть возможность имитировать набор текста человеком, а также медленно выводить символы один за другим для некоторых аппаратных устройств, у которых нет входного FIFO и которые действительно разборчивы. На странице руководства (отредактировано):

send_slow принимает список из двух элементов. Первый элемент - это целое число, которое описывает количество байтов для атомарной отправки. Второй элемент - это действительное число, которое описывает количество секунд, на которые атомарные посылки должны быть разделены. Например, set send_slow {10 .001} отправляет строки с интервалом в 1 миллисекунду между каждыми 10 отправленными символами.

Вот ожидаемый скрипт slowly, использующий эту функцию, которая медленно копирует stdin в stdout.

#!/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 также может быть полезен для имитации определенного типа прерывистого потока данных, подобного человеческому, и устранения некоторых ошибок.

person meuh    schedule 26.02.2021