Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Как решить проблему кэша и DMA
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Системы на ПЛИС - System on a Programmable Chip (SoPC)
barabek
Симптомы. Имеется буфер, в который пишет DMA. Иногда начало буфера оказывается испорчено, а именно - сохраняет свое старое значение. Грешил на самописный DMA.

Причина. После долгими мытарствами выяснил, что проблема оказывается в кэше. Перед целевым буфером линкер расположил локальный статический массив. В одной из функций я обращаюсь к этому массиву : tempbuf[8]&=~0x80; В этот момент, я его отловил signaltap, обновляется строка кэша. Но так как строка 32 байта и она частично захватывает массив и частично целевой буфер, то происходит обновление и начала моего буфера. И если в это время DMA кидал данные в эти ячейки, то происходит коллизия, которую я замучался вылавливать.

Вопрос. Как же это побороть? Схожие темы видел, но в них либо причина была иная и решалась обновлением линии кэша (.._flash()), либо решения нет. Одним из решений вижу размещение буфера по границам размера кэш-линии. Но это, на мой взгляд, корявое решение, т.к. и размер должен быть кратен размеру линии. Или есть другие пути?

DevL
если правильно понял проблему ( это свой CPU? )
есть разные пути, например
- http://en.wikipedia.org/wiki/Scratchpad_memory
- ввести locking prefix для асм. инструкций
- вычитывать что dma is done

tegumay
если я правильно помню, эту область ОЗУ надо объявить некэшируемой.
barabek
Цитата
если правильно понял проблему...
Спасибо за содействие, процессор не мой, а Nios. По 1- есть аналог "tightly coupled memory", но мне не подходит. По 2 - не понял. По 3 - тоже не подходит, в общем случае dma пишет в любое время. Ждать не представляется возможным.

Цитата( @ Mar 10 2012, 06:29) *
если я правильно помню, эту область ОЗУ надо объявить некэшируемой.


А как? Использовать alt_remap_uncached? Если я правильно понял, что делает эта функция :

Код

       //'alt_remap_uncached.с'  
      volatile void* alt_remap_uncached (void* ptr, alt_u32 len)
      {
      alt_dcache_flush (ptr, len);
      return (volatile void*) (((alt_u32) ptr) | BYPASS_DCACHE_MASK);
      }


Она возвращает указатель на область некэшируемой памяти, тупо добавив 1-цу в 31-й бит адреса. Но у меня портить память обращение к переменным НЕ принадлежащим к целевому буферу, а соседним. Какие это будут соседи - одному линкеру известно. Или Вы подразумевали что-то другое?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.