реклама на сайте
подробности

 
 
> Zynq: DMA busy, Ваш звонок в DMA очень важен для нас, оставайтесь на линии
ConstHw
сообщение Dec 15 2015, 08:14
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 58
Регистрация: 12-11-15
Пользователь №: 89 287



Начал пользоваться встроенным в процессорную часть 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

Что я могу делать не так?
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 23:24
Рейтинг@Mail.ru


Страница сгенерированна за 0.01351 секунд с 7
ELECTRONIX ©2004-2016