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

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

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

Не для ЦОС (хотя и она там возможно в каком-то количестве будет чуть позже), но в устройстве нужно 5-6 UART (одновременно работающих и при этом желательно - не перегружающих систему прерываниями в десятки кГц) + 2 одновременно работающих SPI (20-40МГц). Это как минимум то, что в STM32 придётся делать с DMA. В старых устройствах на LPC17x примерно то же самое работает занимая всего 4 DMA-канала (2 SPI), а UART-ы без DMA нормально работают, так как имеют FIFO. Да и SPI-каналы имеют FIFO, так что, как я понимаю, меньше занимают шину блочными пересылками.

А в новом устройстве планируется более интенсивный поток по SPI-каналам (к тому-же - реалтаймовый). По этой причине в основном и отказались от STM32.

Как тут уже написали - работать с FIFO - то же самое что и без, практически никакой разницы, только частота обслуживания может быть в 16 раз меньше.

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


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

Как тут уже написали - работать с FIFO - то же самое что и без, практически никакой разницы, только частота обслуживания может быть в 16 раз меньше.

 

Это только в "тепличных" условиях. В моем случае была поддержка протоколов с пакетами разной длины от 6 до 1000 байт, причем длина указывается в первых байтах, без таймаутов, там же и ИД-пакета, которые нужно парсить "на лету", тут все фифы только вредят, и работа уартов на 115200 не сильно замедляет систему, если конечно, не нагружать прерывания чем-то еще, кроме приема...

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


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

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

У меня по SPI 2 устройства: at45db и АЦП.

1. Во втором случае надо передавать 2 байта и получать 4.

2. В случае работы с флэшкой то же не всё шикарно. Если не выравнивать флэшку на границу страницы, то надо выполнять кучу работы. Грузить страницу, заполнять, записывать. Для всего этого требуется разные команды. У меня идёт в основном запись архивов и ошибок. Как правило требуется забота с малыми объёмами данных.

Я прикидывал, вариант драйвера с DMA. Для меня это очень значительное усложнение.

 

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

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


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

Это только в "тепличных" условиях. В моем случае была поддержка протоколов с пакетами разной длины от 6 до 1000 байт, причем длина указывается в первых байтах, без таймаутов, там же и ИД-пакета, которые нужно парсить "на лету", тут все фифы только вредят, и работа уартов на 115200 не сильно замедляет систему, если конечно, не нагружать прерывания чем-то еще, кроме приема...

Ну да... 11520*6UART*2(TX/RX) итого частота прерываний ==138240Гц, т.е. - прерывания с периодом 7.2мкс конечно не нагружают никак систему ;)

Про случай когда надо работать всего с одним UART-ом - тут нет вопросов.

А ведь бывают ещё и бОльшие скорости по UART.

У нас тоже по всем UART-каналам идёт обмен по протоколам с размером кадров переменной длины. FIFO не мешает этому никак.

 

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

Когда нужно всего пару байт - никто не мешает использовать обмен по прерываниям: записать в FIFO сразу все 1...8 слов, а потом получить 1..N прерываний и вычитать.

Можно комбинировать (я так делаю при малых размерах транзакции по SPI, полностью влезающей в размер FIFO): настраиваю DMA только на приёмный канал, записываю в TX.FIFO сразу все байты (программно), а потом по окончании приёма всего пакета получаю ОДНО прерывание завершения DMA (без ожидания таймаута по завершению).

Готовность AT45DB никак не надо обходить. Считывать регистр состояния согласно документации. Хоть программно, хоть с DMA.

Никто не мешает смешивать работу через DMA с программным обменом, хоть одновременно, хоть поочередно.

В зависимости от SCLK и её соотношения с частотой CPU, можно хоть программно записать в SPI необходимую команду чтения статуса и ждать поллингом завершения приёма

(допустимо при большой SCLK, когда такое ожидание приёма занимает мало тактов и выигрыш от освобождения процессора на время передачи невелик или нету его),

хоть записать программно, настроив DMA на приём ответа и генерацию прерывания по завершению (если SCLK много меньше частоты CPU и если ждать поллингом, то

надолго займёшь CPU впустую).

На МК без FIFO всё гораздо хуже, так как нельзя записать целиком посылку в FIFO, настроив только RX.DMA.

 

Мы много используем AT45DB. Передача данных в драйверах идёт через DMA, опрос состояния - как я описал (у нас SCLK=25...30МГц).

Под рукой сейчас нет исходника с AT45DB, но вот подобная операция с nRF24L01+ (чтение регистра nRF24L01+ - короткая SPI-транзакция):

static void ActSSP(int cmd, int len, int stepNew)
{
 Pclr(PIN_NRF_CS);  //CS=low
 isrStep = stepNew;
 volatile HwRegsSSP *ssp = &concatAB(SSP, nSSP_nrf);
 HwRegsDMA::T_CH volatile *ch = &DMA.CH[DMA_CH_nrf_RX];
//DMA-канал DMA_CH_nrf_RX статически привязан к данному SPI (nSSP_nrf), так что адрес источника (ch->SRC) и ch->LLI устанавливаются в инит-коде и каждый раз их писать не надо.
//Всё программирование DMA для запуска транзакции занимает 3 строчки кода ниже, настройка регистров: ch->DST, ch->CTL и старт RX.DMA: ch->CFG.
 ch->DST = &sh.regIO.status;
 ch->CTL = len + sizeof(sh.regIO.status) | 1 << 12 | B27 | B31;
 ch->CFG = B0 | (DMA_REQ_nrf_RX >> 4) << 1 | 2 << 11 | B14 | B15;
 ssp->CR[1] = B1;   //включаем SPI-канал
 __DMB();
 ssp->DR = cmd;  //старт передачи (и приёма)
}

static uint RegRead(REG reg)
{
 ActSSP((int)reg + CMD_R_REGISTER, 1, IS_GAP);
 concatAB(SSP, nSSP_nrf).DR = 0;  //запись хвоста (для приёма значения регистра)
 NrfCtxSw(); //переключение контекста в фоновую задачу с ожиданием завершающего DMA-IRQ, который делает CS=high
 return sh.regIO.val[0];
}

[code]#define concatAB_(a, b) a##b
#define concatAB(a, b) concatAB_(a, b)

[/code]

 

Это код для LPC17xx.

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


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

которые нужно парсить "на лету", тут все фифы только вредят,

Это не верно!

Они вредят только в одном случае, при неожиданном разрыве обмена их надо очищать от старых пакетов... И в LPC для уарта они сделали очистку, а для SSP нет, приходиться 8 слов читать чтобы точно передатчик был пусть, в случае слейва это ложиться на внешнее устройство...

 

В остальном они только помогают, UART с FIFO неотличим от UART без фифо, кроме одного момента, на приеме если из UART без фифо не успеть забрать символ, он потеряется, а тут он сохраниться, на передаче без фифо вам приходиться ждать когда уйдет прошлый символ прежде чем сунуть следующий, а с фифо можно сразу запихать несколько.

 

FIFO - благо

 

 

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


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

Готовность AT45DB никак не надо обходить. Считывать регистр состояния согласно документации. Хоть программно, хоть с DMA.

Подскажите а в чём преимущество, если я готовность буду через DMA получать?

Просто мозг закипает.

Кто-нибудь приведёт расчёт доказывающий эффективность такой работы?

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

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

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


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

Это не верно!

Они вредят только в одном случае, при неожиданном разрыве обмена их надо очищать от старых пакетов... И в LPC для уарта они сделали очистку, а для SSP нет, приходиться 8 слов читать чтобы точно передатчик был пусть, в случае слейва это ложиться на внешнее устройство...

 

Тогда объясните алгоритм приема пакета с фифо, где 1й байт ИД, который нужно фильтровать, затем адрес, то-же самое, и длина, по которой определяется буфер, а в конце еще и КС??

Причем длина, как правило, не кратна фифо. Таймауты использовать нельзя!

 

Подскажите а в чём преимущество, если я готовность буду через DMA получать?

Просто мозг закипает.

 

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

 

Если флешка побайтная - то дма не нужен, только для чтения и блоками.

 

Ну да... 11520*6UART*2(TX/RX) итого частота прерываний ==138240Гц, т.е. - прерывания с периодом 7.2мкс конечно не нагружают никак систему

 

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

 

И 130кгц прерываний, для векторного nvic - это немного. Тут все зависит от "кривости" обработчика ;)

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

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


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

Тогда объясните алгоритм приема пакета с фифо, где 1й байт ИД, который нужно фильтровать, затем адрес, то-же самое, и длина, по которой определяется буфер, а в конце еще и КС??

Причем длина, как правило, не кратна фифо. Таймауты использовать нельзя!

 

такой же как и без FIFO. Только разница вот в чем. На 115200 время передачи 1 символа ~87 мкСек, а 16 символов уже 1.3 мСек. То есть если у вас нет фифо, то вы нигде не можете висеть дольше 87 мкСек, потому что иначе уже полученный символ затрется следующим, а если фифо есть, то у вас уже 1.3 миллисекунда есть в запасе до того как начнут гибнуть пришедшие символы.

 

Можно сразу сделать опрос по таймеру с 1 мСек интервалами, и ничего гарантированно не потеряется а нагрузка в 16 раз меньше чем по прерыванием на каждый символ.

 

FIFO ничего не меняет в логике, кроме того что создает запас на всякие непредвиденные случаи.

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


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

FIFO ничего не меняет в логике, кроме того что создает запас на всякие непредвиденные случаи.

 

Хорошо, объясню подругому... Принимаю пакет, фифо настроен на 16 байт, а пакет - 7, т.е. прерывания на прием я не дождусь, а придет оно только, когда приму еще 9 байт, или таймаут, но я должен сразу ответить устройству, что принял от него пакет, а я отвечу только через мсек, а устройство будет "думать", что пакет проглотился и начнет слать новый - не годится.

 

 

 

Можно сразу сделать опрос по таймеру с 1 мСек интервалами,

 

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

 

ЗЫ. Лично мое мнение - фифо использовать хоть как-то удобно только под небольшие пакеты кратной длины, остальное либо прерывания, либо дма.

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

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


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

Хорошо, объясню подругому... Принимаю пакет, фифо настроен на 16 байт, а пакет - 7, т.е. прерывания на прием я не дождусь, а придет оно только, когда приму еще 9 байт, или таймаут, но я должен сразу ответить устройству, что принял от него пакет, а я отвечу только через мсек, а устройство будет "думать", что пакет проглотился и начнет слать новый - не годится.

Таймаут в 3-4 символа -- это слишком много? Что это за устройство у вас такое?

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


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

Подскажите а в чём преимущество, если я готовность буду через DMA получать?

...

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

Вы мой пост вообще читали или сразу отвечать начали? ;)

Я вообще-то там и написал, что в зависимости от соотношения частот CPU и SCLK SPI (сколько тактов CPU займёт SPI-транзакция) и от размера транзакции и нужно определять, что эффективнее - через DMA, или по прерываниям или вообще поллингом (если SCLK - велика, а транзакция == 1-2 байта).

 

Кстати, если речь зашла о AT45DB, то насколько помню там есть возможность быстрого чтения статуса: при активном сигнале CS и отсутствии обмена по SPI, она на линии MISO держит статус занятости. И достаточно просто прочитать состояние пина.

Хотя - может путаю с другой ИС? Уже не помню, давно работал с ней....

 

Хорошо, объясню подругому... Принимаю пакет, фифо настроен на 16 байт, а пакет - 7, т.е. прерывания на прием я не дождусь, а придет оно только, когда приму еще 9 байт, или таймаут, но я должен сразу ответить устройству, что принял от него пакет, а я отвечу только через мсек, а устройство будет "думать", что пакет проглотился и начнет слать новый - не годится.

Что за протокол такой кривой, что 3-4 символа задержка для него обрушивает обмен? На помойку его! ;)

Если таймаут ответа такой короткий, то получается и ответ надо формировать в ISR, а перед этим значит надо и распарсить принятый кадр (на который отвечаем), а значит и парсер входящих кадров

(и собственно вся обработка протокола) должен быть в ISR.

Вот собственно Вы сами и ответили на свой-же вопрос про 130кГц прерываний :biggrin:

Так построенная работа (обработка протокола в ISR) да ещё для нескольких каналов параллельно и завалит всю вашу систему ;)

Пока Вы будете формировать ответ с таймаутом 3-4 символа в ISR, в это время по другому каналу (работающему без FIFO) произойдёт потеря байтов.

 

Только не надо выдумывать следующий умозрительный случай, с протоколом работающим на низкой бодовой скорости и короткими таймаутами на ответ в 1-2 символа ;)

 

ЗЫ. Лично мое мнение - фифо использовать хоть как-то удобно только под небольшие пакеты кратной длины, остальное либо прерывания, либо дма.

Главный плюс FIFO: кратное снижение необходимой частоты обслуживания хоть процессором (снижение частоты прерываний) хоть DMA (пакетные пересылки по шине, меньше её занятость).

 

И 130кгц прерываний, для векторного nvic - это немного. Тут все зависит от "кривости" обработчика ;)

Немного, когда CPU нечем больше заниматься...

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


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

Принимаю пакет, фифо настроен на 16 байт, а пакет - 7, т.е. прерывания на прием я не дождусь,

А... дело в том что фифо всегда 16 символов, оно не настраиваемо. А прерывание можно настроить на 1 символ, половину фифо, все фифо.

 

В приведенном примере настраиваем прерывание на 1 символ, ставим ему не высокий приоритет и все.

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

 

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

 

 

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

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


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

Вот собственно Вы сами и ответили на свой-же вопрос про 130кГц прерываний

Так построенная работа (обработка протокола в ISR) да ещё для нескольких каналов параллельно и завалит всю вашу систему

 

Не буду впадать в тупой спор, просто скажу, что кроме уартов на интах, работает файловая система, сетевой стек, парсер биткода виртуальной задачи, работа с кучей периферии, включая несколько каналов 1wire(кто в теме, тот знает, как этот протокол чувствителен к задержкам)и еще много чего... И самое главное - все работает и "не жужжит". Зависнуть все может только из-за кривости самого программиста.

 

Потом настраиваем прерывание на 1 символ, ставим ему не высокий приоритет и все.лекаться...

 

Дак какой тогда выигрыш-то, кроме дополнительных настроек? Я же говорю, что выигрыш есть, если в протоколе байты передаются кратными пакетами, на которые настроен триггер фифо. Ну сколько времени потребуется, если в инте проверить пару байт и записать в память с инкрементом счетчика?? На частоте 160 МГц?? И за это время что можно потерять?? Ничего не терялось никогда.

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


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

А... дело в том что фифо всегда 16 символов, оно не настраиваемо. А прерывание можно настроить на 1 символ, половину фифо, все фифо.

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

 

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

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

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


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

Если фифо железное, то глубина фифо определена жестко, вопрос в том на какой наполненности мы узнаем что там что-то есть. Если только можно увеличить глубину одного фифо за счет другого... но это экзотика какая-то ИМХО.

 

И самое главное - все работает и "не жужжит"

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

 

Дак какой тогда выигрыш-то, кроме дополнительных настроек?

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

 

Ну сколько времени потребуется, если в инте проверить пару байт и записать в память с инкрементом счетчика??

А обработка общего буфера где? А как же про ответ за время 2-3 символов?

 

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


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

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

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

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

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

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

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

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

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

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