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

И снова LPC4337 + SSP + DMA

Добрый день!

 

В моём проекте в целом работает связь микроконтроллера по ssp с флешками n25q128. Для транзакций задействован DMA. Были в своё время проблемы, не очень чётко описанные в документации, но они давно решены (тема тут.

 

Но недавно выползла новая проблемка. Как я уже сказал, запись/чтение на флешки работает отлично. Никаких сбоев. SSP не использует прерываний, они разрешены лишь только для диагностики. (overrun/timeout). И вот если во время обмена данными в одной из задач выполняется memset в массив, либо std::fill в вектор, то вывалвается прерывание overrun по SSP. Я ни как не могу разобраться в чём дело. У меня есть теория, которую пока не могу ни опровергнуть, ни подтвердить. Возможно, что DMA и процессор не могут поделить шины. И если проц начинает копирование данных, т.е. интенсивно использовать шины, то DMA (не смотря на то, что у него есть fifo, у SSP есть fifo) не успевает вычитать данные с шины. И там наступает переполнение. Если это так, то подскажите, пожалуйста. как грамотно разрулить ситуацию?

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


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

Если это так, то подскажите, пожалуйста. как грамотно разрулить ситуацию?

Приоритеты у приёмного и передающего каналов DMA какие? Надеюсь у RxDMA приоритет выше, чем у TxDMA?

Burst используете и какие размеры? С блокировкой шины или без? И как они соотносятся с размерами кешей?

И к каким областям памяти обращаются DMA и CPU - одной или разным?

 

Как я уже сказал, запись/чтение на флешки работает отлично. Никаких сбоев. SSP не использует прерываний, они разрешены лишь только для

Как же "отлично" если Вы даже не отладили работу в реальной программе, одновременно с другими процессами???

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

Если Вы этого не делали - значит Вы ничего и не отладили.

 

PS: И почему кстати SSP, а не SPIFI?

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


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

Надеюсь у RxDMA приоритет выше, чем у TxDMA?

Да.

Burst используете и какие размеры?

Tx Burst 4 байта, Rx Burst 1 байт (4 работает неустойчиво, этом мы с вам в предыдущей теме по ссылке выше выяснили).

С блокировкой шины или без? И как они соотносятся с размерами кешей?

Об этом ничего не знаю... Что за блокировка? И как про кеши узнать?

И к каким областям памяти обращаются DMA и CPU - одной или разным?

Разные.

Если Вы этого не делали - значит Вы ничего и не отладили.

Ну так как раз в процессе отладки, поскольку над проектом несколько человек работают.

PS: И почему кстати SSP, а не SPIFI?

Так был удобно, ибо на шине кроме флешек висит ещё с десяток устройств.

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


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

И там наступает переполнение. Если это так, то подскажите, пожалуйста. как грамотно разрулить ситуацию?

В Keil есть галочка "Split load and store multiple". Она не дает делать длинные неразрывные программные пересылки регистров которые обычно появляются в функциях типа memset.

Но дело скорее всего не в этом. Мне это никогда не помогало.

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

 

 

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


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

Tx Burst 4 байта, Rx Burst 1 байт (4 работает неустойчиво, этом мы с вам в предыдущей теме по ссылке выше выяснили).

Об этом ничего не знаю... Что за блокировка? И как про кеши узнать?

Я не точно выразился: не кеши, а FIFO в DMA канале и FIFO в SSP.

Я уже давно не работал с LPC, уже подзабыл как там устроено. Но раз используете burst-пересылки, то прежде Вам нужно изучить как там формируются DMA-запросы от периферии. Именно с этим я думаю у Вас как раз и проблемы.

Почти год назад писал драйвер для SPI-FLASH на XMC4700. И у меня были очень похожие проблемы. Это было связано именно с формированием DMA-запросов от SPI-контроллера и их обработкой. В XMC в регистрах TX-FIFO и RX-FIFO программируется по какому уровню заполнения FIFO формировать DMA-event. Когда DMA-event генерируется, он запоминается триггером до момента начала обслуживания DMA-каналом. Вот в таком механизме как раз и кроется проблема.

Например: имею RX-FIFO == 16 слов, уровень генерации DMA-event-а при > 7 слов, размер RX-burst == 8 слов. Вроде бы всё нормально и должно работать? А нет - будет глючить! И чем выше скорость SPI-потока - тем чаще. Как раз и будет возникать событие RX-underrun. С TX-каналом всё аналогично, только будет событие TX-overflow.

Что происходит (как я понял)?: когда в RX-FIFO появляется 8-е слово, генерится RX-DMA-event, который запоминается триггером. Но RX-SPI ведь продолжает в это время работать и уже вдвигает биты следующего слова! DMA-контроллер освобождается, переходит к обслуживанию этого event-а (триггер сбрасывается), т.е. - начинает пересылку burst-а. Но он burst ведь считывает не сразу целиком атомарно из FIFO, а по словам. Например считывает 1-е слово. В FIFO теперь 7 слов. И в этот момент заканчивается вдвигание битов следующего слова. Оно поступает в FIFO, там опять >7 - т.е. генерится новый DMA-event, запоминаемый в триггере. А ведь чтение текущего burst ещё не закончено! И когда чтение закончится, в FIFO останется всего 1 слово (если за это время не успеет прийти ещё слов), а в триггере стоит запрос на чтение следующего burst размером ==8слов. Вот когда DMA начнёт обслуживание этого event-а, вот тогда и случится RX-underrun.

 

Такова природа проблем была у меня в XMC. У Вас возможно аналогично.

Я решил её уменьшением burst до 4 (1/4 от размера FIFO), но уровень формирования DMA-event сделал == 6 (event формируется при появлении 7-го слова в FIFO).

Для TX-канала всё аналогично, но наоборот.

Ну или вообще отказаться от burst (что мне было нежелательно).

Блокировка - это например DMA-контроллер XMC умеет выставлять сигнал LOCK на шину на время проведения burst-транзакции. Т.е. - никакие другие пересылки по шине не будут выполняться до завершения текущего burst DMA. Правда вышеописанной проблемы с формированием DMA-event-ов это никак не решает, хотя несколько уменьшает вероятность появления таких сбоев.

DMA-контроллер в Tiva (например) полностью лишён данной проблемы, так как там DMA-event-ы формируются совершенно по другому (более грамотно).

 

Так был удобно, ибо на шине кроме флешек висит ещё с десяток устройств.

Насколько я помню - в LPC43xx SPIFI по ногам совмещён с одним из SSP, так что ничего не мешает для каких-то пересылок использовать SPIFI, а для других - SSP. Используя средства блокировки. Когда требуется выполнить транзакцию с другим устройством (или запись во FLASH): включаем блокировку, отключаем отображение SPIFI на адресное пространство, выполняем транзакцию, восстанавливаем отображение, снимаем блокировку.

Хотя - дело Ваше.

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


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

Блокировка - это например DMA-контроллер XMC умеет выставлять сигнал LOCK

После выходных посмотрю что-там с dma у LPC. Поищу на счёт блокировки. Но вроде бы такого нет.

восстанавливаем отображение, снимаем блокировку.

В будущем, когда освободится время, возможно и произведём доработку.

 

Благодарю вас за столь подробный и обстоятельный ответ!!!

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


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

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

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

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

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

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

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

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

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

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