torik 0 8 февраля, 2008 Опубликовано 8 февраля, 2008 · Жалоба Вот и опять я....) Ранее был разговор о том, как загружать данные из CFI_FLASH в SDRAM. Была проблема в том что глючно происходила запись. Как выяснилось из документации - виноват кэш. И проблема, соответсвенно решилась использованием макросов IOWR/IORD. Код перекачки одного кадра изображения из флеша в сдрам получился такой: for (i = 0; i < 614400; i++) { dst_src = IORD_8DIRECT(CFI_FLASH_0_BASE+f_offset, i); IOWR_8DIRECT(SDRAM_0_BASE+d_offset, i, dst_src); } Как вы понимаете - этот метод уже не устраивает, т.к. процессор загружен. Иными словами, я решил разобраться с прямым доступом к памяти DMA. Вот тут-то и возникли проблемы :(, прошу помочь найти ошибку. Как используем DMA: alt_dma_txchan txchan; alt_dma_rxchan rxchan; int rc, rc1; if ((txchan = alt_dma_txchan_open("/dev/dma_0")) == NULL) {rc1 = 2;}; if ((rxchan = alt_dma_rxchan_open("/dev/dma_0")) == NULL) {rc1 = 3;}; if ((rc = alt_dma_txchan_send (txchan, (void*)(CFI_FLASH_0_BASE+f_offset), 614400, NULL, NULL)) < 0) { rc1 = 4; } if ((rc = alt_dma_rxchan_prepare (rxchan, (void*)(SDRAM_0_BASE+d_offset), 614400, dma_done, NULL)) < 0) { rc1 = 5; } while (!rx_done); //инкремент в функции dma_done rx_done = 0; Эта последовательность действий получена на основе примера memtest. Результат плачевный - в дебагере видно, что даже результат первых строчек NULL. Почему не открывается канал? CFI_FLASH_0_BASE+f_offset = адрес картинки во влеше, источник SDRAM_0_BASE+d_offset = куда копировать, адрес в ОЗУ Прилагаю также картинки SOPC и настроек DMA. Помогите разобраться что не так... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
torik 0 12 февраля, 2008 Опубликовано 12 февраля, 2008 · Жалоба Что, никто не пишет программы по ниос? Та же фигня и с флеш памятью. Все работает только через IOWR-ы. В чем дело? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
id_gene 0 12 февраля, 2008 Опубликовано 12 февраля, 2008 · Жалоба Да методы отладки остались все те же: 1. чтение документации; 2. моделирование верилога; 3. пошаговая отладка в железе; 4. монитор памяти в отладчике; 5. сигналтап. Расковыряйте в исходниках, что делает функция alt_dma_txchan_open, дизассемблируйте код, посмотрите регистры процессора в режиме step debug. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
torik 0 12 февраля, 2008 Опубликовано 12 февраля, 2008 · Жалоба Да можно и так, но опыта у меня мало, потому все это займет у меня много времени, а не хотелось бы. Кроме того - дизассемблирование вообще, на мой взгляд - чушь порядочная. Ты когда на visual С++ по windows пишешь и ошибка появляется, тоже "дизассемблируешь"? Потому и спрашиваю, что наверняка кто-либо уже с этим сталкивался и ошибка весьма примитивна... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Postoroniy_V 0 13 февраля, 2008 Опубликовано 13 февраля, 2008 · Жалоба Да можно и так, но опыта у меня мало, потому все это займет у меня много времени, а не хотелось бы. Кроме того - дизассемблирование вообще, на мой взгляд - чушь порядочная. Ты когда на visual С++ по windows пишешь и ошибка появляется, тоже "дизассемблируешь"? Потому и спрашиваю, что наверняка кто-либо уже с этим сталкивался и ошибка весьма примитивна... Обычно если что то не получается так как у вас например, я использую совет id_gene 3. пошаговая отладка в железе; посмотрите что происходит при вызове alt_dma_txchan_open и что в ней например есть вызов alt_find_dev ну и так далее... страно что сразу так не сделать было....много вопросов отпало сразу же Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
id_gene 0 13 февраля, 2008 Опубликовано 13 февраля, 2008 · Жалоба Да можно и так, но опыта у меня мало, потому все это займет у меня много времени, а не хотелось бы. Кроме того - дизассемблирование вообще, на мой взгляд - чушь порядочная. Ты когда на visual С++ по windows пишешь и ошибка появляется, тоже "дизассемблируешь"?Ну, ваш вопрос висит уже 4 дня, и никто еще не ответил, похоже, что никто не сталкивался с такой проблемой, поэтому не лез в исходники С-файлов. Я, честно говоря, ДМА не использовал, но просто поиском в файлах описания указанной функции не нашел. :( А отладка займет не так уж много времени, как вам кажется. Главное - найти в исходниках функцию и понять, что она делает. И тут не С++, программа не такая уж сложная. Дизассемблируйте с ключом -S, будет понятнее. Если ключ gcc -O0 (не оптимизировать), то результат будет очень близок к исходнику. Первый шаг: в отладчике ставите точку останова перед вызовом функции, дожидаетесь останова, далее переключаетесь в режим "instruction stepping mode" и шагаете по коду. Исходники там, кажется, тоже откроются. Проблема тут в том, что альтера многие свои функции объявляет _inline_ , так что они не всегда у вас "всплывут" при обычной отладке, вы перешагнете через них и не заметите. Лучше два часа потерять сейчас на простом примере, зато в следующий раз такие проблемы решатся гораздо быстрее. Если вы собираетесь дальше работать с ниосом, применять этот метод вам рано или поздно придется все равно (когда вы начнете писать сложные приложения и драйверы под свои модули). Удачи Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
torik 0 13 февраля, 2008 Опубликовано 13 февраля, 2008 · Жалоба Раз так все говорят, значит это, вероятно, правда :) Приду на работу - пошагово отлажу. За ответ спасибо! Кроме того, id_gene прав на счет пары часов... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
torik 0 15 февраля, 2008 Опубликовано 15 февраля, 2008 · Жалоба Продолжу здесь, дабы не захламлять эфир еще одной темой... Дошел до того, что хочу подключить библиотеку к проекту в ниосе. Добавляю в проект elca_fat.h и elca_fat.a (сама библиотека) и... при компиляции IDE делает вид что не видит эту библиотеку. Я уже и в свойствах проекта ее указал - почему не видит? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexanderL 0 15 февраля, 2008 Опубликовано 15 февраля, 2008 · Жалоба Доброго времени суток! По поводу ДМА: dma_clear_status(); dma_clear_control(); dma_wr_source_address(source_addr); dma_wr_dest_address(dest_addr); dma_wr_length(length); //длинна в байтах dma_wr_control(ALTERA_AVALON_DMA_CONTROL_DWORD_MSK| ALTERA_AVALON_DMA_CONTROL_LEEN_MSK| ALTERA_AVALON_DMA_CONTROL_RCON_MSK| ALTERA_AVALON_DMA_CONTROL_GO_MSK); // все эти биты есть в описании while (IORD_ALTERA_AVALON_DMA_STATUS (DMA_0_BASE) & ALTERA_AVALON_DMA_STATUS_BUSY_MSK); // ждем пока все не передаст :) САМИ МАКРОСЫ #include <altera_avalon_dma_regs.h> #define dma_clear_status() IOWR_ALTERA_AVALON_DMA_STATUS(DMA_0_BASE, 0) #define dma_clear_control() IOWR_ALTERA_AVALON_DMA_CONTROL(DMA_0_BASE,0) #define dma_wr_source_address(address) IOWR_ALTERA_AVALON_DMA_RADDRESS(DMA_0_BASE, address) #define dma_wr_dest_address(address) IOWR_ALTERA_AVALON_DMA_WADDRESS(DMA_0_BASE, address) #define dma_wr_length(length) IOWR_ALTERA_AVALON_DMA_LENGTH(DMA_0_BASE, length) #define dma_wr_control(control) IOWR_ALTERA_AVALON_DMA_CONTROL(DMA_0_BASE, control) по поводу библиотек, попробуй грохнуть старые sislib из проекта и создать новые, вроде помогало (правой кнопкой мыша и создать новую библиотеку, должно втянуть то что ты написал) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
torik 0 15 февраля, 2008 Опубликовано 15 февраля, 2008 · Жалоба Вот спасибо! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RYury 0 19 февраля, 2008 Опубликовано 19 февраля, 2008 · Жалоба Вот еще код при работе с дма, шина данных 8 бит. #include <stdio.h> #include "altera_avalon_dma.h" #include "sys/alt_dma.h" char txbuf[512]; char rxbuf[512]; static volatile int rx_done = 0; static void dma_done (void* handle, void* data) { rx_done++; } int main() { int dma_ok, rc, i; alt_dma_txchan txchan; alt_dma_rxchan rxchan; if ((txchan = alt_dma_txchan_open("/dev/dma")) == NULL) printf("alt_dma_txchan_open error\n"); if ((rxchan = alt_dma_rxchan_open("/dev/dma")) == NULL) printf("alt_dma_rxchan_open error\n"); alt_dma_txchan_ioctl(txchan, ALT_DMA_SET_MODE_8, NULL);//SDRAM MT48LC8M8A2->WIDTH_DATA=8 alt_dma_rxchan_ioctl(rxchan, ALT_DMA_SET_MODE_8, NULL);//SDRAM MT48LC8M8A2->WIDTH_DATA=8 while(1) { printf("test dma \n"); for(i=0; i<512; i++) {txbuf=i; rxbuf=0; } if ((rc = alt_avalon_dma_send(txchan, txbuf, 512, NULL, NULL)) < 0) { printf("alt_dma_txchan_send : error = %d\n", rc); } if ((rc = alt_avalon_dma_prepare(rxchan, rxbuf, 512, dma_done, NULL)) < 0) { printf("alt_dma_rxchan_send : error = %d\n", rc); } while (!rx_done); //инкремент в функции dma_done rx_done = 0; dma_ok = 1; for(i=0; i<512; i++) { if(rxbuf != txbuf) { dma_ok = 0; printf("error : txbuf[%d] = %x rxbuf[%d] = %x\n", i, txbuf, i, rxbuf); } } if(dma_ok) printf("dma_ok\n"); } return 0; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
torik 0 19 февраля, 2008 Опубликовано 19 февраля, 2008 · Жалоба Вариант работы через IOWR-ы впорядке, все работает нормально... Последний вариант, к сожалению не работает. Я тоже самое взял из примера memtest (вроде). txchan = alt_dma_txchan_open("/dev/dma") когда дело доходит до этой функции - он не воспринимает имя "/dev/dma", и я пока отложил в сторону эту проблему... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться