Перейти к содержанию
    

Lattice ECP5 и PCIe MSI

Всем привет!

Есть задачка - загнать оцифрованный видеопоток на компьютер. В качестве компьютера используется Nvidia Jetson nano,  к нему подключена через PCIe x1 карточка с ПЛИС Lattice ECP5. С платой идет несколько примеров: PCIeBasic, PCIeSGDMA и PCIeThruput. Если я правильно понял, ни в одном из этих примеров MSI не задействован, т.е. во всех случаях инициатором обмена является компьютер. Кто-нибудь использовал прерывания на PCIe IP-ядре от Lattice? Есть у кого-нибудь какая-нибудь дополнительная литература, appnotes, примеры, раскрывающие способы использования IP-ядра? Просто не хотелось бы руками писать свою логику поверх нативного интерфейса IP-ядра и по максимуму использовать инфраструктуру примеров (там используется шина Wishbone, и модули, к которым можно обратиться через маппинг BAR'ов, висят на ней).

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так, ну кое-что получилось. Оставлю тут на всякий случай, вдруг пригодится кому-нибудь.

Во-первых, при работе с PCI на Jetson Nano выяснилась интересная особенность - по умолчанию Lattice генерирует ядро, в котором Class Code устройства равен 0x000000. Линух на Jetson как-то странно воспринимает этот код и, не смотря на то, что молча выполняет mmap на BAR'ы, читает всегда 0xFF и ничего не записывает, а попытка в драйвере вызвать pci_enable_device заканчивается кодом 22. Если посмотреть таблицу, то код 0x00000 будет соответствовать Unclassified Non-VGA-Compatible device. Если заменить Class Code на 0xFF (Unassigned Class), то драйвер благополучно прописывается в системе.

Во-вторых, на форуме Nvidia нашлась информация (впрочем то сообщение было довольно древним, а сам пока не проверял), что Nvidia Jetson поддерживает только одно прерывание MSI на устройство, а если нужно больше то, пожалуйста, используйте MSI-x.

Теперь по поводу прерываний MSI. 

В одном из примеров (PCIeSGMA) и в ответном для него приложении (написано под винду, исходники поставляются с примером), нашелся тест для прерываний. По нему стало понятно в какие регистры что записывать, чтобы заставить плату поднять линию MSI[0], которая и порождает прерывание. Это прерывание благополучно доставляется до драйвера, о чем сообщает печать в dmesg.

Изначально я наивно полагал, что с помощью MSI мне удастся сразу отправить нужные данные на Jetson, а обработчик будет вызываться тогда, когда данные уютно обустроятся в каком-нибудь буфере, но, похоже, я перепутал мечты с реальностью. В связи с чем новый вопрос - насколько быстро система отвечает на прерывания? Сколько прерываний/с можно отправить на хост? От этого зависит размер буфера, который мне придется держать на ПЛИС.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую!

40 minutes ago, Konst said:

...

Изначально я наивно полагал, что с помощью MSI мне удастся сразу отправить нужные данные на Jetson, а обработчик будет вызываться тогда, когда данные уютно обустроятся в каком-нибудь буфере, но, похоже, я перепутал мечты с реальностью. В связи с чем новый вопрос - насколько быстро система отвечает на прерывания? Сколько прерываний/с можно отправить на хост? От этого зависит размер буфера, который мне придется держать на ПЛИС.

MSI/MSIx прерывания через PCIe это фактически  запись  со стороны  периферийного устройства (FPGA) 32 бит слова по  определенному адресу в PC. Генерировать  такое прерывание можно хоть каждую 1 us, НО сомневаюсь  что ваша OS  потянет обработку прерываний с такой частотой.  Поэтому предельная  частота прерываний определяется  софтом. И в обычных  системах редко бывает выше 1...10KHz. 

Для потока данных прерывание  обычно генерят по окончании пересылки данных посредством контроллера DMA в FPGA.  Поэтому  ван надо внимательней посмотреть на пример  PCIeSGDMA  скорее всего прерывания там генерируются  внутри контроллера DMA.

 

Удачи! Rob.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

25.12.2020 в 19:02, Konst сказал:

Изначально я наивно полагал, что с помощью MSI мне удастся сразу отправить нужные данные на Jetson, а обработчик будет вызываться тогда, когда данные уютно обустроятся в каком-нибудь буфере, но, похоже, я перепутал мечты с реальностью. В связи с чем новый вопрос - насколько быстро система отвечает на прерывания? Сколько прерываний/с можно отправить на хост? От этого зависит размер буфера, который мне придется держать на ПЛИС.

Не понимаю, какая связь между количеством прерываний и размером буфера? От количества прерываний зависит время, через которое хост узнает о наличии новых данных. Если у вас идет видеопоток, то скорее всего не имеет смысла делать прерывания чаще, чем на видеокадр (т.е. порядка 60 прерываний в секунду в "стандартном" случае).

 

А вот размер буфера в ПЛИС будет зависеть от latency на шине PCI Express - главным образом, от периодически возникающих затыков на шине, приостанавливающих передачу данных. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

25.12.2020 в 19:43, RobFPGA сказал:

Для потока данных прерывание  обычно генерят по окончании пересылки данных посредством контроллера DMA в FPGA.  Поэтому  ван надо внимательней посмотреть на пример  PCIeSGDMA  скорее всего прерывания там генерируются  внутри контроллера DMA.

Спасибо за ответ!

К сожалению, в примере c DMA прерывания не используются от слова совсем, хост просто все время читает из PCI. Но к примеру мне точно нужно присмотреться, может мне тоже можно будет сделать совсем без прерываний.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

5 часов назад, Flood сказал:

Не понимаю, какая связь между количеством прерываний и размером буфера? От количества прерываний зависит время, через которое хост узнает о наличии новых данных. Если у вас идет видеопоток, то скорее всего не имеет смысла делать прерывания чаще, чем на видеокадр (т.е. порядка 60 прерываний в секунду в "стандартном" случае).

 

А вот размер буфера в ПЛИС будет зависеть от latency на шине PCI Express - главным образом, от периодически возникающих затыков на шине, приостанавливающих передачу данных. 

В том то и дело, что буфера для целого кадра на плате может и не оказаться, но даже если бы он и был, то 60 раз в секунду я могу и сам спросить, есть данные или нет. Какой мне тогда смысл от этих прерываний? На отладочной плате есть, конечно, DDR3, но с ней я не хочу связываться.

А видеопоток не сильно мощный - 16 бит яркостного сигнала (целимся в формат пикселя, который в V4L2 в Linux называеся Y16) с разрешением 800х600 или 1600х1200 при 25 к/с. Родной памяти плиска имеет 108 блоков по 1024 18-разрядных слова, т.е. всего  1 990 656 бит.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую!

17 minutes ago, Konst said:

В том то и дело, что буфера для целого кадра на плате может и не оказаться, но даже если бы он и был, то 60 раз в секунду я могу и сам спросить, есть данные или нет. Какой мне тогда смысл от этих прерываний? На отладочной плате есть, конечно, DDR3, но с ней я не хочу связываться.

А видеопоток не сильно мощный - 16 бит яркостного сигнала (целимся в формат пикселя, который в V4L2 в Linux называеся Y16) с разрешением 800х600 или 1600х1200 при 25 к/с. Родной памяти плиска имеет 108 блоков по 1024 18-разрядных слова, т.е. всего  1 990 656 бит.

Ну вот берите и считайте  - 16 бит  800х600х25  получается ~24 MB/s. Для  1600x1200 все в 4 раза хуже - ~96 MB/s.  Программным  чтением через CPU вы такой поток не вытащите, даже с большими буферами и частыми прерываниями.  Так что без DMA вам никак. 

А  когда DMA есть то буфера в FPGA нужны (как и говорили выше) небольшие - лишь для сглаживания пиковых провалов на шине PCIe и задержек при пере-инициализации DMA. Ну и прерывания если и нужны  будут то только для этого, что как раз можно совместить с размером кадра. 

 

Удачи! Rob.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

17 часов назад, Konst сказал:

В том то и дело, что буфера для целого кадра на плате может и не оказаться, но даже если бы он и был, то 60 раз в секунду я могу и сам спросить, есть данные или нет. Какой мне тогда смысл от этих прерываний? На отладочной плате есть, конечно, DDR3, но с ней я не хочу связываться.

Причем тут вообще DDR3 на отладочной плате? Возможно, вы не до конца продумали и представляете себе путь движения данных. Нарисуйте потоки, их инициаторы и приемники на схеме - возможно, тогда станет понятнее.

 

Обыкновенно, задачи типа вашей решаются следующим образом:

В системе есть периферийное устройство (плата с ПЛИС с интерфейсом видеокамеры или видеовхода и ограниченным размером буферной памяти) и хост-система (материнская плата с центральным процессором и кучей памяти). Тогда:

- хост-система выделяет в своей безбрежной памяти набор приемных буферов (не менее двух, лучше трех), размером на видеокадр каждый и настраивает периферийное устройство на прием в эти буфера;

- периферийное устройство (ПЛИС) работает в режим bus-master и инициирует передачу данных в память хост-процессора по переданным ему адресам приемного буфера (этот процесс называется DMA);

- по окончании заполнения очередного буфера устройство возбуждает прерывание и переходит к приему новых данных в следующий буфер;

- центральный процессор по этому прерыванию понимает, что буфер готов, забирает его и дает периферийному устройству следующий буфер.

Прерывания нужны, чтобы быстро узнать о готовности буфера, не отвлекаясь на поллинг. Это не обязательно, но довольно удобно при низком темпе поступления данных (а 60 кадров в секунду - это медленно). Существуют более эффективные способы приема данных, чем подтверждения по прерываниям, но для приема видеоданных с частотой 60 Гц они не обязательны.

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, Flood сказал:

Возможно, вы не до конца продумали и представляете себе путь движения данных. Нарисуйте потоки, их инициаторы и приемники на схеме - возможно, тогда станет понятнее.

Не возможно, а совершенно точно:biggrin:. Работу с PCI я не так представлял, но по Вашему возмущению относительно размера буфера из первого поста понял, что где-то не прав:biggrin:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если я правильно помню, ARM не тоже самое что x86 при приеме данных по PCIe шине.

Как вы решаете или планируете решить вопрос cache coherency на Jetson NANO ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

16 минут назад, toshas сказал:

Как вы решаете или планируете решить вопрос cache coherency на Jetson NANO ?

Пока что я читаю 15 главу книжки Linux Device Drivers, параллельно пытаясь понять, что от меня потребуется со стороны платы на Lattice. 

Но из того, что я прочитал, мне показалось, что эта проблема должна возникать, когда устройство и драйвер расшаривают одну область памяти на двоих и используют ее вместе, т.е. и процессор и драйвер пишут в одну и ту же область. Я же собираюсь, как и советовал Flood, выделить несколько буферов под DMA и циклически менять их местами, т.е. каждрый раз перезаряжать PCI-плату, подсовывая ей новый адрес приемного буфера. А проц будет только читать. В таком случае тоже может возникнуть проблема когеренции? Если так, то должны же быть какие-нибудь механизмы, позволяющие решить этот вопрос, кроме как запросить у ос специальный буфер через dma_alloc_coherent?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

8 hours ago, toshas said:

Как вы решаете или планируете решить вопрос cache coherency на Jetson NANO ?

На Jetson Xavier AGX он решился точно так же - через dma_alloc_coherent

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...