какие устройства используют dma

DMA — технология прямого доступа к памяти

Термин DMA наверняка не раз встречался читателям в различных компьютерных статьях. Что же он означает, влияет ли это понятие на работу компьютера, и если да, то как? В этом мы и попытаемся разобраться.

какие устройства используют dma. Смотреть фото какие устройства используют dma. Смотреть картинку какие устройства используют dma. Картинка про какие устройства используют dma. Фото какие устройства используют dma

Принцип работы

Большинство устройств ПК нуждаются в периодическом обмене данными не только с центральным процессором (ЦП), но и с оперативной памятью. В первых вариантах персональных компьютеров процесс обмена данными какого-либо устройства с ОЗУ протекал при помощи процессора. Такой метод получил название PIO (Programmable Input-Output, программируемый ввод-вывод). Однако этот метод имел ряд недостатков. Прежде всего, было очевидно, что поскольку процессор загружен множеством задач, то он не всегда может отвлекаться на то, чтобы управлять процессом чтения и записи данных ОЗУ, тем более, что объем этих данных в результате прогресса компьютерной техники все увеличивался и увеличивался.

Так появилась идея технологии DMA (сокращение от Direct Memory Access, т.е. Прямой Доступ к Памяти), состоящая в том, чтобы позволить различным устройствам обращаться к оперативной памяти напрямую, минуя ЦП. Также часто используется русская аббревиатура данной технологии – ПДП.

Первоначально практическая реализация этой технологии (в материнских платах на основе шины ISA) была осуществлена при помощи встроенного в материнскую плату контроллера ПДП, который был призван управлять процессом обмена данными между устройством и ОЗУ. При этом процессор также не был полностью исключен из этого процесса. Прежде всего, механизм ПДП инициализировался самим процессором, однако в ход процесса передачи данных он не вмешивался, занимаясь в это время другими задачами. После того, как обмен информацией между устройством и ОЗУ завершался, то процессор получал соответствующее прерывание, которое отсылал ему контроллера DMA.

В шине ISA также использовались специальные каналы ПДП, которые часто закреплялись за отдельным устройством:

Обычно данные каналы можно было устанавливать программным путем, но на некоторых старых устройствах, например, картах расширения для подключения накопителей CD-ROM, необходимо было вручную устанавливать значения нужных каналов при помощи перемычек.

Современная реализация

Начиная с появления шины ввода-вывода PCI, концепция практической реализации ПДП претерпела изменения. В материнских платах с шиной PCI больше не использовался контроллер DMA, а вместо этого стала применяться технология Bus Mastering. Суть этой технологии заключается в том, что любое устройство может обратиться к шине и полностью использовать ее в своих целях, в том числе, и для доступа к оперативной памяти. Кроме того, в шине PCI отпала необходимость в использовании каналов доступа к памяти. Подобный механизм используется также и в преемниках шины PCI –сверхбыстрых шинах AGP и PCI-Express.

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

Современные операционные системы, такие как MS Windows, умеют управлять режимом ПДП для многих устройств. В частности, пользователь имеет возможность включить или выключить режим DMA для жестких дисков.

В жестких дисках с интерфейсом IDE технология ПДП получила свое развитие в виде дополнительных режимов ПДП, получивших название Ultra DMA (UDMA). Всего стандарт Ultra DMA поддерживает 8 основных режимов передачи данных, обеспечивающих скорость от 16,7 до 167 МБ/c. Использование режимов Ultra DMA для винчестеров позволило значительно увеличить пропускную способность шины IDE. Включить или изменить режим Ultra DMA для жестких дисков можно при помощи специальной опции BIOS, обычно носящей название DMA (UDMA) Mode.

Заключение

Появление технологии ПДП позволило разгрузить процессор и избавить его от большого объема рутинной работы по пересылке данных между оперативной памятью и устройствами, расположенными на материнской плате или подключенными к ней. Особенно важно использование разновидности технологии ПДП – Ultra DMA в винчестерах на основе интерфейса IDE, что позволяет значительно ускорить обмен данными между накопителем IDE и материнской платой.

Источник

DMA для новичков или то, что вам нужно знать

Всем привет, сегодня мы с вами поговорим о DMA: именно о той технологии, которая помогает вашему компьютеру воспроизводить для вас музыку, выводить изображение на экран, записывать информацию на жесткий диск, и при этом оказывать на центральный процессор просто мизерную нагрузку.

DMA, что это? О чем вы говорите?

DMA, или Direct Memory Access – технология прямого доступа к памяти, минуя центральный процессор. В эпоху 486-ых и первых Pentium во всю царствовала шина ISA, а также метод обмена данными между устройствами – PIO (Programmed Input/Output).

Когда объемы данных, которыми оперирует процессор начали возрастать, стало понятно, что нужно минимизировать участие процессора в цепочке обмена данными, а то прийдется туго. И вот тогда активное применение нашла технология прямого доступа к памяти.

Кстати говоря, DMA используется не только для обмена данными между устройством и ОЗУ, но также между устройствами в системе, возможен DMA трансфер между двумя участками ОЗУ (хотя данный маневр не применим к x86 архитектуре). Также в своем процессоре Cell, IBM использует DMA как основной механизм обмена данными между синергетическими процессорными элементами (SPE) и центральным процессорным элементом (PPE). Также каждый SPE и PPE может обмениватся данными через DMA с оперативной памятью. Данный прием – на самом деле большое преимущество Cell, ибо избавляет от проблем когерентности кешей при мультипроцессорной обработке данных.

И снова теория

Прежде чем мы перейдем к практике, я бы хотел осветить несколько важных аспектов программирования PCI, PCI-E устройств.

Я вскользь упомянул о регистрах устройства, но как же к ним имеет доступ центральный процессор? Как многие из вас знают, есть такая сущность в компьютерных технологиях, как IO порты (Input/Output ports). Они предназначены для обмена информацией между центральным процессором и периферийными устройствами, а доступ к ним возможен с помощью специальных ассемблерных инструкций — in/out. BIOS (или OpenFirmware на PPC based системах) на ранних этапах инициализации PCI устройств, а также некоторых других (Super IO контроллера, контроллера PS/2 устройств, ACPI timer и т.д.), закрепляет за определенным контроллером собственный диапазон IO портов, куда и отображаются регистры устройства.

Итак, существует два метода утилизации DMA: contiguous DMA и scatter/gather DMA.

Contiguous DMA

Scatter/gather DMA

С ростом скорости Ethernet адаптеров, contiguous DMA показал свою несостоятельность. В основном из-за того, что требовались области памяти достаточно большого размера, которые подчас невозможно было выделить, так как в современных системах фрагментация физической памяти достаточно высока. Во всем виноват механизм виртуальной памяти, без которого нынче никуда 🙂

Решение напрашивается само собой: использовать вместо одного большого участка памяти несколько, но в разных регионах этой самой памяти. Возникает вопрос, но как же сообщить контроллеру устройства, как инициировать DMA трансфер и по какому адресу писать данные? И тут нашли решение, использовать дескрипторы, чтобы описывать каждый вот такой участок в оперативной памяти.

На сегодня пожалуй все, иначе информации станет слишком много. В следующей статье я покажу вам, как с этой уличной магией работает IOKit. Жду отзывов и дополнений 😉

Источник

DMA вообще и в частности

Знал бы где упадешь, соломки подстелил бы

О существовании DMA (Direct Memory Access) — русскоязычное ПДП (Прямой Доступ к Памяти) многие разработчики встроенных устройств слышали, но вот применяют его гораздо реже, чем он (ПДП) этого заслуживает. Кстати, я буду упоминать именно эту аббревиатуру, но не потому, что я такой упрямый патриот и противник англоязычных заимствований, а всего лишь от того, что мне лень лишний раз переключать раскладку клавиатуры.

Основных причин недостаточного использования ПДП в программах для МК три: 1) относительная сложность данного устройства, которая вместе с 2) непониманием выгод его применения приводит к нежеланию данное устройство изучать и осваивать (как говорят в таких случаях, старшая сестра не велит — для тех, кто в танке — это про лень, котороая раньше нас родилась), отягощенному 3) отсутствием хороших и понятных примеров применения ПДП в поставляемых с МК руководствами. И если первые две причины носят явно субъективный характер, то третья несомненно объективна и внутри меня просыпается параноик и настойчиво утверждает, что это сделано специально с целью не допустить отечественных разработчиков МК на продвинутые уровни, где-то выше 60 (то, что при этом страдают и остальные разработчики по всему миру, параноиком игнорируется, поскольку либо 1) за пределами России распространяются правильные примеры, либо 2) ради великой цели не допустить вставания, сами понимаете кого, с колен буржуины готовы пойти на любые жертвы).

Тем не менее без шуток, действительно, в примерах в лучшем случае лежит модуль настройки отдельно взятого канала ПДП, а увязанную систему с ПДП драйвером Вы в примерах применений не найдете (даже в CMSIS не найдете, ну тут действительно есть объективная причина — напишу пост про него — упомяну). Почему так на самом деле — я не знаю, но разработчикам кристаллов виднее, единственное разумное обоснование, которое мне приходит в голову — это то, что ПДП довольно таки специфичны, поэтому «нельзя просто так взять и » перенести код из другого источника, а ввиду малой востребованности ПДП в реальных разработках отсутствие таких примеров не считается существенным недостатком. Восполнить указанный мной пробел в знаниях и предназначен настоящий пост (нескромное заявление, но если сам себя не похвалишь, весь день ходишь как оплеванный), поэтому те, кого я заинтриговал, могут нажать на кнопочку.

Тем не менее, должен предостеречь нетерпеливого читателя, что он не найдет тут серебряной пули, которую можно смело включать в свои разработки, а всего лишь (но и это немало) обнаружит некоторые мысли и подходы, которые облегчат ему построение своих собственных систем на МК с применением ПДП. То есть я поставлю флажки в тех местах, где точно лежат грабли, но не гарантирую, что непомеченных граблей не останется, что, впрочем, не мешает Вам повыкидывать флажки на фиг и пройтись по граблям самостоятельно. Вообще, те, кто читал мои посты, наверняка обратили внимание, что я делаю упор не на то, ЧТО следует сделать и КАК именно, а на то, ПОЧЕМУ я рекомендую сделать именно так.

Итак, ПДП — это часть аппаратуры МК, которая позволяет производить пересылку данных между различными составными частями данного МК (и системы с его участием) без привлечения ресурсов процессора (точнее говоря, с минимальным привлечением, поскольку делать что либо в МК системе вообще БЕЗ участия процессора — мысль смелая и далеко заводящая).

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

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

Встречалась картина (например в ДВК), когда одно ВУ работало по ПДП, а второе — по прерываниям или даже в цикле опроса (драйвер MX, если кто помнит). Когда появились первые МК, в которых память интегрирована в чип, создание внешних по отношению к кристаллу устройств с ПДП стало весьма нетривиальной задачей и, естественно, ПДП перекочевало внутрь МК и стало частью его архитектуры. Этот процесс не имел линейного поступательного характера и можно встретить как МК на основе 51й архитектуры с поддержкой ПДП, так и МК на основе Cortex-M3 с богатым набором периферии, но без поддержки ПДП (например, Stellaris). Тем не менее, в бОльшей части современных МК на основе ARM ПДП присутствует и можем перейти к их изучению и для начала остановиться на рассмотрению их особенностей.

Как было сказано выше, основное назначение ПДП — передача данных между разными устройствами с минимальным привлечением процессора. Как правило, одним из этих устройств является основная память МК, хотя иногда возможны как передачи между двумя внешними устройствами, так из памяти в память. Некоторые ПДП поддерживают такие возможности, некоторые нет, и это следует учитывать при выборе МК.

Следующей особенностью можно считать механизм обслуживания запросов в одном канале. Остановимся на этом моменте поподробнее и разберем в общих чертах работу одного запроса одного канала ПДП.

Для того, чтобы совершить передачу, нам следует сообщить ПДП о своих намерениях, то есть откуда мы хотим передавать данные, куда их следует направить, сколько именно данных следует передать, режимы передачи (об этом чуть позже), и, возможно, служебная информация. Поместить данную информацию мы можем либо в регистры, ответственные за работу ПДП (устаревший способ и дальше мы поймем, почему) либо в оперативную память системы, причем в последнем случае это должна быть либо специальная выделенная область памяти, чтобы ПДП знал, откуда надо взять информацию, либо в какой то регистр ПДП должна быть помещена информация о том, где именно в оперативной памяти лежат данные (говоря привычным языком, мы должны поместить ссылку). Именно последний метод и используется, поскольку он имеет следующие преимущества: оперативная память МК — ценный ресурс и сегментировать ее на детерминированные блоки не есть хорошая практика.

На практике встречаются разнообразные комбинированные схемы, в основном с целью экономии аппаратуры МК — указатель на область памяти, в которой размещаются 2 или более БУП, циклически переключающиеся по мере исполнения, указатель на следующий БУП в служебном поле текущего БУП, иерархический доступ, когда БУП содержит указания на последовательность БУП, которые собственно и выполняются и так далее.

Теперь перейдем от рассмотрения ПДП вообще к рассмотрению конкретной реализации, а именно к МК фирмы «Миландр» 1986ВЕ1Т.

Почему именно к нему? Ну, во-первых, я с ним работаю, во-вторых, у него достаточно богатый по возможностям ПДП, а в-третьих, у него богато фич (это не баг это фича такая — да да именно из этого разряда), которые делают работу с МК увлекательным занятием, после которого работа с аналогами от известных производителей покажется легкой и простой.

Сначала о хорошем — ПДП поддерживает 32 независимых канала доступа — по одному на каждое внешнее устройство в составе МК и еще один для пересылок память-память. Кроме того, как вы уже поняли из предыдущего предложения, ПДП поддерживает все возможные режимы пересылки, а именно: регистры ВУ-память, регистры ВУ-регистры ВУ, память-память, и если вам кажется, что так и должно быть, то это совсем не так, и разные режимы функционируют слегка по-разному и не везде реализованы.

Далее, ПДП поддерживает разные форматы данных: 1 байт, 2 байта и 4 байта (слово в нашей архитектуре), а также разные виды инкремента адреса отдельно источника и приемника: на 1, на 2 и на 4 (декремент не поддерживается). ПДП имеет систему арбитража обслуживаемых каналов с возможностью назначения гибких приоритетов для каждого канала и настраиваемого размера элементарной транзакции (количества передач одного канала, по выполнению которых производится арбитраж). Кроме того, каждый канал может иметь до 2 БУП, которые могут сменяться по циклической системе, либо работать в иерархическом режиме, вместе с тем возможен и однократный режим.

Чтобы соблюсти баланс, скажем и о менее хорошем. Опять про документацию — если Вы на знаете, как работает ПДП, то из документации фирмы вы об этом точно не узнаете. Документация явно переводная, есть и ошибки перевода, которые сильно искажают смысл, есть и весьма невнятно описанные места, но в целом для подготовленного разработчика ее может и хватить, если вы привыкли домысливать за автора. Из более существенных недостатков (конечно по сравнению с идеальным устройством) — значительные затраты ресурса шины (6 доступов на 1 пересылку, хотя может я чего-то недопонял) и еще ряд фич, о которых чуть позже.

ЗАСАДА №1 от разработчиков — прерывание от окончания передачи не проявляются в внешних устройствах. То есть у нас есть один вектор прерывания по окончанию транзакции от любого из запрограммированных каналов. Более того, нет никакого регистра, в котором хранился бы номер канала, завершившего транзакцию, либо хотя бы битовый регистр с флагами. То есть единственный способ определить номер завершившего передачу канала — перебирать все каналы и смотреть соответствующие поля TCB, и это нам придется делать в обработчике прерывания, который должен занимать минимальное время. Напрашивающееся решение — перенести поиск канала в нижнюю половину драйвера обработки не проходит, поскольку нас ожидает:

ЗАСАДА № 2 от разработчиков — прерывание является потенциальным и прекратить работу верхней половниы, не сбросив его явным образом, мы не можем. Более того, есть еще и

ЗАСАДА № 3 от них же — мы не можем сбросить прерывание путем манипуляции реистрами ПДП, а должны проводить сброс разрешения выработки запросов в регистрах внешнего устройства. Да да, именно так, драйвер ПДП должен что то знать о составе регистров обслуживаемых устройств, более чудовищного нарущения принципа инкапсуляции (а он справедлив и для проектирования аппаратуры) трудно себе представить. Я не знаю, что курили разработчики ПДП, но, как написано у Гайдука, «что то очень интересное». То есть, вы можете не верить, но если мы запретим прохождение запросов соостветствующего канала и запретим его обработку, то прерывание мы все равно НЕ СБРОСИМ.
Что-то получилось больше букв, чем было запланировано, поэтому оставим читателей размышлять о сложной ситуации, в которой оказался главный герой истории, что особенно актуально в пятницу вечером, а сам напишу Продолжение следует…

Источник

DMA для новичков или то, что вам нужно знать

Всем привет, сегодня мы с вами поговорим о DMA: именно о той технологии, которая помогает вашему компьютеру воспроизводить для вас музыку, выводить изображение на экран, записывать информацию на жесткий диск, и при этом оказывать на центральный процессор просто мизерную нагрузку.

DMA, что это? О чем вы говорите?

DMA, или Direct Memory Access – технология прямого доступа к памяти, минуя центральный процессор. В эпоху 486-ых и первых Pentium во всю царствовала шина ISA, а также метод обмена данными между устройствами – PIO (Programmed Input/Output).

Когда объемы данных, которыми оперирует процессор начали возрастать, стало понятно, что нужно минимизировать участие процессора в цепочке обмена данными, а то прийдется туго. И вот тогда активное применение нашла технология прямого доступа к памяти.

Кстати говоря, DMA используется не только для обмена данными между устройством и ОЗУ, но также между устройствами в системе, возможен DMA трансфер между двумя участками ОЗУ (хотя данный маневр не применим к x86 архитектуре). Также в своем процессоре Cell, IBM использует DMA как основной механизм обмена данными между синергетическими процессорными элементами (SPE) и центральным процессорным элементом (PPE). Также каждый SPE и PPE может обмениватся данными через DMA с оперативной памятью. Данный прием – на самом деле большое преимущество Cell, ибо избавляет от проблем когерентности кешей при мультипроцессорной обработке данных.

И снова теория

Прежде чем мы перейдем к практике, я бы хотел осветить несколько важных аспектов программирования PCI, PCI-E устройств.

Я вскользь упомянул о регистрах устройства, но как же к ним имеет доступ центральный процессор? Как многие из вас знают, есть такая сущность в компьютерных технологиях, как IO порты (Input/Output ports). Они предназначены для обмена информацией между центральным процессором и периферийными устройствами, а доступ к ним возможен с помощью специальных ассемблерных инструкций — in/out. BIOS (или OpenFirmware на PPC based системах) на ранних этапах инициализации PCI устройств, а также некоторых других (Super IO контроллера, контроллера PS/2 устройств, ACPI timer и т.д.), закрепляет за определенным контроллером собственный диапазон IO портов, куда и отображаются регистры устройства.

Итак, существует два метода утилизации DMA: contiguous DMA и scatter/gather DMA.

Contiguous DMA

Scatter/gather DMA

С ростом скорости Ethernet адаптеров, contiguous DMA показал свою несостоятельность. В основном из-за того, что требовались области памяти достаточно большого размера, которые подчас невозможно было выделить, так как в современных системах фрагментация физической памяти достаточно высока. Во всем виноват механизм виртуальной памяти, без которого нынче никуда 🙂

Решение напрашивается само собой: использовать вместо одного большого участка памяти несколько, но в разных регионах этой самой памяти. Возникает вопрос, но как же сообщить контроллеру устройства, как инициировать DMA трансфер и по какому адресу писать данные? И тут нашли решение, использовать дескрипторы, чтобы описывать каждый вот такой участок в оперативной памяти.

На сегодня пожалуй все, иначе информации станет слишком много. В следующей статье я покажу вам, как с этой уличной магией работает IOKit. Жду отзывов и дополнений 😉

Источник

DMA: мифы и реальность

какие устройства используют dma. Смотреть фото какие устройства используют dma. Смотреть картинку какие устройства используют dma. Картинка про какие устройства используют dma. Фото какие устройства используют dma

Введение

В прошлой статье («Часть 2: Использование блоков UDB контроллеров PSoC фирмы Cypress для уменьшения числа прерываний в 3D-принтере») я отметил один очень интересный факт: если автомат в UDB изымал данные из FIFO слишком быстро, он успевал заметить состояние, что новых данных в FIFO нет, после чего переходил в ложное состояние Idle. Разумеется, меня заинтересовал этот факт. Вскрывшиеся результаты я показал группе знакомых. Один человек ответил, что это всё вполне очевидно, и даже назвал причины. Остальные были удивлены не менее, чем я в начале исследований. Так что некоторые специалисты не найдут здесь ничего нового, но неплохо бы донести эту информацию до широкой общественности, чтобы её имели в виду все программисты для микроконтроллеров.

Не то чтобы это был срыв каких-то покровов. Оказалось, что всё это отлично задокументировано, но беда в том, что не в основных, а в дополнительных документах. И лично я пребывал в счастливом неведении, считая, что DMA — это очень шустрая подсистема, которая позволяет резко повысить эффективность программ, так как там идёт планомерная перекачка данных без отвлечения на те же команды инкремента регистров и организации цикла. Насчёт повышения эффективности – всё верно, но за счёт чуть иных вещей.

Но обо всём по порядку.

Эксперименты с Cypress PSoC

Сделаем простейший автомат. У него будет условно два состояния: состояние покоя и состояние, в которое он будет попадать, когда в FIFO имеется хотя бы один байт данных. Войдя в такое состояние, он просто изымет эти данные, после чего снова провалится в состояние покоя. Слово «условно» я привёл не случайно. У нас два FIFO, поэтому я сделаю два таких состояния, по одному на каждое FIFO, чтобы убедиться в том, что они полностью идентичны по поведению. Граф переходов у автомата получился таким:

какие устройства используют dma. Смотреть фото какие устройства используют dma. Смотреть картинку какие устройства используют dma. Картинка про какие устройства используют dma. Фото какие устройства используют dma

Флаги для выхода из состояния Idle определяем так:

какие устройства используют dma. Смотреть фото какие устройства используют dma. Смотреть картинку какие устройства используют dma. Картинка про какие устройства используют dma. Фото какие устройства используют dma

Не забываем на входы Datapath подать биты номера состояния:

какие устройства используют dma. Смотреть фото какие устройства используют dma. Смотреть картинку какие устройства используют dma. Картинка про какие устройства используют dma. Фото какие устройства используют dma

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

какие устройства используют dma. Смотреть фото какие устройства используют dma. Смотреть картинку какие устройства используют dma. Картинка про какие устройства используют dma. Фото какие устройства используют dma

АЛУ будет просто фиктивно забирать данные из FIFO:

какие устройства используют dma. Смотреть фото какие устройства используют dma. Смотреть картинку какие устройства используют dma. Картинка про какие устройства используют dma. Фото какие устройства используют dma

Давайте я покажу детализацию для состояния «0001»:

какие устройства используют dma. Смотреть фото какие устройства используют dma. Смотреть картинку какие устройства используют dma. Картинка про какие устройства используют dma. Фото какие устройства используют dma

Ещё я поставил разрядность шины, какая была в проекте, на котором я заметил данный эффект, 16 бит:

какие устройства используют dma. Смотреть фото какие устройства используют dma. Смотреть картинку какие устройства используют dma. Картинка про какие устройства используют dma. Фото какие устройства используют dma

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

какие устройства используют dma. Смотреть фото какие устройства используют dma. Смотреть картинку какие устройства используют dma. Картинка про какие устройства используют dma. Фото какие устройства используют dma

Как видно, тактовую частоту я сделал 24 мегагерца. У процессорного ядра частота точно такая же. Чем ниже частота, тем меньше помех на китайском осциллографе (официально у него полоса 250 МГц, но то китайские мегагерцы), а замеры все будут вестись относительно тактовых импульсов. Какая бы частота ни была, система всё равно отработает относительно них. Я бы и один мегагерц поставил, но среда разработки запретила мне вводить значение частоты процессорного ядра менее, чем 24 МГц.

Теперь тестовые вещи. Для записи в FIFO0 я сделал такую функцию:

Слово ROM в имени функции связано с тем, что отправляемый массив хранится в области ПЗУ, а Cortex M3 имеет Гарвардскую архитектуру. Скорость доступа к шине ОЗУ и шине ПЗУ может различаться, хотелось это проверить, поэтому меня есть аналогичная функция для отправки массива из ОЗУ (у массива steps в её теле отсутствует модификатор static const). Ну, и есть такая же пара функций для посылки в FIFO1, там отличается регистр приёмника: не F0, а F1. В остальном все функции идентичны. Так как особой разницы в результатах я не заметил, рассматривать буду результаты вызова именно приведённой выше функции. Жёлтый луч — тактовые импульсы, голубой — выход FIFO0empty.

какие устройства используют dma. Смотреть фото какие устройства используют dma. Смотреть картинку какие устройства используют dma. Картинка про какие устройства используют dma. Фото какие устройства используют dma

Сначала проверим правдоподобность, почему FIFO заполнено на протяжении двух тактов. Посмотрим этот участок поподробнее:

какие устройства используют dma. Смотреть фото какие устройства используют dma. Смотреть картинку какие устройства используют dma. Картинка про какие устройства используют dma. Фото какие устройства используют dma

По фронту 1 данные попадают в FIFO, флаг FIFO0enmpty падает. По фронту 2 автомат переходит в состояние GetDataFromFifo1. По фронту 3 в этом состоянии происходит копирование данных из FIFO в регистр АЛУ, FIFO опустошается, флаг FIFO0empty вновь взводится. То есть осциллограмма ведёт себя правдоподобно, можно считать на ней такты на цикл. Получаем 9 штук.

какие устройства используют dma. Смотреть фото какие устройства используют dma. Смотреть картинку какие устройства используют dma. Картинка про какие устройства используют dma. Фото какие устройства используют dma

Итого, на осмотренном участке, на копирование одного слова данных из ОЗУ в UDB силами DMA требуется 9 тактов.

А теперь то же самое, но силами процессорного ядра. Сначала — идеальный код, слабо достижимый в реальной жизни:

что превратится в ассемблерный код:

Никаких разрывов, никаких лишних тактов. Две пары тактов подряд…

какие устройства используют dma. Смотреть фото какие устройства используют dma. Смотреть картинку какие устройства используют dma. Картинка про какие устройства используют dma. Фото какие устройства используют dma

Сделаем код чуть более реальным (с накладными расходами на организацию цикла выборку данных и инкремент указателей):

полученный ассемблерный код:

На осциллограмме видим всего 7 тактов на цикл против девяти в случае DMA:

какие устройства используют dma. Смотреть фото какие устройства используют dma. Смотреть картинку какие устройства используют dma. Картинка про какие устройства используют dma. Фото какие устройства используют dma

Немного о мифе

Если честно, для меня первоначально это было шоком. Я как-то привык считать, что механизм DMA позволяет быстро и эффективно переносить данные. 1/9 от частоты шины — это не то, чтобы очень быстро. Но оказалось, что никто этого и не скрывает. В документе TRM для PSoC 5LP даже имеется ряд теоретических выкладок, а документ «AN84810 — PSoC 3 and PSoC 5LP Advanced DMA Topics» детально расписывает процесс обращения к DMA. Виной всему латентность. Цикл обмена с шиной занимает некоторое количество тактов. Собственно, именно эти такты и играют решающую роль в возникновении задержки. В общем, никто ничего не скрывает, но это надо знать.

Если знаменитый GPIF, используемый в FX2LP (другой архитектуре, выпускаемой фирмой Cypress), скорость ничем не ограничивает, то здесь ограничение скорости обусловлено латентностями, возникающими при обращениях к шине.

Проверка DMA на STM32

Я был под таким впечатлением, что решил провести эксперимент на STM32. В качестве подопытного кролика был взят STM32F103, имеющий такое же процессорное ядро Cortex M3. У него нет UDB, из которого можно было бы вывести служебные сигналы, но проверить DMA вполне можно. Что такое GPIO? Это набор регистров в общем адресном пространстве. Вот и прекрасно. Настроим DMA в режим копирования «память-память», указав в качестве источника реальную память (ПЗУ или ОЗУ), а в качестве приёмника — регистр данных GPIO без инкремента адреса. Будем слать туда поочерёдно то 0, то 1, а результат фиксировать осциллографом. Для начала я выбрал порт B, к нему было проще подключиться на макетке.

какие устройства используют dma. Смотреть фото какие устройства используют dma. Смотреть картинку какие устройства используют dma. Картинка про какие устройства используют dma. Фото какие устройства используют dma

Мне очень понравилось считать такты пальцем, а не курсорами. Можно ли сделать так же на данном контроллере? Вполне! Опорную тактовую частоту для осциллографа возьмём с ножки MCO, которая у STM32F10C8T6 связана с портом PA8. Выбор источников для этого дешёвого кристалла не велик (тот же STM32F103, но посолиднее, даёт гораздо больше вариантов), подадим на этот выход сигнал SYSCLK. Так как частота на MCO не может быть выше 50 МГц, уменьшим общую тактовую частоту системы до 48 МГц. Будем умножать частоту кварца 8 МГц не на 9, а на 6 (так как 6 * 8 = 48):

какие устройства используют dma. Смотреть фото какие устройства используют dma. Смотреть картинку какие устройства используют dma. Картинка про какие устройства используют dma. Фото какие устройства используют dma

MCO запрограммируем средствами библиотеки mcucpp Константина Чижова (дальше я все обращения к аппаратуре буду вести через эту замечательную библиотеку):

Ну, и теперь задаём вывод массива данных в GPIOB:

Полученная осциллограмма очень похожа на ту, что была на PSoC.

какие устройства используют dma. Смотреть фото какие устройства используют dma. Смотреть картинку какие устройства используют dma. Картинка про какие устройства используют dma. Фото какие устройства используют dma

В середине большой голубой горб. Это идёт процесс инициализации DMA. Голубые импульсы слева получены чисто программным путём на PB1. Растянем их пошире:

какие устройства используют dma. Смотреть фото какие устройства используют dma. Смотреть картинку какие устройства используют dma. Картинка про какие устройства используют dma. Фото какие устройства используют dma

2 такта на импульс. Работа системы соответствует ожидаемой. Но теперь посмотрим покрупнее область, отмеченную на основной осциллограмме тёмно-синим фоном. В этом месте уже работает блок DMA.

какие устройства используют dma. Смотреть фото какие устройства используют dma. Смотреть картинку какие устройства используют dma. Картинка про какие устройства используют dma. Фото какие устройства используют dma

10 тактов на одно изменение линии GPIO. Вообще-то, работа идёт с ОЗУ, а программа зациклена в постоянном цикле. Обращений к ОЗУ от процессорного ядра нет. Шина полностью в распоряжении блока DMA, но 10 тактов. Но на самом деле, результаты не сильно отличаются от увиденных на PSoC, поэтому просто начинаем искать Application Notes, относящийся к DMA на STM32. Их оказалось несколько. Есть AN2548 на F0/F1, есть AN3117 на L0/L1/L3, есть AN4031 на F2/F4/F77. Возможно, есть ещё какие-то…

Но, тем не менее, из них мы видим, что и здесь во всём виновата латентность. Причём у F103 пакетные обращения к шине у DMA невозможны. Они возможны для F4, но не более, чем для четырёх слов. Дальше снова возникнет проблема латентности.

Попробуем выполнить те же действия, но при помощи программной записи. Выше мы видели, что прямая запись в порты идёт моментально. Но там была скорее идеальная запись. Строки:

при условии таких настроек оптимизации (обязательно следует указать оптимизацию для времени):

какие устройства используют dma. Смотреть фото какие устройства используют dma. Смотреть картинку какие устройства используют dma. Картинка про какие устройства используют dma. Фото какие устройства используют dma

превратились в следующий ассемблерный код:

В реальном копировании будет обращение к источнику, к приёмнику, изменение переменной цикла, ветвление… В общем, масса накладных расходов (от которых, как считается, как раз и избавляет DMA). Какая будет скорость изменений в порту? Итак, пишем:

Этот код на C++ превращается в такой ассемблерный код:

какие устройства используют dma. Смотреть фото какие устройства используют dma. Смотреть картинку какие устройства используют dma. Картинка про какие устройства используют dma. Фото какие устройства используют dma

8 тактов в верхнем полупериоде и 6 — в нижнем (я проверил, результат повторяется для всех полупериодов). Разница возникла потому, что оптимизатор сделал 2 копирования на каждую итерацию. Поэтому 2 такта в одном из полупериодов добавляются на операцию ветвления.

Грубо говоря, при программном копировании тратится 14 тактов на копирование двух слов против 20 тактов на то же самое, но силами DMA. Результат вполне документированный, но весьма неожиданный для тех, кто ещё не читал расширенную литературу.

Хорошо. А что будет, если начать писать данные сразу в два потока DMA? Насколько упадёт скорость? Подключим голубой луч к PA0 и перепишем программу следующим образом:

Сначала осмотрим характер импульсов:

какие устройства используют dma. Смотреть фото какие устройства используют dma. Смотреть картинку какие устройства используют dma. Картинка про какие устройства используют dma. Фото какие устройства используют dma

Пока идёт настройка второго канала, скорость копирования для первого выше. Затем, когда идёт копирование в паре, скорость падает. Когда первый канал закончил работу, второй начинает работать быстрее. Всё логично, осталось только выяснить, насколько именно падает скорость.

Пока канал один, запись занимает от 10 до 12 тактов (цифры плавают).

какие устройства используют dma. Смотреть фото какие устройства используют dma. Смотреть картинку какие устройства используют dma. Картинка про какие устройства используют dma. Фото какие устройства используют dma

Во время совместной работы получаем 16 тактов на одну запись в каждый порт:

какие устройства используют dma. Смотреть фото какие устройства используют dma. Смотреть картинку какие устройства используют dma. Картинка про какие устройства используют dma. Фото какие устройства используют dma

То есть, скорость падает не вдвое. А что если начать писать сразу в три потока? Добавляем работу с PC15, так как PC0 не выведен (именно поэтому в массиве выдаётся не 0, 1, 0, 1. а 0x0000,0x8001, 0x0000, 0x8001. ).

Здесь результат настолько неожиданный, что я отключу луч, отображающий тактовую частоту. Нам не до измерений. Смотрим на логику работы.

какие устройства используют dma. Смотреть фото какие устройства используют dma. Смотреть картинку какие устройства используют dma. Картинка про какие устройства используют dma. Фото какие устройства используют dma

Пока не закончил работу первый канал, третий не начал работы. Три канала одновременно не работают! Что-то на эту тему можно вывести из AppNote на DMA, там говорится, что у F103 всего две Engine в одном блоке (а мы копирует средствами одного блока DMA, второй сейчас простаивает, и объём статьи уже такой, что его я в ход пускать не стану). Перепишем на пробу программу так, чтобы третий канал запустился раньше всех:

какие устройства используют dma. Смотреть фото какие устройства используют dma. Смотреть картинку какие устройства используют dma. Картинка про какие устройства используют dma. Фото какие устройства используют dma

Картинка изменится следующим образом:

какие устройства используют dma. Смотреть фото какие устройства используют dma. Смотреть картинку какие устройства используют dma. Картинка про какие устройства используют dma. Фото какие устройства используют dma

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

Немного о приоритетах

Собственно, предыдущая картинка связана с приоритетами DMA, есть и такие. Если у всех работающих каналов указан один и тот же приоритет, в дело вступают их номера. В пределах одного заданного приоритета, у кого номер меньше, тот и приоритетней. Попробуем третьему каналу указать иной глобальный приоритет, возвысив его над всеми остальными (попутно повысим приоритет и второму каналу):

какие устройства используют dma. Смотреть фото какие устройства используют dma. Смотреть картинку какие устройства используют dma. Картинка про какие устройства используют dma. Фото какие устройства используют dma

Теперь ущемлённым станет первый, который раньше был самым крутым.

какие устройства используют dma. Смотреть фото какие устройства используют dma. Смотреть картинку какие устройства используют dma. Картинка про какие устройства используют dma. Фото какие устройства используют dma

Итого, мы видим, что даже играя в приоритеты, больше двух потоков на одном блоке DMA у STM32F103 запустить не получится. В принципе, третий поток можно запустить на процессорном ядре. Это нам позволит сравнить производительность.

Сначала общая картинка, на которой видно, что всё работает в параллель и у процессорного ядра скорость копирования выше всех:

какие устройства используют dma. Смотреть фото какие устройства используют dma. Смотреть картинку какие устройства используют dma. Картинка про какие устройства используют dma. Фото какие устройства используют dma

А теперь я дам возможность всем желающим посчитать такты в то время, когда все потоки копирования активны:

какие устройства используют dma. Смотреть фото какие устройства используют dma. Смотреть картинку какие устройства используют dma. Картинка про какие устройства используют dma. Фото какие устройства используют dma

Процессорное ядро приоритетней всех

Теперь вернёмся к тому факту, что при двухпоточной работе, пока настраивался второй канал, первый выдавал данные за различное число тактов. Этот факт также хорошо документирован в AppNote на DMA. Дело в том, что во время настройки второго канала, периодически шли запросы к ОЗУ, а процессорное ядро имеет при обращении к ОЗУ больший приоритет, чем ядро DMA. Когда процессор запрашивал какие-то данные, у DMA отнимались такты, оно получало данные с задержкой, поэтому производило копирование медленней. Давайте сделаем последний на сегодня эксперимент. Приблизим работу к более реальной. После запуска DMA будем не уходить в пустой цикл (когда обращений к ОЗУ точно нет), а выполнять операцию копирования из ОЗУ в ОЗУ, но эта операция не будет относиться к работе DMA ядер:

какие устройства используют dma. Смотреть фото какие устройства используют dma. Смотреть картинку какие устройства используют dma. Картинка про какие устройства используют dma. Фото какие устройства используют dma

Местами цикл растянулся с 16 до 17 тактов. Я боялся, что будет хуже.

Начинаем делать выводы

Собственно, переходим к тому, что я вообще хотел сказать.

Начну издалека. Несколько лет назад, начиная изучать STM32, я изучал существовавшие на тот момент версии MiddleWare для USB и недоумевал, зачем разработчики убрали прокачку данных через DMA. Видно было, что исходно такой вариант имелся на виду, затем был убран на задворки, а под конец остались только рудименты от него. Теперь я начинаю подозревать, что понимаю разработчиков.

В первой статье про UDB я говорил, что хоть UDB и может работать с параллельными данными, заменить собой GPIF он вряд ли сможет, так как у PSoC шина USB работает на скорости Full Speed против High Speed у FX2LP. Оказывается, есть более серьёзный ограничивающий фактор. DMA просто не успеет доставлять данные с той же скоростью, с какой доставляет их GPIF даже в пределах контроллера, не принимая во внимание шину USB.

Как видим, нет единой сущности DMA. Во-первых, каждый производитель делает его по-своему. Мало того, даже один производитель для разных семейств может варьировать подход к построению DMA. Если планируется серьёзная нагрузка на этот блок, следует внимательно проанализировать, будут ли удовлетворены потребности.

Наверное, надо разбавить пессимистический поток одной оптимистической репликой. Я даже выделю ее.

DMA у контроллеров Cortex M позволяют повысить производительность системы по принципу знаменитых Джавелинов: «Запустил и забыл». Да, программное копирование данных идёт чуть быстрее. Но если надо копировать несколько потоков, никакой оптимизатор не сможет сделать так, чтобы процессор всех их гнал без накладных расходов на перезагрузку регистров и закручивание циклов. Кроме того, для медленных портов процессор должен ещё ждать готовности, а DMA делает это на аппаратном уровне.

Но даже тут возможны различные нюансы. Если порт всего лишь условно медленный… Ну, скажем, SPI, работающий на максимально возможной частоте, то теоретически возможны ситуации, когда DMA не успеет забрать данные из буфера, и произойдёт переполнение. Или наоборот — поместить данные в буферный регистр. Когда поток данных один, вряд ли это произойдёт, но когда их много, мы видели, какие удивительные накладки могут возникать. Чтобы бороться с этим, следует разрабатывать задачи не обособленно, а в комплексе. А тестерам стараться спровоцировать подобные проблемы (такая у тестеров деструктивная работа).

Ещё раз повторю, что эти данные никто не скрывает. Но почему-то всё это обычно содержится не в основном документе, а в Application Notes. Так что моя задача была именно обратить внимание программистов на то, что DMA — это не панацея, а всего лишь удобный инструмент.

Но, разумеется, не только программистов, а ещё и разработчиков аппаратуры. Скажем, у нас в организации сейчас разрабатывается большой программно-аппаратный комплекс для удалённой отладки встраиваемых систем. Идея состоит в том, что кто-то разрабатывает некое устройство, а «прошивку» хочет заказать на стороне. И почему-то не может предоставить оборудование на сторону. Оно может быть громоздким, оно может быть дорогим, оно может быть уникальным и быть «нужно самим», с ним могут работать разные группы в разных часовых поясах, обеспечивая этакую многосменную работу, оно может постоянно доводиться до ума… В общем, причин придумать можно много, нашей группе просто спустили эту задачу, как данность.

Соответственно, комплекс для отладки должен уметь имитировать собой как можно большее число внешних устройств, от банальной имитации нажатия кнопок до различных протоколов SPI, I2C, CAN, 4-20 mA и прочего, прочего, прочего, чтобы через них эмуляторы могли воссоздавать различное поведение внешних блоков, подключаемых к разрабатываемому оборудованию (лично я в своё время сделал много имитаторов для наземной отладки навесного оборудования для вертолётов, у нас на сайте соответствующие кейсы ищутся по слову Cassel Aero).

И вот, в ТЗ на разработку спущены определённые требования. Столько-то SPI, столько-то I2C, столько-то GPIO. Они должны работать на таких-то предельных частотах. Кажется, что всё понятно. Ставим STM32F4 и ULPI для работы с USB в режиме HS. Технология отработанная. Но вот наступают длинные выходные с ноябрьскими праздниками, на которых я разобрался с UDB. Увидев неладное, я уже по вечерам получил те практические результаты, что приведены в начале этой статьи. И понял, что всё, конечно, здорово, но не для данного проекта. Как я уже отметил, когда возможная пиковая производительность системы приближается к верхней границе, следует проектировать всё не раздельно, а в комплексе.

А здесь комплексного проектирования задач не может быть в принципе. Сегодня идёт работа с одним сторонним оборудованием, завтра — совсем с другим. Шины будут использоваться программистами под каждый случай эмуляции по их усмотрению. Поэтому вариант был отвергнут, в схему было добавлено некоторое количество различных мостов FTDI. В пределах моста одна-две-четыре функции будут разрулены по жёсткой схеме, а между мостами всё будет разруливать USB хост. Увы. В данной задаче я не могу доверять DMA. Можно, конечно, сказать, что программисты потом выкрутятся, но часы на процесс выкрутасов – это трудозатраты, которых следует избегать.

Но это крайность. Чаще всего следует просто держать ограничения подсистемы DMA в уме (например, вводить поправочный коэффициент 10: если требуется поток 1 миллион транзакций в секунду, учитывать, что это не 1 миллион, а 10 миллионов тактов) и рассматривать производительность в комплексе.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *