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

 
 
> Обращение к AXI_DMA приводит к зависанию, Zynq на плате HW-Z7-ZC702
Nivovod
сообщение Mar 2 2018, 12:58
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 38
Регистрация: 16-06-10
Пользователь №: 57 971



Нужно мне гнать поток данных из своей логики через AXI4-Stream. Написал я интерфейсный блок AXI4-Stream, добавил к своей логике, сделал ядро. Подключил к AXI_DMA. Взял драйвер отсюда https://github.com/Xilinx/embeddedsw/blob/m...e_simple_poll.c
Проходит инициализация DMA и виснет проц на строке
XAxiDma_IntrDisable(&AxiDma, XAXIDMA_IRQ_ALL_MASK, XAXIDMA_DEVICE_TO_DMA);
то есть ровно в том месте где идет попытка записи в регистры DMA.

Ну думаю - накосячил где-то со своим IP. Нашел пошаговую инструкцию подключения и работы с AXI_DMA
http://www.fpgadeveloper.com/2014/03/using...dma-engine.html
Там и vhdl код ядра взял, там и драйвер взял. Все по инструкции сделал. Снова виснет в ТОМ ЖЕ МЕСТЕ. Если закоментировать запрет прерываний, то виснет на строке
XAxiDma_SimpleTransfer(&AxiDma,(UINTPTR) RxBufferPtr, MAX_PKT_LEN, XAXIDMA_DEVICE_TO_DMA);
то есть опять в том месте где идет запись в DMA.

Понимаю что проблема элементарная и кроется в мелочи, но осилить не могу уже несколько дней. Прошу помощи.

P.S. Использую ISE 14.5, XPS, SDK.

Сообщение отредактировал Nivovod - Mar 2 2018, 12:59
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Nivovod
сообщение Mar 6 2018, 06:29
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 38
Регистрация: 16-06-10
Пользователь №: 57 971



Продолжим.

Описываю по шагам ход пробы работы с DMA.

1. Создаю в ISE проект на Zynq XC7Z020 CLG484. Головной файл в schematic. В него добавляю Embedded Processor. Запускается XPS, где я импортирую xml файл тестовой платы HW-Z7-ZC702 (рис.1)

2. Создаем своё ядро с названием my_dma(рис.2), интерфейсом AXI4-Stream(рис.3), оставляем размерность без изменений(рис.4), не генерим лишних файлов(рис.5).

3. Меняем код в VHDL файле ядра на прикрепленный

4. Вставляем наше ядро в процессор (рис.6)

5. Вставляем ядро AXI DMA Engine. Снимаем галку со строки Include Scatter Gather Engine (рис. 7). Все остальные параметры по умолчанию. Окончание настройки - добавляем ядро (рис.8)

6. Подключаем наше ядро к DMA через AXI4-Stream.(рис.9). Модули axi_intercoonect добавились и подключились автоматически.
Настройки не менял

7. Подключаем сигнал ACLK нашего ядра к тому же клоку что используют axi_intercoonect(рис.10)

8. Запускаем Generate Netlist

9. По окончании генерации возвращаемся в ISE. Вставляем символ проца. Подключаем все его выводы. Компилим проект. Создаем bit файл. Импортируем и запускаем SDK

10. В SDK создаем новый Application Project с шаблоном Hello World(рис. 11)

11. Копируем в него прикрепленный код

12. Грузим плис и запускаем проект(рис.12)

13. Получаем неизменное зависание на первой строке запрета прерываний(рис.13)


14. Еще можно перед запуском Generate Netlist открыть mhs файл проекта и в ручную прописать порт ARESETN нашего ядра(рис. 14), ибо не понятно подключился ли он автоматически (рис. 15).

На результат это никак не влияет. Зависание в том же месте.

Вопрос тот же. Что я делаю не так? Где ошибка?

VHDL Код ядра

Код
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity dma_axis is
    port
    (
        -- DO NOT EDIT BELOW THIS LINE ---------------------
        -- Bus protocol ports, do not add or delete.
        ACLK    : in    std_logic;
        ARESETN : in    std_logic;
        S_AXIS_TREADY   : out   std_logic;
        S_AXIS_TDATA    : in    std_logic_vector(31 downto 0);
        S_AXIS_TLAST    : in    std_logic;
        S_AXIS_TVALID   : in    std_logic;
        M_AXIS_TVALID   : out   std_logic;
        M_AXIS_TDATA    : out   std_logic_vector(31 downto 0);
        M_AXIS_TLAST    : out   std_logic;
        M_AXIS_TREADY   : in    std_logic
        -- DO NOT EDIT ABOVE THIS LINE ---------------------
    );

attribute SIGIS : string;
attribute SIGIS of ACLK : signal is "Clk";

end dma_axis;

architecture EXAMPLE of dma_axis is

   -- Total number of input data.
   constant NUMBER_OF_INPUT_WORDS  : natural := 8;

   -- Total number of output data
   constant NUMBER_OF_OUTPUT_WORDS : natural := 8;

   type STATE_TYPE is (Idle, Read_Inputs, Write_Outputs);

   signal state        : STATE_TYPE;

   -- Accumulator to hold sum of inputs read at any point in time
   signal sum          : std_logic_vector(31 downto 0);

   -- Counters to store the number inputs read & outputs written
   signal nr_of_reads  : natural range 0 to NUMBER_OF_INPUT_WORDS - 1;
   signal nr_of_writes : natural range 0 to NUMBER_OF_OUTPUT_WORDS - 1;

   -- TLAST signal
   signal tlast : std_logic;

begin
   -- CAUTION:
   -- The sequence in which data are read in and written out should be
   -- consistent with the sequence they are written and read in the
   -- driver's axi_stream_generator.c file

   -- S_AXIS_TREADY  <= '1'   when state = Read_Inputs   else '0';
   S_AXIS_TREADY  <= '0' when state = Write_Outputs else '1';
   M_AXIS_TVALID <= '1' when state = Write_Outputs else '0';

   M_AXIS_TDATA <= sum;
   M_AXIS_TLAST <= tlast;

   The_SW_accelerator : process (ACLK) is
   begin  -- process The_SW_accelerator
    if ACLK'event and ACLK = '1' then     -- Rising clock edge
      if ARESETN = '0' then               -- Synchronous reset (active low)
        -- CAUTION: make sure your reset polarity is consistent with the
        -- system reset polarity
        state        <= Idle;
        nr_of_reads  <= 0;
        nr_of_writes <= 0;
        sum          <= (others => '0');
        tlast        <= '0';
      else
        case state is
          when Idle =>
            if (S_AXIS_TVALID = '1') then
              state       <= Read_Inputs;
              nr_of_reads <= NUMBER_OF_INPUT_WORDS - 1;
              sum         <= (others => '0');
            end if;

          when Read_Inputs =>
            if (S_AXIS_TVALID = '1') then
              -- Coprocessor function (Adding) happens here
              sum         <= std_logic_vector(unsigned(sum) + unsigned(S_AXIS_TDATA));
              if (S_AXIS_TLAST = '1') then
                state        <= Write_Outputs;
                nr_of_writes <= NUMBER_OF_OUTPUT_WORDS - 1;
              else
                nr_of_reads <= nr_of_reads - 1;
              end if;
            end if;

          when Write_Outputs =>
            if (M_AXIS_TREADY = '1') then
              if (nr_of_writes = 0) then
                state <= Idle;
                tlast <= '0';
              else
                -- assert TLAST on last transmitted word
                if (nr_of_writes = 1) then
                  tlast <= '1';
                end if;
                nr_of_writes <= nr_of_writes - 1;
              end if;
            end if;
        end case;
      end if;
    end if;
   end process The_SW_accelerator;
end architecture EXAMPLE;



СИ код прикладного проекта

Код
#include <stdio.h>
#include "platform.h"
#include "xaxidma.h"
#include "xparameters.h"

/*
* Device hardware build related constants.
*/

#define DMA_DEV_ID        XPAR_AXIDMA_0_DEVICE_ID

//#define MEM_BASE_ADDR        (XPAR_PS7_DDR_0_S_AXI_BASEADDR + 0x1000000)
#define MEM_BASE_ADDR        (XPAR_PS7_DDR_0_S_AXI_BASEADDR + 0x10000000)

#define TX_BUFFER_BASE        (MEM_BASE_ADDR + 0x00100000)
#define RX_BUFFER_BASE        (MEM_BASE_ADDR + 0x00300000)
#define RX_BUFFER_HIGH        (MEM_BASE_ADDR + 0x004FFFFF)

#define MAX_PKT_LEN_WORDS    8
#define MAX_PKT_LEN            MAX_PKT_LEN_WORDS*4

#define TEST_START_VALUE    0xC

#define NUMBER_OF_TRANSFERS    10

/************************** Function Prototypes ******************************/

int XAxiDma_SimplePollExample(u16 DeviceId);
static int CheckData(void);

/************************** Variable Definitions *****************************/
/*
* Device instance definitions
*/
XAxiDma AxiDma;


int main()
{
    int Status;

    init_platform();
    xil_printf("\r\n--- Entering main() --- \r\n");

    /* Run the poll example for simple transfer */
    Status = XAxiDma_SimplePollExample(DMA_DEV_ID);

    if (Status != XST_SUCCESS) {

        xil_printf("XAxiDma_SimplePollExample: Failed\r\n");
        return XST_FAILURE;
    }

    xil_printf("XAxiDma_SimplePollExample: Passed\r\n");

    xil_printf("--- Exiting main() --- \r\n");

    return XST_SUCCESS;
}

/*****************************************************************************/
/**
* The example to do the simple transfer through polling. The constant
* NUMBER_OF_TRANSFERS defines how many times a simple transfer is repeated.
*
* @param    DeviceId is the Device Id of the XAxiDma instance
*
* @return
*        - XST_SUCCESS if example finishes successfully
*        - XST_FAILURE if error occurs
*
* @note        None
*
*
******************************************************************************/
int XAxiDma_SimplePollExample(u16 DeviceId)
{
    XAxiDma_Config *CfgPtr;
    int Status;
    int Tries = NUMBER_OF_TRANSFERS;
    int Index;
    u32 *TxBufferPtr;
    u32 *RxBufferPtr;
    u32 Value;

    TxBufferPtr = (u32 *)TX_BUFFER_BASE;
    RxBufferPtr = (u32 *)RX_BUFFER_BASE;

    /* Initialize the XAxiDma device.
     */
    CfgPtr = XAxiDma_LookupConfig(DeviceId);
    if (!CfgPtr) {
        xil_printf("No config found for %d\r\n", DeviceId);
        return XST_FAILURE;
    }


    Status = XAxiDma_CfgInitialize(&AxiDma, CfgPtr);
    if (Status != XST_SUCCESS) {
        xil_printf("Initialization failed %d\r\n", Status);
        return XST_FAILURE;
    }

    if(XAxiDma_HasSg(&AxiDma)){
        xil_printf("Device configured as SG mode \r\n");
        return XST_FAILURE;
    }

    xil_printf("1");

    /* Disable interrupts, we use polling mode
     */
    XAxiDma_IntrDisable(&AxiDma, XAXIDMA_IRQ_ALL_MASK,
                        XAXIDMA_DEVICE_TO_DMA);
    xil_printf("2");
    XAxiDma_IntrDisable(&AxiDma, XAXIDMA_IRQ_ALL_MASK,
                        XAXIDMA_DMA_TO_DEVICE);


    Value = 0;

    for(Index = 0; Index < MAX_PKT_LEN_WORDS; Index ++) {
            TxBufferPtr[Index] = Value;
            Value++;
    }
    /* Flush the SrcBuffer before the DMA transfer, in case the Data Cache
     * is enabled
     */
    Xil_DCacheFlushRange((u32)TxBufferPtr, MAX_PKT_LEN);

    for(Index = 0; Index < Tries; Index ++) {


        Status = XAxiDma_SimpleTransfer(&AxiDma,(u32) RxBufferPtr,
                    MAX_PKT_LEN, XAXIDMA_DEVICE_TO_DMA);

        if (Status != XST_SUCCESS) {
            return XST_FAILURE;
        }


        Status = XAxiDma_SimpleTransfer(&AxiDma,(u32) TxBufferPtr,
                    MAX_PKT_LEN, XAXIDMA_DMA_TO_DEVICE);

        if (Status != XST_SUCCESS) {
            return XST_FAILURE;
        }

        while (XAxiDma_Busy(&AxiDma,XAXIDMA_DMA_TO_DEVICE)) {
                /* Wait */
        }
        while (XAxiDma_Busy(&AxiDma,XAXIDMA_DEVICE_TO_DMA)) {
                /* Wait */
        }

        Status = CheckData();
        if (Status != XST_SUCCESS) {
            return XST_FAILURE;
        }

    }

    /* Test finishes successfully
     */
    return XST_SUCCESS;
}



/*****************************************************************************/
/*
*
* This function checks data buffer after the DMA transfer is finished.
*
* @param    None
*
* @return
*        - XST_SUCCESS if validation is successful.
*        - XST_FAILURE otherwise.
*
* @note        None.
*
******************************************************************************/
static int CheckData(void)
{
    u32 *RxPacket;
    int Index = 0;

    RxPacket = (u32 *) RX_BUFFER_BASE;

    /* Invalidate the DestBuffer before receiving the data, in case the
     * Data Cache is enabled
     */
    Xil_DCacheInvalidateRange((u32)RxPacket, MAX_PKT_LEN);

    xil_printf("Data received: ");
    for(Index = 0; Index < MAX_PKT_LEN_WORDS; Index++) {
        xil_printf("0x%X ", (unsigned int)RxPacket[Index]);
    }
    xil_printf("\r\n");

    return XST_SUCCESS;
}


Сообщение отредактировал Nivovod - Mar 6 2018, 06:32
Эскизы прикрепленных изображений
Прикрепленное изображение
Прикрепленное изображение
Прикрепленное изображение
Прикрепленное изображение


Прикрепленное изображение
Прикрепленное изображение
Прикрепленное изображение
Прикрепленное изображение


Прикрепленное изображение
Прикрепленное изображение
Прикрепленное изображение
Прикрепленное изображение


Прикрепленное изображение
Прикрепленное изображение
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 25th July 2025 - 22:04
Рейтинг@Mail.ru


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