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

 
 
> ZYNQ 7000, DMA и Xil_In32, Xil_Out32
sheynmanyu
сообщение Feb 6 2018, 13:02
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 66
Регистрация: 5-07-17
Пользователь №: 97 975



Здравствуйте!
Задача: передать в память DDR со счетчика, расположенного в PL, 512 32-разрядных слов (2 пакета по 256 слов), минимально задействовав процессор. Выбрала передачу через ядро DMA + InterConnect.
Режим работы DMA - не Scatter/Gather, а просто через регистры.
Инициализирую DMA так:
Код
    unsigned int tmpVal;
    Xil_Out32( XPAR_PS7_GPIO_0_BASEADDR + (2 * XGPIOPS_DATA_MASK_OFFSET) + XGPIOPS_DATA_LSW_OFFSET, 0xFFFD0000); //reset fifo - reset it
    Xil_Out32(XPAR_AXI_DMA_0_BASEADDR + 0x30, (1<<RESET_DMA)); //start_DMA_control_reg_val);
        while(Xil_In32(XPAR_AXI_DMA_0_BASEADDR + 0x30) & (1<<RESET_DMA)) xil_printf("Reseting DMA...\n");
    tmpVal = Xil_In32 (XPAR_AXI_DMA_0_BASEADDR + 0x30);
    tmpVal |= 0x1001;  //dma unit enable. interrupt on complete enable
    Xil_Out32(XPAR_AXI_DMA_0_BASEADDR + 0x30, tmpVal);
    tmpVal = Xil_In32 (XPAR_AXI_DMA_0_BASEADDR + 0x30);
    xil_printf("value for DMA control reg is %x\n\r",tmpVal);
    Xil_Out32 (XPAR_AXI_DMA_0_BASEADDR + 0x48, addr);

Обработка прерываний от DMA:
Код
        u32 tmpVal = Xil_In32 (XPAR_AXI_DMA_0_BASEADDR + 0x34);
    
***********
        xil_printf("DMA status %x\n",tmpVal);         //I can't understand, but without this line CPU reading the length of written bytes from DMA fails...
***********
        
         if((tmpVal&(1<<ERR_IRQ))||(tmpVal&(1<<4)))   //reset DMA if DMA Internal error
    {
            XGpioPs_WritePin(&my_Gpio, 54, 0);   //Закончить работу счетчика
            tmpVal = Xil_In32 (XPAR_AXI_DMA_0_BASEADDR + 0x30);
            tmpVal &= ~0x1001;  //dma unit disable. interrupt on complete disable
            Xil_Out32(XPAR_AXI_DMA_0_BASEADDR + 0x30, tmpVal);
            xil_printf("DMA stopped! Data weren't accepted! Sorry!\n");
            finished = 2;   //It would be good to stop DMA?
    }
    else
    {
        tmpVal = Xil_In32 (XPAR_AXI_DMA_0_BASEADDR + 0x58);

***********
        xil_printf("tmpVal is %d\n",tmpVal);
***********

        Max_num = Max_num + tmpVal;
        if((Max_num)<MAX_BYTE_NUMBERS)
        {
            addr = addr + tmpVal;
            StartDMATransfer(addr,MAX_BYTE_NUMBERS-Max_num);
        }
        else
        {
                //тут заканчиваем передачу
              XGpioPs_WritePin(&my_Gpio, 54, 0); //Закончить работу счетчика
         }

Если в коде нет строчек, выделенных **************, то передается не вся посылка, а примерно 280-290 слов. Если есть - передается всё. и в режиме Release, и в режиме Debug. DMA ошибок не выдает. Выполняется команда XGpioPs_WritePin(&my_Gpio, 54, 0); //Закончить работу счетчика
раньше того как будут переданы все слова. MAX_BYTE_NUMBERS = 2048.
Объясните пожалуйста, почему??? Шаманство "добавим вывод в uart и все заработает" мне не сильно нравится. Хотелось бы понять, сколько времени нужно на выполнение операции чтения-записи в память, и как обойтись без uart?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
dmitry-tomsk
сообщение Feb 6 2018, 14:11
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 672
Регистрация: 18-02-05
Пользователь №: 2 741



В system файле щёлкаете на example напротив dma контроллера и копируете оттуда poll_example. Там несколько строчек кода, заблудиться сложно.
Go to the top of the page
 
+Quote Post
sheynmanyu
сообщение Feb 6 2018, 15:32
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 66
Регистрация: 5-07-17
Пользователь №: 97 975



Цитата(dmitry-tomsk @ Feb 6 2018, 17:11) *
В system файле щёлкаете на example напротив dma контроллера и копируете оттуда poll_example. Там несколько строчек кода, заблудиться сложно.

Это не является ответом на мой вопрос. Возможно, это станет решением. Но я, даже после просмотра примера (а мой код создавался изначально на основе этого примера и еще каких-то найденных в сети), я не понимаю, ПОЧЕМУ у меня НОРМАЛЬНО ПЕРЕДАЮТСЯ данные после вставки двух функций вывода строк в uart.
Go to the top of the page
 
+Quote Post
RobFPGA
сообщение Feb 6 2018, 17:38
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 214
Регистрация: 23-12-04
Пользователь №: 1 643



Приветствую!

Цитата(sheynmanyu @ Feb 6 2018, 18:32) *
Это не является ответом на мой вопрос. Возможно, это станет решением. Но я, даже после просмотра примера (а мой код создавался изначально на основе этого примера и еще каких-то найденных в сети), я не понимаю, ПОЧЕМУ у меня НОРМАЛЬНО ПЕРЕДАЮТСЯ данные после вставки двух функций вывода строк в uart.
Скорее всего потому что добавляется задержка до момента когда вы останавливаете счетчик или DMA.
Вывод в uart или в printf это довольно медленные функции. Смотрите по какому событию у Вас настроено прерывание DMA.
Может оно срабатывает не на окончание пересылки данных, а например на окончание обработки дескриптора.

Удачи! Rob.
Go to the top of the page
 
+Quote Post
sheynmanyu
сообщение Feb 6 2018, 18:34
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 66
Регистрация: 5-07-17
Пользователь №: 97 975



Цитата(RobFPGA @ Feb 6 2018, 20:38) *
Приветствую!

Скорее всего потому что добавляется задержка до момента когда вы останавливаете счетчик или DMA.
Вывод в uart или в printf это довольно медленные функции. Смотрите по какому событию у Вас настроено прерывание DMA.
Может оно срабатывает не на окончание пересылки данных, а например на окончание обработки дескриптора.

Удачи! Rob.

На окончание работы дескриптора? Ой... А это как?
Go to the top of the page
 
+Quote Post
dmitry-tomsk
сообщение Feb 6 2018, 19:23
Сообщение #6


Знающий
****

Группа: Свой
Сообщений: 672
Регистрация: 18-02-05
Пользователь №: 2 741



у dma контроллера только одна фича, которая не даёт завершить обмен - отсутствие tlast.
Go to the top of the page
 
+Quote Post
RobFPGA
сообщение Feb 6 2018, 19:38
Сообщение #7


Профессионал
*****

Группа: Свой
Сообщений: 1 214
Регистрация: 23-12-04
Пользователь №: 1 643



Приветствую!

Цитата(dmitry-tomsk @ Feb 6 2018, 22:23) *
у dma контроллера только одна фича, которая не даёт завершить обмен - отсутствие tlast.
Нее .. tlast важен для пакетного режима. В этом случае по tlast закрывается текущий дескриптор со счетчиком реально принятых байт. А без tlast должно быть принято то число байт которое в поле len заданно.

Удачи! Rob.


Go to the top of the page
 
+Quote Post
dmitry-tomsk
сообщение Feb 6 2018, 19:53
Сообщение #8


Знающий
****

Группа: Свой
Сообщений: 672
Регистрация: 18-02-05
Пользователь №: 2 741



Цитата(RobFPGA @ Feb 6 2018, 22:38) *
Приветствую!

Нее .. tlast важен для пакетного режима. В этом случае по tlast закрывается текущий дескриптор со счетчиком реально принятых байт. А без tlast должно быть принято то число байт которое в поле len заданно.

Удачи! Rob.


Гляньте форум на xilinx.com, так уже не раз обсуждали, что без tlast нет завершения, но похоже ещё и от версии корки зависит, в vivado 2017.4 точно так, проверял месяц назад.
Go to the top of the page
 
+Quote Post
sheynmanyu
сообщение Feb 6 2018, 21:18
Сообщение #9


Участник
*

Группа: Участник
Сообщений: 66
Регистрация: 5-07-17
Пользователь №: 97 975



Приветствую!
Цитата(dmitry-tomsk @ Feb 6 2018, 22:53) *
Гляньте форум на xilinx.com, так уже не раз обсуждали, что без tlast нет завершения, но похоже ещё и от версии корки зависит, в vivado 2017.4 точно так, проверял месяц назад.

У меня завершается при любом заданном числе байт, если хотя бы один тласт был. И при этом не обязательно в конце. 2017.1 версия. Только вечером этот эффект отловила - на анализаторе еще не смотрела, но похоже на то.
А можно конкретную ссылку на обсуждение на форуме, плиз?

Цитата(RobFPGA @ Feb 6 2018, 22:08) *
Поэтому Вам надо внимательно почитать-посмотреть как конфигурируются прерывания. Каков статус DMA в прерывании (какое событие вызывает прерывание) и.т.д.

Статус - прерывание по завершению приема. Статус регистр содержит 1002 на первом tlast, и 1000 на втором прерывании. Оба числа представлены в десятичной форме .

Цитата(Sergei_Ilchenko @ Feb 6 2018, 19:59) *
Здравствуйте!
Я не разбираюсь в данном вопросе, но смею предположить, что ошибка может быть локализована не в этом коде.

Можете ли вы показать весь код и процессорный и проектный? Возможно это сможет вам помочь.

Здравствуйте!
Дизайн в pdf файле. Настройки: счетчик обнуляется раз в секунду, считает до заданного значения, генерирует два пакета. Когда счетчик обнуляется, вызывается прерывание, внутри которого настраивается на прием dma, очищается fifo, очищается буфер dma, запускается прием слов и передача их в ddr. Буфер работает в режиме packet fifo, но после первых 16 слов по понятным причинам переходит в режим data fifo, то есть по мере поступления новых слов выдвигает уже имевшиеся на линию своего мастера. Синхронизаторы служат исключительно для подключения ILA. Плата zedboard. Тактовый сигнал на порту clk 100 МГц, он по отношению к плис внешний. В clk wizard из этих внешних 100 я делаю 32 МГц. Master fifo, dma, smc тактируются 100 МГц.


Сообщение отредактировал sheynmanyu - Feb 6 2018, 20:57
Прикрепленные файлы
Прикрепленный файл  2_5463105118117298362.pdf ( 232.78 килобайт ) Кол-во скачиваний: 35
 
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 24th June 2025 - 13:07
Рейтинг@Mail.ru


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