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

За основу взял пример xdmaps_example_w_intr.c
Есть общий файл app_xdmaps.c
В нем функции
Код
static char         Checked [NUMOF_USED_DMA];

int XDMA_init();
int Setup_DMA_Interrupt_System();

void DmaDoneHandler(unsigned int HandleChannel, XDmaPs_Cmd *DmaCmd, void *CallbackRef)
{
    Checked[HandleChannel] = 1;
}

int XDMA_PS_memcpy(char *pDst,char *pSrc, size_t len){
    // Some code
    XDmaPs_SetDoneHandler(&DmaInstance,Channel,DmaDoneHandler,(void *)Checked);
    status=XDmaPs_Start(&DmaInstance, Channel, &DmaCmd, 0);

    while (!Checked[Channel]&& (TimeOutCnt < TIMEOUT_LIMIT)) {
           TimeOutCnt++;
    }

    if (TimeOutCnt >= TIMEOUT_LIMIT) {
        xil_printf("%d Timeout FAILED :-( \r\n",cmd_cnt);

    xil_printf("%d Exit XDMA_PS_memcpy  \r\n",cmd_cnt);
return status;    
}
}

При инициации платформы конфигурирую контроллер DMA, конфигурирую контроллер прерываний, включаю прерывания. Все как в образце.

Затем вызываю функцию XDMA_PS_memcpy.
Указатели src dst и len не обрабатываю, шлю транзакции между фиксированными адресами фиксированной длины.

И вот после вызова функции происходит ситуация, что прерывание как будто "блокируется" кем то. То есть пока я не выйду из функции XDMA_PS_memcpy обработчик прерываний DmaDoneHandler не вызовется. Если убрать счетчик таймаута, то не вызовется никогда.
То есть лог работы выглядит так

Код
1 Timeout FAILED :-(
1 Exit XDMA_PS_memcpy
Handled channel 0
2 Timeout FAILED :-(
2 Exit XDMA_PS_memcpy
Handled channel 0
3 Timeout FAILED :-(
3 Exit XDMA_PS_memcpy

Срабатывает таймаут, выход из функции, вызов обработчика прерываний. Ок, подумал я, попробую сделать в лоб.
Функция XDmaPs_Start может возвращать значения занято, ошибка, Ок. Будем вызывать ее в цикле, пока занято не превратиться в Ок

Код
            do {
                status=XDmaPs_Start(&DmaInstance, Channel, &DmaCmd, 0);
                Channel=(Channel+1) % NUMOF_USED_DMA;
            }
            while (status==XST_DEVICE_BUSY);

В итоге через некоторое время работы я умудряюсь все 8 каналов погрузить в состояние бизи, то есть результат команды для всех каналов навсегда остается XST_DEVICE_BUSY

Что я могу делать не так?
Corner
Как вы считаете, сколько одновременных запросов к памяти поддерживаете ваша внутрення шина?
ConstHw
Ошибка сохраняется если используется 1 канал.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.