Какие-нибудь встроенные методы Linux для устройств типа AXI-Burst?
Мне нужно общаться с устройством FPGA на основе интерфейса AXI-пакета. Как можно получить доступ к такому устройству через Linux, не используя DMA? Burst является неотъемлемым свойством стандарта AXI, которое обычно должно запускаться автоматически при передаче больших объемов данных. И еще большая проблема заключается в том, что FPGA разработана так, чтобы отвечать только на запросы пакетного типа по шине AXI. Так что это вызывает серьезные проблемы в Linux, когда приложение пытается выполнить последовательное копирование. Я уже пробовала memcpy
и это не работает.
2 ответа
Я предполагаю, что ваше "устройство FPGA" представляет собой пользовательский блок, отображаемый в памяти через интерфейс AXI для Cortex-A9. Я думаю, что есть 2 или 3 способа сделать эту работу.
1) Кэшируемое отображение. Аппаратный интерфейс кеша осуществляет пакетную передачу всей строки кеша за раз. Вам нужно будет вручную очистить (после записи) и сделать недействительным (до чтения).
2) Не кешируемое отображение, и программа на языке ассемблера ARM обрабатывает передачу низкого уровня. Я думаю, что инструкции "Загрузка и сохранение нескольких регистров" могут предоставить то, что вы ищете.
У меня была похожая проблема, когда к периферийному устройству AXI (пользовательскому контроллеру памяти) требовался доступ с 8-байтовыми передачами от процессора Cortex-A9. Обычные инструкции ARM, конечно, передают 1, 2 или 4 байта (байт, полуслово, слово). Те работали через кэшируемое отображение, но не через не кэшируемое отображение. LDM / STM, 2 слова за раз, работали с обоими отображениями.
Конечно, режимы передачи AHB/AXI зависят от реализации. Согласно вашему описанию, вам нужны режимы INCR или WRAP, а не SINGLE. Но так не должно быть. Это поднимает третий способ, которым вы могли бы сделать эту работу:
3) Поговорите с вашим разработчиком цифрового оборудования, сообщите ему о влиянии программного обеспечения на его реализацию.
На мой взгляд, вам не нужно выполнять необычные / нестандартные низкоуровневые операции MMU. В Linux есть высокоуровневые методы, вы бы поместили стандартные хуки в драйвер вашего устройства и / или board.c, основной вариант - идти без кэширования (т. Е. COHERENT). Обратитесь к LDD3.
Вам нужно настроить MMU для информирования аппаратного обеспечения о возможностях вашего компонента. Вам также необходимо убедиться, что все межсоединение поддерживает пакетные передачи и не выполняет никаких преобразований (что может произойти, если при создании межсоединения возникает неопределенность в отношении возможностей вашего компонента).
Чтобы установить MMU, вы выполняете вызов следующим образом:
/* shareable device: S=b0 TEX=b000 AP=b11, C=b0, B=b1 = 0xC06*/
Xil_SetTlbAttributes(COMPONENT_BASE_ADDRESS, 0xC06);
атрибуты определяются следующим образом (из Технического справочного руководства Zynq):
Encoding Bits Cache Attribute
C B
0 0 Non-cacheable
0 1 Write-back, write-allocate
1 0 Write-through, no write-allocate
1 1 Write-back, no write-allocate
Таким образом, приведенная выше строка задает регион для обратной записи, для выделения записи, что может дать вам пакетный доступ при записи.
Смотрите также Xilinx AR#47406 и это сообщение на форуме.