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

Работа с быстрой периферией по прежнему пишется в стиле автоматов состояний.

Задержки делаются аппаратными таймерами. Переключение состояний автоматов производится в процедурах обслуживания прерываний по цепочке от разных источников включая DMA.

Сами прерывания это прерывания уровня ядра.

Прерывание RTOS вызывается только когда уже готов блок данных для обработки. И вот там-то взводится объект синхронизации о готовности данных.

 

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

Изменено пользователем mantech

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


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

"не о чем" - было о другом...

 

конкретный пример SPI обмен:

опустить CS

послать запрос - 6 байт

дождаться ответа (ножки ОК, Есть данные, Ошибка) или таймаут

в случае наличия данных принять их - 4 байта

поднять CS

 

Хорошо звучит написать драйвер, без блокировок, без ожиданий циклами и так далее...

А на деле что?

Прерывания принят - отправлен байт по SPI - нет, единственный способ это проверять флаг что передатчик закончил. ДМА настраивать на обмен 6 байтами - глупо, а 2 ДМА для приема 4 еще глупее. Если нет FIFO как в STM все байты сразу не запихаешь. Растянуть цикл обмена на несколько миллисекунд - глупо.

 

Вот и получается что "надо драйвер написать чтобы все в прерывании делал и не тормозил" - не о чем...

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


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

ДМА настраивать на обмен 6 байтами - глупо, а 2 ДМА для приема 4 еще глупее.

 

Да, если недальновидно выбран микроконтроллер.

 

Я например сразу планирую сколько скоростных последовательных каналов будет в системе и прикидываю сколько каналов DMA понадобится.

 

Чем больше каналов DMA тем лучше чип заточен под RTOS.

 

Лучше всего здесь дела обстоять у Kinetis (32 канала), похуже у STM32F4 (16 каналов), еще хуже у LPC17xx (8 каналов)

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


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

В принципе не возражаю, только вот это - "хорошо читаемый" напрягает. Субъективизм же.

Во первых в скоростной периферии важнее хорошая отлаживаемость

Во вторых хорошо читаемый только короткий код.

Расположите все ISR связанные с одним автоматом в одном месте и получите короткий код, понятно откоментируйте и отформатируйте и получите отличную читаемость.

Вот такая работа с SPI (вполне хорошо читаемая и короткая при построении драйвера на уровне OS-задачи или как я описывал - псевдозадачей (выглядит так же как с OS)):

FlashRead();
n = N_PAGES;
do FlashWrite();
while (--n);

при описывании state-машиной превращается в дикий лес, из нескольких десятков шагов с вермишельной логикой ветвлений:

(учтите что здесь ещё надо расписать шаги внутри FlashRead()/FlashWrite(), с реализацией стека вызовов (стека state-переменных))

while (1) {
  switch (state) {
    case STATE_0:
      StartActionRead(...);
      state = STATE_1;
      break;
    case STATE_1:
      n = N_PAGES;
    case STATE_2:
      StartActionWrite(...);
      state = STATE_3;
      break;
    case STATE_3:
      state = STATE_ERROR;
      if (!result) continue;
      state = STATE_2;
      if (--n) continue;
     ...
    case STATE_ERROR:
     ...
  ...
  }
break;
}

Особенно если учесть, что надо реализовать цикл(циклы), что внутри FlashWrite(), FlashRead() может быть несколько транзакций по SPI-шине с несколькими входами в ISR, могут быть циклы с проверкой условий и т.п.). Вообще если нужно сделать простейшую функцию (набор часто повторяемых действий) на базе state-машины.

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

state-машину, то сразу видно какой получается малочитаемый код.

 

State-машиной ещё вполне нормально реализуются простые линейные последовательности шагов алгоритма, без ветвлений и вызовов функций. Не более того.

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


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

при описывании state-машиной превращается в дикий лес

Для этого существует protothreads. Никакого дикого леса.

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


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

Лучше всего здесь дела обстоять у Kinetis (32 канала), похуже у STM32F4 (16 каналов), еще хуже у LPC17xx (8 каналов)

Тут дело даже не в "канальности".

У STM32F4 например к каждому каналу (точнее, стриму) привязано до 8 определённых источников/приёмников данных.

Поэтому если вы хотите использовать ДМА для 2-3-4 источников, привязанных к одному стриму, то вас может ждать облом.

Точнее, облом был бы неминуем, но один и тот же источних часто (но не всегда) привязан к двум стримам (а в целом они распределены хаотично), но всё же облом вероятен (я — уже). Нет и речи о том чтобы использовать хотя бы половину стримов.

 

А к примеру в "тупике эволюции" блэкфине каналы ДМА не привязаны к конкретной периферии.

При этом забавно, что там каналов чуть ли не больше чем источников данных :-)))

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


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

еще матрица шин, а потом доступ проца и каналы кроют друг друга, и к шине не достучишься...

ДМА - хорошо, но все же использовать надо с осторожностью.

 

Опять же иногда ДМА настроить дольше чем перепихать данные... LPC кстати имеет фифо - что здорово облегчает иногда дело, но все равно проблемы имеются...

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


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

Вот и получается что "надо драйвер написать чтобы все в прерывании делал и не тормозил" - не о чем...

 

Ну вот зачем такие голословные утверждения?

 

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

 

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

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


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

Поэтому если вы хотите использовать ДМА для 2-3-4 источников, привязанных к одному стриму, то вас может ждать облом.

Точнее, облом был бы неминуем, но один и тот же источних часто (но не всегда) привязан к двум стримам (а в целом они распределены хаотично), но всё же облом вероятен (я — уже). Нет и речи о том чтобы использовать хотя бы половину стримов.

Это одна из главных причин из-за которой недавно, при выборе МК для новой железки, мы отказались от STM32F4. Очень убого реализована периферия в нём - ни буферизации (FIFO) ни достаточного числа DMA-каналов для решения проблемы без FIFO. :(

 

Опять же иногда ДМА настроить дольше чем перепихать данные... LPC кстати имеет фифо - что здорово облегчает иногда дело, но все равно проблемы имеются...

LPC, Tiva имеют нормальные FIFO (UARTы, SPI, etc). STM32 экономит на пуговицах непонятно зачем, значительно ухудшая характеристики МК.

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


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

Прием - запускаю дма и счетчик таймаута, жду событий и генерю софтинт, что сложного?

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

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


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

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

Смотрю различные драйвера обработки SPI - просто убивает. Порой визуально видно, что будет менее эффективно чем простой while.

При частоте проца 168МГц и работе SPI 22, байт вылетает за 61 такт. Обработчик прерывания на SPI это не 2 строки. Плюс вход/ выход. В чём прелесть?

Применение DMA порой ещё более натянуто. Я попробовал реализовать работу с флэшкой at45db. Правда у меня там разные режимы включая потоковую запись через разные буфера. Применение DMA существенно усложняет драйвер. Оценить выигрыш в производительности не представляется возможным. Оценить надёжность такой работы ... Да это надо целое исследование производить. При этом не надо забывать, что Ваше приложение не винда!!! Вам не нужно обеспечивать максимальную производительность. Вам надо обеспечить достаточную производительность. Как правило. Ну если не рассматривать вопросы потребления.

Применение автомата в некоторых случаях конечно оправдано и наиболее удобно.

А в целом нет универсального способа написания драйвера. Чего бы то ни было. Надо исходить из поставленной задачи.

Кидайте в меня палками, на SPI я применяю while. Не блокирующий. Кроме того у меня есть один поток на диагностику, где я пытаюсь контролировать в том числе зависание потока, а также анализирую зависание периферии. Там кстати автомат, так как я там всякие мелкие задачи в один поток собираю чтобы не плодить.

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


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

Смотрю различные драйвера обработки SPI - просто убивает. Порой визуально видно, что будет менее эффективно чем простой while.

При частоте проца 168МГц и работе SPI 22, байт вылетает за 61 такт. Обработчик прерывания на SPI это не 2 строки. Плюс вход/ выход. В чём прелесть?

Прелесть в том, что по SPI обычно не по одному байту пересылают, а десятки и сотни за транзакцию.

 

Применение DMA существенно усложняет драйвер. Оценить выигрыш в производительности не представляется возможным. Оценить надёжность такой работы ... Да это надо целое исследование производить.

Ошибаетесь. Всего ПЛЮС несколько дополнительных строк на инициализацию, и МИНУС некоторое кол-во строк на цикл опроса состояний/программной пересылки и т.п.

В простых случаях по коду одинаково, но несравнимо быстрее с DMA.

 

Кидайте в меня палками, на SPI я применяю while. Не блокирующий. Кроме того у меня есть один поток на диагностику, где я пытаюсь контролировать в том числе зависание потока, а также анализирую зависание периферии. Там кстати автомат, так как я там всякие мелкие задачи в один поток собираю чтобы не плодить.

Ваш while убъёт все нижележащие по приоритету задачи. Особенно если там надо не один-два байта переслать.

Для многозадачной среды - это зло.

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


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

Это одна из главных причин из-за которой недавно, при выборе МК для новой железки, мы отказались от STM32F4. Очень убого реализована периферия в нём - ни буферизации (FIFO) ни достаточного числа DMA-каналов для решения проблемы без FIFO.

 

Че-то не пойму, или все пытаются использовать стм для ЦОС, с несколькими стримами по 100 мегабайт\сек или используют сразу всю периферию, что каналов дма нехватает или что еще...

Вот никогда эти фифо не использовал, муторно с ними, работал с 5 уартами и 2 спи одновременно, по 100мег не передавал, конечно, ибо для таких задач существуют коммуникационные процы или плис. Никаких проблем не испытывал, либо, принимал по прерываниям, либо дма, для больших пакетов.

 

Тут, по моему, искусственно создают бурю в стакане воды...

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


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

Вот никогда эти фифо не использовал, муторно с ними

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

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


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

Че-то не пойму, или все пытаются использовать стм для ЦОС, с несколькими стримами по 100 мегабайт\сек или используют сразу всю периферию, что каналов дма нехватает или что еще...

Достаточно неудачно выбрать 3-4 периферийных блока чтобы стримы ДМА пересеклись.

А для ЦОС - да, уже пытаюсь использовать.

 

по 100мег не передавал, конечно, ибо для таких задач существуют коммуникационные процы или плис.

Для ПЛИС 100 МБпс это ничто. Отличный способ сделать совершенно неоптимальное устройство.

Можно мне показать такой "коммуникационный процессор"? Чтобы 1-2МБ флеши, 256КБ срамы, корпус 10х10х0.6?

Задача ещё и в том чтобы обрабатывать эти потоки на минимальной частоте ядра. Для моей текущей задачи разница в потреблении на частоте 168 и 84 очень существенна. Надеюсь вообще уложиться в 42.

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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