Платформенная справка ArmSoM: китайский RK-KF-YF-100 V1.1.1 охватывает серии 30, 31, 32, 33, PX, Sofia и RV1108 с Linux 3.10/4.4, но не подтверждает поддержку всех плат ArmSoM. Проверяйте плату, SoC, BSP, разводку, контроллер и ядро. Все результаты — примеры источника, не измерения ArmSoM; аппаратная проверка не проводилась. Английского PDF нет; во всех четырёх версиях используются четыре рисунка китайского PDF.
Замечания: сохранены исторические имена USB, “400MBps?”, Webcam 648×480 / UYV и KB/MB без единицы времени; это не утверждения о современных стандартах. Исходные rm of=…, ehco, длинные тире в параметрах blkparse и пробел в пути сомнительны; перед применением сверяйте синтаксис инструмента. Прямая запись на диск, сброс кеша, изменение Gadget, отключение ядер CPU и межсетевого экрана влияют на систему: это только исходные лабораторные процедуры, они не выполнялись, нужна изолированная среда. Противоречие HID protocol=2 и комментария Keyboard также сохранено.
1. Теоретические скорости USB
1.1 USB Communication Flow
Рисунок 1-1 показывает многоуровневую модель USB: соединение хоста с устройством состоит из связей нескольких уровней. Уровень интерфейса шины обеспечивает физическое соединение и передачу/приём данных. Уровень устройства видим системному ПО USB, выполняющему общие операции. Прикладной уровень через соответствующее клиентское ПО предоставляет хосту дополнительные функции. Связь уровней устройства и приложения логическая; физическую передачу выполняет интерфейс шины.

Рисунок 1-1. USB Communication Flow
1.2 Скорость физического уровня
Скорость физического уровня — скорость физической шины USB. Исторический источник перечисляет пять стандартов: USB1.0, USB1.1, USB2.0, USB3.0 (USB3.1 Gen1), USB3.1 Gen2. Максимальные скорости приведены в таблице 1-1.
| Версия USB | Максимальная скорость | Обозначение |
|---|---|---|
| USB 1.0 | 1.5Mbps | Низкая скорость(Low-Speed) |
| USB 1.1 | 12Mbps | Полная скорость(Full-Speed) |
| USB 2.0 | 480Mbps | Высокая скорость(High-Speed) |
| USB 3.0(USB 3.1 Gen1) | 5Gbps | Сверхскорость(Super-Speed) |
| USB 3.1 Gen2 | 10Gbps | В источнике ещё не определено(Super-Speed+) |
1.3 Скорость протокольного уровня
Типы USB-устройств используют разные классовые протоколы: накопители — подкласс USB Mass Storage Class Bulk-Only Transport, камеры — USB Video Class, HID — USB Human Interface Devices Class. Другие спецификации доступны у USB-IF. Форматы пакетов различаются; некоторые протоколы требуют командных пакетов и подтверждений. Различаются и виды передачи: накопители — Bulk, камеры — Isochronous, HID — Interrupt.
Четыре вида:
- Control: перечисление при подключении и специальные операции устройства.
- Interrupt: надёжная передача небольших объёмов с жёсткими требованиями задержки, например клавиатуры и игровые контроллеры.
- Bulk: надёжные большие объёмы без строгой задержки, например накопители и Ethernet.
- Isochronous: передача в реальном времени с меньшими требованиями надёжности, например камеры и аудио.
На физической шине различия невелики; отличаются механизмы, планирование хостом, доступная полоса и максимальная длина пакета. Сравнение дано в таблице 1-2.
| Тип передачи | USB 2.0 | USB 3.0 |
|---|---|---|
| Управляющая | Max Packet: 64Bytes Burst:Не поддерживается Управление потоком только OUT(PING) |
Max Packet: 512Bytes Burst:1 Управление потоком(ERDY) |
| Прерывания | Max Packet: 0 〜 1024 ×3 Bytes Max Transfer Speed:23.44MBps Burst:Не поддерживается Нет управления потоком |
Max Packet: 0 〜 1024 ×3 Bytes Max Transfer Speed:23.44MBps Burst:1 ~ 3 Управление потоком(ERDY) |
| Массовая | Max Packet: 512Bytes Max Transfer Speed:53.25MBps Burst:Не поддерживается Управление потоком только OUT(PING) |
Max Packet: 1024Bytes Max Transfer Speed:400MBps? Burst:1 〜 16 Управление потоком(ERDY)) |
| Изохронная | Max Packet: 0 〜 1024 ×3 Bytes Max Transfer Speed:23.44MBps Burst:Не поддерживается Нет управления потоком |
Max Packet: 0 〜 1024 ×16 × 3Bytes Max Transfer Speed:375.04MBps Burst:1 ~ 16 Управление потоком(PING -> PING_RESPONSE) |
Таблица 1-2 показывает разные теоретические пределы для видов передачи. Их ограничения и взаимодействие классовых протоколов делают реальную скорость значительно ниже физической.
1.4 Основные факторы скорости
Скорость USB в основном зависит от следующих факторов:
-
Качество сигнала. Его оценивают по глазковой диаграмме USB. Плохой сигнал вызывает потери пакетов и повторные передачи, снижая скорость.
-
AHB CLK контроллера и DMA Burst Length. Более высокая частота AHB и длинные DMA-пакеты могут улучшить эффективность DMA.
-
Частота CPU влияет на выполнение кода и memcpy. Её повышение может ускорить драйвер USB и приложение, увеличивая скорость.
-
Размер буфера URB (USB Request Block) задаёт блок одной передачи контроллера. Для примеров, отнесённых источником к MSC, включая USB Disk и USB MTP, увеличение буфера уменьшает число прерываний, если не учитывать влияние размера блока на eMMC/NAND. Указаны максимумы одной передачи: DWC2 — 512KB, DWC3 — 16MB - 1 Bytes.
-
Скорость носителей. MSC-устройства, например накопители, зависят от производительности носителя хоста и самого USB-накопителя.
-
Формат файловой системы.
Распространённые форматы — VFAT, EXT4, NTFS. В стеке источника блочный слой ядра объединяет маленькие блоки VFAT/EXT4 в 120K перед записью; NTFS пишет из userspace без такого объединения. При запросах приложения по 4KB скорость NTFS может быть существенно ниже VFAT/EXT4. Анализ см. в разделе 2.1.
2. Производительность USB Host
2.1 Скорость USB-накопителя
Методика. Предполагается следующий раздел после подключения к USB Host:
/dev/block/sda1
Точка монтирования:
/mnt/media_rw/0E64-5F76/
Путь файла eMMC хоста: /sdcard/. Методы ниже используют эти пути.
Нужен достаточно большой test. Для 3399 EVB с 4G DDR источник рекомендует 2G и сообщает неточность при 1024MB. Объяснение: proc/sys/vm/dirty_background_ratio обычно 5%; асинхронная запись начинается при 4G × 5% = 204.8MB грязных страниц. conv=fsync у dd записывает кэш на диск.
Два метода. Метод 1: вручную либо cp скопировать большой файл, например фильм, измерить время и скорость. Шаг 1 создаёт test через dd для шага 2.
busybox dd if=/dev/zero of=/mnt/media_rw/0E64-5F76/test bs=64K count=16K
Шаг 2. Измерьте время cp.
echo 3 > /proc/sys/vm/drop_caches
time cp /mnt/media_rw/0E64-5F76/test /sdcard/.
Так проверяется чтение. Для записи поменяйте пути. Метод 2 использует dd. Для чтения шаг 1 создаёт test для следующих копирований.
busybox dd if=/dev/zero of=/mnt/media_rw/0E64-5F76/test bs=64K count=16K
Шаг 2. Очищайте кэш перед каждым dd.
echo 3 > /proc/sys/vm/drop_caches
Проверьте чтение блоками 4K.
busybox dd if=/mnt/media_rw/0E64-5F76/test of=/dev/null bs=4K count=256K
Шаг 3. Очищайте кэш перед каждым dd.
echo 3 > /proc/sys/vm/drop_caches
Проверьте чтение блоками 64K.
busybox dd if=/mnt/media_rw/0E64-5F76/test of=/dev/null bs=64K count=16K
Шаг 4. Очищайте кэш перед каждым dd.
echo 3 > /proc/sys/vm/drop_caches
Проверьте чтение блоками 128K.
busybox dd if=/mnt/media_rw/0E64-5F76/test of=/dev/null bs=128K count=8K
Шаг 5. Очищайте кэш перед каждым dd.
echo 3 > /proc/sys/vm/drop_caches
Проверьте чтение блоками 512K.
busybox dd if=/mnt/media_rw/0E64-5F76/test of=/dev/null bs=512K count=2K
Запись USB-накопителя: шаг 1. Очистите кэш перед каждым dd.
echo 3 > /proc/sys/vm/drop_caches
Проверьте запись блоками 4K.
busybox dd if=/dev/zero of=/mnt/media_rw/0E64-5F76/test bs=4K count=256K
Шаг 2.
rm of=/mnt/media_rw/0E64-5F76/test
sync
echo 3 > /proc/sys/vm/drop_caches
Проверьте запись блоками 64K.
busybox dd if=/dev/zero of=/mnt/media_rw/0E64-5F76/test bs=64K count=16K
Шаг 3.
rm of=/mnt/media_rw/0E64-5F76/test
sync
echo 3 > /proc/sys/vm/drop_caches
Проверьте запись блоками 128K.
busybox dd if=/dev/zero of=/mnt/media_rw/0E64-5F76/test bs=128K count=8K
Шаг 4.
rm of=/mnt/media_rw/0E64-5F76/test
sync
echo 3 > /proc/sys/vm/drop_caches
Проверьте запись блоками 512K.
busybox dd if=/dev/zero of=/mnt/media_rw/0E64-5F76/test bs=512K count=2K
Метод 1 измеряет реальное копирование, но смешивает влияние носителя хоста, ФС и USB-контроллера, не изолируя его производительность. Метод 2 исключает носитель/ФС хоста, однако ФС USB-устройства всё ещё влияет. Прямой доступ к sd* в /dev/ обходит её, но может уничтожить данные: необходима крайняя осторожность. conv=fsync записывает кэш на диск; большой файл также снижает влияние кэша. Источник рекомендует оба метода: сначала 1, при недостаточной скорости — 2 для поиска ограничения контроллера.
Результаты источника с dd: USB2.0 Host обычно 25–35MBps; USB3.0 без UAS — 60–100MBps; с UAS — до примерно 350MBps. Носители сильно различаются; чтение некоторых быстрее записи в 3–5 раз. Проверяйте несколько моделей, сравнивая те же устройства тем же способом на Ubuntu PC.
USB3 RK3399/RK3328 поддерживает UASP (USB Attached SCSI PROTOCOL), способный существенно повысить скорость. Нужны CONFIG_USB_UAS (по умолчанию включён в Kernel3.10/4.4 источника) и поддержка UAS накопителем. Использование протокола видно в журнале перечисления.
[80373.513866] usb 4-1: new SuperSpeed USB device number 2 using xhci_hcd
[80373.534854] usb 4-1: New USB device found, idVendor=174c, idProduct=55aa
[80373.534871] usb 4-1: New USB device strings: Mfr=2, Product=3, SerialNumber=1
[80373.534873] usb 4-1: Product: CHIPFANCIER
[80373.534874] usb 4-1: Manufacturer: WINTOGO
[80373.534876] usb 4-1: SerialNumber: 000001485761816
[80373.537036] scsi host6: uas (说明将以UAS协议进⾏通信)
[80373.537648] scsi 6:0:0:0: Direct-Access WINTOGO CHIPFANCIER 0 PQ: 0 ANSI: 6
Пример анализа и оптимизации: чтение/запись USB3-накопителя на RK3399 EVB. Метод применим для анализа других сценариев.
Условия источника: RK3399 EVB, 2G DDR + 16G eMMC; SanDisk Type-C USB3.0 32G, NTFS. Копирование большого файла с USB3 в eMMC через cp/dd. USB: /mnt/media_rw/0E64-5F76/, eMMC: /sdcard/. При 4G DDR источник рекомендует файл 2GB для уменьшения влияния кэша; conv=fsync записывает кэш на диск, большой файл также снижает влияние. Шаг 1 создаёт test размером 1GB через dd.
busybox dd if=/dev/zero of=/mnt/media_rw/0E64-5F76/test bs=64K count=16K
Шаг 2 проверяет копирование USB3 в eMMC. Для test 1GB источник сообщает 0m48.42s real 0m00.29s user 0m18.17s system, то есть 1024M/48 = 21MBps, ниже ожидаемой скорости USB3.
Шаг 3 копирует прямо из /dev/block/sda1 в /sdcard/test, обходя ФС USB-накопителя. Результат около 20MBps; источник заключает, что причина не в самой ФС 3399.
Шаг 4 отдельно проверяет USB-накопитель и eMMC через dd. Сначала чтение USB3; очищайте кэш перед каждой командой.
time cp /mnt/media_rw/0E64-5F76/test /sdcard/.
time cp /dev/block/sda1 /sdcard/test
echo 3 > /proc/sys/vm/drop_caches
Проверьте чтение блоками 4K.
busybox dd if=/mnt/media_rw/0E64-5F76/test of=/dev/null bs=4K count=256K
Результат источника: 1073741824 bytes (1.0GB) copied, 14.183164 seconds, 72.2MB/s. Очищайте кэш перед каждым dd.
echo 3 > /proc/sys/vm/drop_caches
Проверьте чтение блоками 64K.
busybox dd if=/mnt/media_rw/0E64-5F76/test of=/dev/null bs=64K count=16K
Результат источника: 1073741824 bytes (1.0GB) copied, 12.546069 seconds, 81.6MB/s. Очищайте кэш перед каждым dd.
echo 3 > /proc/sys/vm/drop_caches
Проверьте чтение блоками 128K.
busybox dd if=/mnt/media_rw/0E64-5F76/test of=/dev/null bs=128K count=8K
Результат источника: 1073741824 bytes (1.0GB) copied, 12.601817 seconds, 81.3MB/s. Очищайте кэш перед каждым dd.
echo 3 > /proc/sys/vm/drop_caches
Проверьте чтение блоками 512K.
busybox dd if=/mnt/media_rw/0E64-5F76/test of=/dev/null bs=512K count=2K
Результат: 1073741824 bytes (1.0GB) copied, 12.402147 seconds, 82.6MB/s. Затем запись eMMC 3399; очищайте кэш перед каждым dd.
echo 3 > /proc/sys/vm/drop_caches
Проверьте запись блоками 4K.
busybox dd if=/dev/zero of=/sdcard/test bs=4K count=256K
Результат источника: 1073741824 bytes (1.0GB) copied, 39.525297 seconds, 25.9MB/s
rm of=/sdcard/test
sync
echo 3 > /proc/sys/vm/drop_caches
Проверьте запись блоками 64K.
busybox dd if=/dev/zero of=/sdcard/test bs=64K count=16K
Результат источника: 1073741824 bytes (1.0GB) copied, 37.505206 seconds, 27.3MB/s
rm of=/sdcard/test
sync
echo 3 > /proc/sys/vm/drop_caches
Проверьте запись блоками 128K.
busybox dd if=/dev/zero of=/sdcard/test bs=128K count=8K
Результат источника: 1073741824 bytes (1.0GB) copied, 37.461603 seconds, 27.3MB/s
rm of=/sdcard/test
sync
echo 3 > /proc/sys/vm/drop_caches
Проверьте запись блоками 512K.
busybox dd if=/dev/zero of=/sdcard/test bs=512K count=2K
Результат: 1073741824 bytes (1.0GB) copied, 37.086531 seconds, 27.6MB/s. Чтение USB3 быстро и почти одинаково для разных блоков; вся запись eMMC медленна. Источник считает узким местом носитель eMMC. Здесь медленны 4K/64K/128K/512K; у многих eMMC Rockchip и USB3-накопителей, по источнику, медленны только 4K. Если проблема только в 4K, исследуйте этот размер. Шаг 5 анализирует cp и блочный слой через strace и blktrace.
Проследите cp через strace:
strace cp /mnt/media_rw/0E64-5F76/test /sdcard/.
Источник установил, что cp на RK3399 читает/пишет по 4KB. Для анализа объединения блоков используйте blktrace. Важные параметры:
max_hw_sectors_kb
max_sectors_kb
max_hw_sectors_kb и max_sectors_kb управляют размером объединённого блока записи: обычно 120KB для USB и 512KB для eMMC в источнике. Пути eMMC:
/sys/block/mmcblk1/queue/max_hw_sectors_kb
/sys/block/mmcblk1/queue/max_sectors_kb
USB Disk:
/sys/block/sda/queue/max_hw_sectors_kb
/sys/block/sda/queue/max_sectors_kb
max_hw_sectors_kb USB-накопителя задаётся здесь:
drivers/usb/storage/scsiglue.c
/*limit the total size of a transfer to 120 KB */
.max_sectors = 240, (单位为block512 bytes)
Параметр настраивается верхним уровнем; пример для RK3399 Type-C1:
/sys/devices/platform/usb@fe900000/fe900000.dwc3/xhci-hcd.9.auto/usb4/4-1/4-1:1.0/host0/target0:0:0/0:0:0:0/max_sectors
Проверьте планировщик I/O:
rk3399:/data# cat /sys/block/mmcblk1/queue/scheduler
noop [cfq] выбирает cfq, что предполагает объединение мелких блоков. Android содержит blktrace, но он может быть отключён. Измените mk, соберите инструмент и скопируйте adb push в /system/bin. Первую строку Android.mk BUILD_BLKTRACE:= false замените на:
BUILD_BLKTRACE:= true
Для blktrace включите CONFIG_BLK_DEV_IO_TRACE в ядре:
Kernel hacking --->
[*]Tracers --->
[*] Support for tracing block IO actions
Пример захвата blktrace:
- Создайте каталог данных.
mkdir /dev/blktrace
- Запустите захват blktrace.
blktrace -d /dev/block/mmcxxx -o /dev/blktrace/blktrace &
/dev/block/mmcxxx — исследуемое устройство, например mmcblk1 на 3399.
- Выполните команду копирования:
busybox dd if=/dev/zero of=/data/test bs=4K count=256K
- Остановите blktrace. После копирования завершите его поток; данные сохранятся в /dev/blktrace. Параметр -w позволяет автоматически остановиться через заданное число секунд. Разбор данных:
blkparse –i /dev/blktrace/ blktrace.blktrace.0 –o /dev/blktrace/blkparse.txt
Статистика источника показывает объединение cfq блоков 4k в 1024 сектора, то есть 512K, перед записью eMMC (рисунок 2-1).

Рисунок 2-1. Данные blktrace. Источник заключает, что объединение блоков 3399 исправно; подробнее — по ссылке анализа I/O blktrace.
Источник повторяет «step5» для анализа ФС. VFAT/EXT4 объединяют блоки в ядре; его NTFS использует FUSE, запись userspace и дополнительное копирование. При запросах 4KB и переменной частоте CPU NTFS может быть медленнее. RK3399 Android cp запрашивает только 4KB, поэтому NTFS USB3 часто медленен в этом окружении.
Факторы оптимизации: скорость USB-накопителя и носителя хоста, USB-контроллер, ФС, размер запроса приложения и частота CPU. Сначала найдите ограничение, затем оптимизируйте.
2.2 Скорость USB Ethernet
Инструмент iperf проверяет качество полосы TCP/UDP, измеряет максимальную полосу TCP, имеет множество параметров и функций UDP, сообщает скорость, джиттер и потери. Сайт https://iperf.fr/ ; загрузка для Windows, Android, Ubuntu, macOS: https://iperf.fr/iperf-download.php . Установка Ubuntu:
sudo apt install iperf
На Android можно установить iperf.apk. Инструкции: https://iperf.fr/iperf-doc.php и http://man.linuxde.net/iperf . Обычно используют UDP для предельной полосы, джиттера и потерь. Начните с теоретической скорости, например -b 100M для канала 100Mbps. Затем повторите с измеренной полосой; джиттер и потери должны уменьшиться. Несколько повторов дают устойчивую реальную скорость.
Пример UDP: сервер Ubuntu PC; RK3399 USB2/USB3 Host соединён с UGREEN USB3 Ethernet, далее кабелем с ПК. Задайте IPv4, маску и шлюз ПК по рисунку 2-2.

Рисунок 2-2. IP-настройка Ubuntu PC. Параметры снимка: способ IPv4 — вручную, адрес 192.168.1.1, маска 255.255.255.0, шлюз 192.168.1.1. Это исходная тестовая конфигурация, а не универсальные настройки сети. Затем выполните:
wlf@wlf-ubuntu:~$ iperf -u -s
------------------------------------------------------------
Server listening on UDP port 5001
Receiving 1470 byte datagrams
UDP buffer size: 208 KByte (default)
------------------------------------------------------------
Клиент 3399: сначала проверьте сведения USB Ethernet.
eth1 Link encap:Ethernet HWaddr 60:38:E0:E3:20:96
inet6 addr: fe80::6238:e0ff:fee3:2096/64 Scope: Link
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:2 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 TX bytes:168
Затем задайте IP:
ifconfig eth1 192.168.1.2 up
Запустите тест полосы:
iperf -u -c 192.168.1.1 -b 1000M -t 60
-b задаёт полосу UDP в bits/sec. Источник рекомендует -b 100M для USB2.0 и -b 1000M для USB3.0. Исходный результат UGREEN USB3.0 Ethernet:
------------------------------------------------------------
Client connecting to 192.168.1.2, UDP port 5001
Sending 1470 byte datagrams
UDP buffer size: 208 KByte (default)
------------------------------------------------------------
[ 3] local 192.168.1.2 port 40116 connected with 192.168.1.1 port 5001
[ ID] Interval Transfer Bandwidth
[ 3] 0.0-60.0 sec 5.61 GBytes 803 Mbits/sec
[ 3] Sent 4096616 datagrams
Тем же методом CISCO USB2.0 Ethernet дал около 95Mbits/sec. Ориентиры источника в обе стороны: USB2.0 Host 95–100Mbits/sec, USB3.0 Host 750–800Mbits/sec. При недостаточной скорости проверьте ошибки ifconfig/tcpdump; при большом числе ошибок измерьте глазковую диаграмму USB.
2.3 Скорость USB Camera
Используйте предпросмотр Camera APK и logcat через UART для текущей частоты кадров:
CameraHal: debugShowFPS(622): Camera 1312 Frames, 30.000 FPS
Отладка UVC: включите trace.
echo 0xffff > /sys/module/uvcvideo/parameters/trace
echo 8 > /proc/sysrq-trigger
Отключите UVC trace:
ehco 0 > /sys/module/uvcvideo/parameters/trace
Проверьте статистику декодирования UVC. Таблица 2-1 содержит максимальные частоты USB Camera из источника.
cat /d/usb/uvcvideo/*/stats
| YUYV формат | MJPEG формат | H264 формат | |
|---|---|---|---|
| USB 2.0 | 640×480 @30fps | 1280×720 @30fps | 1920×1080 @30fps |
| USB 3.0 | 640×480 @60fps | 1280×720 @60fps | 1920×1080 @60fps |
Частоты предполагают одну камеру на контроллер; для двух и более нужны измерения. Большинство камер использует изохронную передачу. Теоретическая полоса USB2.0 по источнику —
23.44MBps, для USB3.0 — 375.04MBps. Предел кадров определяется (a) возможностью камеры и (b) изохронной производительностью хост-драйвера. Проверяйте (a) на ПК. Для (b) рассмотрите повышение приоритета USB QOS, ускорение реакции прерываний, AHB CLK и DMA burst length.
3. Производительность USB Device
3.1 Скорость USB MTP
Подключите устройство к ПК в режиме MTP, вручную скопируйте большой файл, например фильм свыше 1GB, измерьте время и среднюю скорость. Держите устройство на неподвижном рабочем столе без сна. После подключения дождитесь завершения сканирования медиатеки (по logcat).
Тест источника: RK3399 BOX SDK Android N + Kernel4.4. Read — RK3399 → PC, Write — PC → RK3399. 16K/64K/1M — длины буферов MTP Tx/Rx. Частоты больших и малых ядер зафиксированы максимальными. Таблица 3-1: скорости MTP RK3399 BOX SDK.
| Read 16K | Write 16K | Read 64K | Write 64K | Read 1M | Write 1M | |
|---|---|---|---|---|---|---|
| USB 2.0 | 24.7 MBps | 22.8 MBps | 22.8 MBps | 21.5 MBps | 24.7 MBps | 25.6 MBps |
| USB 3.0 | 65.6 MBps | 109.0 MBps | 71.3 MBps | 107.5 MBps | 87.3 MBps | 110.0 MBps |
Тест источника: прототип RK3126C, Android O + Kernel4.4. Таблица 3-2: скорости MTP.
| Read 16K | Write 16K | Read 64K | Write 64K | |
|---|---|---|---|---|
| USB 2.0 | 14.85 MBps | 7.1 MBps | 15.15 MBps | 7.8 MBps |
Анализ и оптимизация:
MTP использует bulk. Источник оценивает USB2.0 примерно в 39MBps (10 транзакций по 512 Bytes за 125мкс), USB3.0 — в 400MBps, но реальная MTP намного медленнее. Фиксированный высокий CPU быстрее переменной частоты; медленный носитель также сильно ограничивает MTP (раздел 2.1). В Kernel4.4 время каждого vfs_read/vfs_write при MTP доступно через интерфейс:
cat /sys/kernel/debug/usb_mtp/status
Сброс статистики:
echo 0 > /sys/kernel/debug/usb_mtp/status
AHB CLK USB2 150MHz и максимальный DMA Burst могут повысить эффективность и скорость. DWC2 передаёт максимум 512KB, DWC3 — 16MB - 1B за раз. Большие MTP Tx/Rx уменьшают прерывания (по умолчанию источника 64KB). Рекомендуются 64KB для USB2 и 1MB для USB3. Параметры Kernel4.4:
/sys/module/usb_f_mtp/parameters/mtp_tx_req_len: длина Tx, байты./sys/module/usb_f_mtp/parameters/mtp_tx_reqs: число Tx-буферов./sys/module/usb_f_mtp/parameters/mtp_rx_req_len: длина Rx, байты.
3.2 Скорость USB MSC
Пример: Linux4.4 RK3399 EVB USB3.0 MSC. Настройте Mass storage как модуль.
<*> USB Gadget Support --->
<M> USB Gadget Drivers
<M> Mass Storage Gadget
Патч ядра:
index f3c7f15..5418d06 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
@@ -404,7 +404,7 @@
compatible = "snps,dwc3";
reg = <0x0 0xfe800000 0x0 0x100000>;
interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH 0>;
- dr_mode = "otg";
+ dr_mode = "peripheral";
phys = <&u2phy0_otg>, <&tcphy0_usb3>;
phy-names = "usb2-phy", "usb3-phy";
phy_type = "utmi_wide";
Соберите ядро, затем модули Mass storage:
make ARCH=arm64 modules SUBDIRS=drivers/usb/gadget
Полученные модули:
libcomposite.ko
usb_f_mass_storage.ko
g_mass_storage.ko
После загрузки создайте lun0.img в data через dd, затем загрузите модули.
insmod libcomposite.ko
insmod usb_f_mass_storage.ko
insmod g_mass_storage.ko file=/data/lun0.img removable=1
Подключите Ubuntu PC, отформатируйте lun0 и обращайтесь к Mass storage с ПК. Цикл проверки чтения:
while true;
do time dd iflag=direct,nonblock if=/media/wlf/4625f014-95f3-419c-96c9-a38f91186eb2/test0 of=/dev/null bs=1024k count=400;
done
Также можно измерить скорость анализатором USB3.0 Agilent (рисунок 3-1).

Рисунок 3-1. Измерение Agilent USB3. Результаты источника: переменная частота RK3399 — чтение 250MBps; малые ядра выключены, большие фиксированы на 1.8 — 300MBps.
3399 关闭⼩核
echo 0 > /sys/devices/system/cpu/cpu0/online
echo 0 > /sys/devices/system/cpu/cpu1/online
echo 0 > /sys/devices/system/cpu/cpu2/online
echo 0 > /sys/devices/system/cpu/cpu3/online
3399 定频⼤核
echo userspace > /sys/devices/system/cpu/cpu4/cpufreq/scaling_governor
echo 1800000 > /sys/devices/system/cpu/cpu4/cpufreq/scaling_setspeed
Источник заключает, что частота CPU заметно влияет на USB MSC: выше частота — выше чтение.
3.3 Скорость USB Gadget Webcam
Инструменты: AMCAP для Windows, guvcview для Ubuntu (sudo apt install guvcview). Оба отображают частоту кадров в реальном времени.
Gadget Webcam требует драйвера UVC gadget в ядре и обработки UVC приложением. В поколении SDK источника Kernel3.10/4.4 поддерживают gadget, но приложение UVC gadget есть только у RV1108; другие платформы могут адаптировать RV1108 либо связанное GitHub-приложение usb gadget uvc driver test application. Kernel3.10 поддерживает Isochronous и Bulk, по умолчанию 1KB за микрокадр 125мкс. Четыре конфигурации дают разные пределы полосы/кадров.
Конфигурация 1 (по умолчанию): изохронно 1KB за 125мкс, максимум 8000KB, то есть 7.8MB в обозначении источника. Таблица 3-3: максимальные кадры RV1108, конфигурация 1.
| YUYV формат | MJPG формат | H264 формат | |
|---|---|---|---|
| USB 2.0 | 648×480 @12fps | 1920×1080 @30fps | 1920×1080 @30fps |
Конфигурация UVC Gadget 2: изохронно 2KB за микрокадр 125мкс. Нужен следующий патч. Повышение полосы может вызвать мерцание; рассмотрите повышение USB QOS, AHB CLK (aclk_peri и hclk_peri) выше 150MHz и другие способы улучшения DMA.
diff --git a/drivers/usb/gadget/f_uvc.c b/drivers/usb/gadget/f_uvc.c
index 382536d..17eac12 100644
--- a/drivers/usb/gadget/f_uvc.c
+++ b/drivers/usb/gadget/f_uvc.c
@@ -37,7 +37,7 @@ static unsigned int streaming_interval = 1;
module_param(streaming_interval, uint, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(streaming_interval, "1 - 16");
-static unsigned int streaming_maxpacket = 1024;
+static unsigned int streaming_maxpacket = 2048;
Максимальная полоса: 16000KB, то есть 15.62MB по источнику. Таблица 3-4: максимальные кадры RV1108, конфигурация 2.
| YUYV формат | MJPG формат | H264 формат | |
|---|---|---|---|
| USB 2.0 | 648×480 @24fps | 1920×1080 @30fps | 1920×1080 @30fps |
Конфигурация UVC Gadget 3:
изохронно 3KB за микрокадр 125мкс. Нужен следующий патч. Повышение полосы может вызвать мерцание; рассмотрите повышение USB QOS, AHB CLK (aclk_peri и hclk_peri) выше 150MHz и другие способы улучшения DMA.
diff --git a/drivers/usb/gadget/f_uvc.c b/drivers/usb/gadget/f_uvc.c
index 382536d..17eac12 100644
--- a/drivers/usb/gadget/f_uvc.c
+++ b/drivers/usb/gadget/f_uvc.c
@@ -37,7 +37,7 @@ static unsigned int streaming_interval = 1;
module_param(streaming_interval, uint, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(streaming_interval, "1 - 16");
-static unsigned int streaming_maxpacket = 1024;
+static unsigned int streaming_maxpacket = 3072;
Максимальная полоса: 24000KB, то есть 23.43MB по источнику. Таблица 3-5: максимальные кадры RV1108, конфигурация 3.
| UYV формат | MJPG формат | H264 формат | |
|---|---|---|---|
| USB 2.0 | 648×480 @30fps | 1920×1080 @30fps | 1920×1080 @30fps |
Конфигурация UVC Gadget 4: Bulk. Примените следующий патч. Этот режим не поддерживает переключение разрешения; источник не рекомендует его при необходимости нескольких разрешений.
diff --git a/drivers/usb/gadget/f_uvc.c b/drivers/usb/gadget/f_uvc.c
index d146ce7..9eb7aad 100644
--- a/drivers/usb/gadget/f_uvc.c
+++ b/drivers/usb/gadget/f_uvc.c
@@ -45,7 +45,7 @@ static unsigned int streaming_maxburst;
module_param(streaming_maxburst, uint, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(streaming_maxburst, "0 - 15 (ss only)");
-static bool bulk_streaming_ep;
+static bool bulk_streaming_ep = true;
module_param(bulk_streaming_ep, bool, S_IRUGO | S_IWUSR);
Максимальная полоса: 35MB по источнику. Таблица 3-6: максимальные кадры RV1108, конфигурация 4.
| UYV формат | MJPG формат | H264 формат | |
|---|---|---|---|
| USB 2.0 | 648×480 > 30fps | 1920×1080 > 30fps | 1920×1080 > 30fps |
3.4 Скорость USB Rndis
Rndis — TCP/IP over USB: TCP/IP на устройстве представляет его сетевым адаптером. Проверка iperf (раздел 2.2). Конфигурация Linux3.10 Android Gadget USB Rndis:
Device Drivers --->
[*] USB support --->
<*> USB Gadget Support --->
<*> USB Gadget Drivers (Android Composite Gadget) --->
Android Composite Gadget
Узлы /sys/class/android_usb/android0/f_rndis настраивают адаптер. Конфигурация Linux3.10 Ethernet Gadget USB Rndis:
Device Drivers --->
[*] USB support --->
<*> USB Gadget Support --->
<*> USB Gadget Drivers (Ethernet Gadget (with CDC Ethernet support)) --->
Ethernet Gadget (with CDC Ethernet support)
Конфигурация Linux4.4 Configfs USB Rndis:
Device Drivers --->
[*] USB support --->
<*> USB Gadget Support --->
<*> USB Gadget Drivers (USB functions configurable through configfs) --->
[*] RNDIS
Пример журнала перечисления Linux3.10 Android Gadget USB Rndis:
shell@android:/ # setprop sys.usb.config rndis
[ 2445.809337] rndis_function_bind_config MAC: 36:C8:78:69:C5:D3
[ 2445.809532] android_usb gadget: using random self ethernet address
[ 2445.809666] android_usb gadget: using random host ethernet address
[ 2445.812255] rndis0: MAC 0a:d4:f2:e3:c5:c7
[ 2445.812330] rndis0: HOST MAC ea:88:5c:93:9d:b5 如连接window,则对应windows以太网卡MAC
[ 2446.208233] DWC_OTG: ********soft connect!!!*****************************************
[ 2446.541253] android_usb gadget: high speed config #1: android
[ 2446.542681] android_work: sent uevent USB_STATE=CONFIGURED
Задайте IP и запустите rndis:
ifconfig rndis0 192.168.1.2 up
Источник требует одной подсети для 192.168.1.2 и ПК, описывая её как 192.168.XX.XX; реальные маски также нужно согласовать. Настройка/тест — раздел 2.2. Совет источника отключить Windows Firewall при проблеме ping сохраняется как исторический совет для изолированного теста, не общая рекомендация безопасности.
Исходные High-speed результаты (Super-Speed не проверен): Linux3.10 Android Gadget — вверх 20Mbps/вниз 40Mbps; Linux3.10 Ethernet Gadget — 100Mbps в обе стороны; Linux4.4 Configfs — 100Mbps в обе стороны. Низкая скорость Android Gadget Kernel3.10 признана проблемой, требующей оптимизации.
3.5 Скорость USB Gadget HID
Инструменты: Windows HidTest.exe, PortHelper1.7.exe либо HID API; Ubuntu hid_gadget_test из Linux3.10 Documentation/usb/gadget_hid.txt либо HID API. Тест источника RK3188 Gadget HID, случай 1: report_length 512 bytes, интервал 1ms, файл 10768KB, high-speed. PC → 3188: 249KBps, 3188 → PC: 125KBps.
Случай 2: report_length 512 bytes, интервал 125us, файл 10768KB, high-speed. PC → 3188: 872KBps; 3188 → PC: 2659KBps. Скорость главным образом зависит от report_length и интервала interrupt. Драйвер drivers/usb/gadget/hid.c источника не содержит HID-дескриптора; его разрабатывают по Documentation/usb/gadget_hid.txt. Пример для report_length 512bytes:
index 79afa82..a05ad79 100644
--- a/drivers/usb/gadget/hid.c
+++ b/drivers/usb/gadget/hid.c
@@ -271,10 +272,93 @@ MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_AUTHOR("Fabien Chouteau, Peter Korsgaard");
MODULE_LICENSE("GPL");
+static struct hidg_func_descriptor rk_hidg_desc = {
+ .subclass = 0, /* No subclass */
+ .protocol = 2, /* Keyboard */
+ .report_length = 512,
+ .report_desc_length = 38,
+ .report_desc = {
+ 0x06, 0x00, 0xFF, /*USAGE_PAGE (Vendor Defined Page 1)*/
+ 0x09, 0x01, /*USAGE (Vendor Usage 1)*/
+ 0xA1, 0x01, /*COLLECTION (Application)*/
+ 0x09, 0x02, /* USAGE (Vendor Usage 2)*/
+ 0x09, 0x03, /*USAGE (Vendor Usage 3)*/
+ 0x15, 0x00, /*LOGICAL_MINIMUM (0)*/
+ 0x26, 0xFF, 0x00, /*LOGICAL_MAXIMUM (255)*/
+ 0x75, 0x10, /*REPORT_SIZE (16)*/
+ 0x96, 0x00, 0x01, /* REPORT_COUNT (256) */
+ 0x81, 0x02, /*INPUT (Data,Var,Abs) */
+ 0x09, 0x04, /*USAGE (Vendor Usage 4)*/
+ 0x15, 0x00, /*LOGICAL_MINIMUM (0) */
+ 0x26, 0xFF, 0x00, /*LOGICAL_MAXIMUM (255) */
+ 0x75, 0x10, /*REPORT_SIZE (16)*/
+ 0x96, 0x00, 0x01, /*REPORT_COUNT (256)*/
+ 0x91, 0x02, /*OUTPUT (Data,Var,Abs) */
+ 0xC0 /*END_COLLECTION*/
+ }
+};
Для report_length 1024bytes измените следующим образом:
@@ -275,7 +275,7 @@ MODULE_LICENSE("GPL");
static struct hidg_func_descriptor rk_hidg_desc = {
.subclass = 0, /* No subclass */
.protocol = 2, /* Keyboard */
- .report_length = 512,
+ .report_length = 1024,
.report_desc_length = 38,
.report_desc = {
0x06, 0x00, 0xFF, /*USAGE_PAGE (Vendor Defined Page 1)*/
@@ -285,13 +285,13 @@ static struct hidg_func_descriptor rk_hidg_desc = {
0x09, 0x03, /*USAGE (Vendor Usage 3)*/
0x15, 0x00, /*LOGICAL_MINIMUM (0)*/
0x26, 0xFF, 0x00, /*LOGICAL_MAXIMUM (255)*/
- 0x75, 0x10, /*REPORT_SIZE (16)*/
+ 0x75, 0x20, /*REPORT_SIZE (32)*/
0x96, 0x00, 0x01, /* REPORT_COUNT (256) */
0x81, 0x02, /*INPUT (Data,Var,Abs) */
0x09, 0x04, /*USAGE (Vendor Usage 4)*/
0x15, 0x00, /*LOGICAL_MINIMUM (0) */
0x26, 0xFF, 0x00, /*LOGICAL_MAXIMUM (255) */
- 0x75, 0x10, /*REPORT_SIZE (16)*/
+ 0x75, 0x20, /*REPORT_SIZE (32)*/
0x96, 0x00, 0x01, /*REPORT_COUNT (256)*/
0x91, 0x02, /*OUTPUT (Data,Var,Abs) */
0xC0 /*END_COLLECTION*/
Интервал HID изменяется через bInterval структур hidg_hs_in_ep_desc и hidg_hs_out_ep_desc в drivers/usb/gadget/f_hid.c. Исходное значение 4 (1ms), минимум 1 (125us).
