Konst 0 24 декабря, 2020 Опубликовано 24 декабря, 2020 · Жалоба Всем привет! Есть задачка - загнать оцифрованный видеопоток на компьютер. В качестве компьютера используется Nvidia Jetson nano, к нему подключена через PCIe x1 карточка с ПЛИС Lattice ECP5. С платой идет несколько примеров: PCIeBasic, PCIeSGDMA и PCIeThruput. Если я правильно понял, ни в одном из этих примеров MSI не задействован, т.е. во всех случаях инициатором обмена является компьютер. Кто-нибудь использовал прерывания на PCIe IP-ядре от Lattice? Есть у кого-нибудь какая-нибудь дополнительная литература, appnotes, примеры, раскрывающие способы использования IP-ядра? Просто не хотелось бы руками писать свою логику поверх нативного интерфейса IP-ядра и по максимуму использовать инфраструктуру примеров (там используется шина Wishbone, и модули, к которым можно обратиться через маппинг BAR'ов, висят на ней). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Konst 0 25 декабря, 2020 Опубликовано 25 декабря, 2020 · Жалоба Так, ну кое-что получилось. Оставлю тут на всякий случай, вдруг пригодится кому-нибудь. Во-первых, при работе с 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, а обработчик будет вызываться тогда, когда данные уютно обустроятся в каком-нибудь буфере, но, похоже, я перепутал мечты с реальностью. В связи с чем новый вопрос - насколько быстро система отвечает на прерывания? Сколько прерываний/с можно отправить на хост? От этого зависит размер буфера, который мне придется держать на ПЛИС. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 25 декабря, 2020 Опубликовано 25 декабря, 2020 · Жалоба Приветствую! 40 minutes ago, Konst said: ... Изначально я наивно полагал, что с помощью MSI мне удастся сразу отправить нужные данные на Jetson, а обработчик будет вызываться тогда, когда данные уютно обустроятся в каком-нибудь буфере, но, похоже, я перепутал мечты с реальностью. В связи с чем новый вопрос - насколько быстро система отвечает на прерывания? Сколько прерываний/с можно отправить на хост? От этого зависит размер буфера, который мне придется держать на ПЛИС. MSI/MSIx прерывания через PCIe это фактически запись со стороны периферийного устройства (FPGA) 32 бит слова по определенному адресу в PC. Генерировать такое прерывание можно хоть каждую 1 us, НО сомневаюсь что ваша OS потянет обработку прерываний с такой частотой. Поэтому предельная частота прерываний определяется софтом. И в обычных системах редко бывает выше 1...10KHz. Для потока данных прерывание обычно генерят по окончании пересылки данных посредством контроллера DMA в FPGA. Поэтому ван надо внимательней посмотреть на пример PCIeSGDMA скорее всего прерывания там генерируются внутри контроллера DMA. Удачи! Rob. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flood 12 27 декабря, 2020 Опубликовано 27 декабря, 2020 · Жалоба 25.12.2020 в 19:02, Konst сказал: Изначально я наивно полагал, что с помощью MSI мне удастся сразу отправить нужные данные на Jetson, а обработчик будет вызываться тогда, когда данные уютно обустроятся в каком-нибудь буфере, но, похоже, я перепутал мечты с реальностью. В связи с чем новый вопрос - насколько быстро система отвечает на прерывания? Сколько прерываний/с можно отправить на хост? От этого зависит размер буфера, который мне придется держать на ПЛИС. Не понимаю, какая связь между количеством прерываний и размером буфера? От количества прерываний зависит время, через которое хост узнает о наличии новых данных. Если у вас идет видеопоток, то скорее всего не имеет смысла делать прерывания чаще, чем на видеокадр (т.е. порядка 60 прерываний в секунду в "стандартном" случае). А вот размер буфера в ПЛИС будет зависеть от latency на шине PCI Express - главным образом, от периодически возникающих затыков на шине, приостанавливающих передачу данных. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Konst 0 27 декабря, 2020 Опубликовано 27 декабря, 2020 · Жалоба 25.12.2020 в 19:43, RobFPGA сказал: Для потока данных прерывание обычно генерят по окончании пересылки данных посредством контроллера DMA в FPGA. Поэтому ван надо внимательней посмотреть на пример PCIeSGDMA скорее всего прерывания там генерируются внутри контроллера DMA. Спасибо за ответ! К сожалению, в примере c DMA прерывания не используются от слова совсем, хост просто все время читает из PCI. Но к примеру мне точно нужно присмотреться, может мне тоже можно будет сделать совсем без прерываний. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Konst 0 27 декабря, 2020 Опубликовано 27 декабря, 2020 · Жалоба 5 часов назад, Flood сказал: Не понимаю, какая связь между количеством прерываний и размером буфера? От количества прерываний зависит время, через которое хост узнает о наличии новых данных. Если у вас идет видеопоток, то скорее всего не имеет смысла делать прерывания чаще, чем на видеокадр (т.е. порядка 60 прерываний в секунду в "стандартном" случае). А вот размер буфера в ПЛИС будет зависеть от latency на шине PCI Express - главным образом, от периодически возникающих затыков на шине, приостанавливающих передачу данных. В том то и дело, что буфера для целого кадра на плате может и не оказаться, но даже если бы он и был, то 60 раз в секунду я могу и сам спросить, есть данные или нет. Какой мне тогда смысл от этих прерываний? На отладочной плате есть, конечно, DDR3, но с ней я не хочу связываться. А видеопоток не сильно мощный - 16 бит яркостного сигнала (целимся в формат пикселя, который в V4L2 в Linux называеся Y16) с разрешением 800х600 или 1600х1200 при 25 к/с. Родной памяти плиска имеет 108 блоков по 1024 18-разрядных слова, т.е. всего 1 990 656 бит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 27 декабря, 2020 Опубликовано 27 декабря, 2020 · Жалоба Приветствую! 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. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flood 12 28 декабря, 2020 Опубликовано 28 декабря, 2020 · Жалоба 17 часов назад, Konst сказал: В том то и дело, что буфера для целого кадра на плате может и не оказаться, но даже если бы он и был, то 60 раз в секунду я могу и сам спросить, есть данные или нет. Какой мне тогда смысл от этих прерываний? На отладочной плате есть, конечно, DDR3, но с ней я не хочу связываться. Причем тут вообще DDR3 на отладочной плате? Возможно, вы не до конца продумали и представляете себе путь движения данных. Нарисуйте потоки, их инициаторы и приемники на схеме - возможно, тогда станет понятнее. Обыкновенно, задачи типа вашей решаются следующим образом: В системе есть периферийное устройство (плата с ПЛИС с интерфейсом видеокамеры или видеовхода и ограниченным размером буферной памяти) и хост-система (материнская плата с центральным процессором и кучей памяти). Тогда: - хост-система выделяет в своей безбрежной памяти набор приемных буферов (не менее двух, лучше трех), размером на видеокадр каждый и настраивает периферийное устройство на прием в эти буфера; - периферийное устройство (ПЛИС) работает в режим bus-master и инициирует передачу данных в память хост-процессора по переданным ему адресам приемного буфера (этот процесс называется DMA); - по окончании заполнения очередного буфера устройство возбуждает прерывание и переходит к приему новых данных в следующий буфер; - центральный процессор по этому прерыванию понимает, что буфер готов, забирает его и дает периферийному устройству следующий буфер. Прерывания нужны, чтобы быстро узнать о готовности буфера, не отвлекаясь на поллинг. Это не обязательно, но довольно удобно при низком темпе поступления данных (а 60 кадров в секунду - это медленно). Существуют более эффективные способы приема данных, чем подтверждения по прерываниям, но для приема видеоданных с частотой 60 Гц они не обязательны. Буфер в самом периферийном устройстве нужен только для того, чтобы накапливать данные от реалтаймового источника во время неизбежно возникающих задержек при передаче данных в память хост-процессора. Почему эти задержки возникают - вопрос совершенно отдельный. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Konst 0 28 декабря, 2020 Опубликовано 28 декабря, 2020 · Жалоба 2 часа назад, Flood сказал: Возможно, вы не до конца продумали и представляете себе путь движения данных. Нарисуйте потоки, их инициаторы и приемники на схеме - возможно, тогда станет понятнее. Не возможно, а совершенно точно. Работу с PCI я не так представлял, но по Вашему возмущению относительно размера буфера из первого поста понял, что где-то не прав Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
toshas 0 31 декабря, 2020 Опубликовано 31 декабря, 2020 · Жалоба Если я правильно помню, ARM не тоже самое что x86 при приеме данных по PCIe шине. Как вы решаете или планируете решить вопрос cache coherency на Jetson NANO ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Konst 0 31 декабря, 2020 Опубликовано 31 декабря, 2020 · Жалоба 16 минут назад, toshas сказал: Как вы решаете или планируете решить вопрос cache coherency на Jetson NANO ? Пока что я читаю 15 главу книжки Linux Device Drivers, параллельно пытаясь понять, что от меня потребуется со стороны платы на Lattice. Но из того, что я прочитал, мне показалось, что эта проблема должна возникать, когда устройство и драйвер расшаривают одну область памяти на двоих и используют ее вместе, т.е. и процессор и драйвер пишут в одну и ту же область. Я же собираюсь, как и советовал Flood, выделить несколько буферов под DMA и циклически менять их местами, т.е. каждрый раз перезаряжать PCI-плату, подсовывая ей новый адрес приемного буфера. А проц будет только читать. В таком случае тоже может возникнуть проблема когеренции? Если так, то должны же быть какие-нибудь механизмы, позволяющие решить этот вопрос, кроме как запросить у ос специальный буфер через dma_alloc_coherent? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gosha-z 2 31 декабря, 2020 Опубликовано 31 декабря, 2020 · Жалоба 8 hours ago, toshas said: Как вы решаете или планируете решить вопрос cache coherency на Jetson NANO ? На Jetson Xavier AGX он решился точно так же - через dma_alloc_coherent Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться