Перейти к содержанию
    

AXI VDMA & Ethernet(lwip)

Добрый день!

Делаю проект на Zynq, в проекте есть два VDMA(инициализированы и настроены по примеру в SDK) и ethernet (lwip, echo сервер ).

Проблема заключается в том, что когда настроены и разрешены прерывания VDMA, не работает прием пакетов ethernet ( а очень надо!)) ).

Решение у меня есть, но оно мне не нравиться, так как картинка идет менее качественная (субъективно видео чуть запаздывает). Я отключаю прерывания на VDMA и обрабатываю все в главном цикле. (Мне кажется, что это неправильно)

Подскажите как правильно настроить прерывания в проекте, что бы все работало вместе.

Код настройки прерываний VDMA

int SetupIntrSystem(XAxiVdma *AxiVdmaPtr,     u16 WriteIntrId)
{
    int Status;
    XScuGic *IntcInstancePtr = &Intc;    /* Instance of the Interrupt Controller */
    XScuGic_Config *IntcConfig;
    IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
    if (NULL == IntcConfig) {
        return XST_FAILURE;
    }
    Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,
                    IntcConfig->CpuBaseAddress);
    if (Status != XST_SUCCESS) {
        return XST_FAILURE;
    }
    XScuGic_SetPriorityTriggerType(IntcInstancePtr, WriteIntrId, 0xA0, 0x3);
    Status = XScuGic_Connect(IntcInstancePtr, WriteIntrId,
                (Xil_InterruptHandler)XAxiVdma_WriteIntrHandler,
                AxiVdmaPtr);
    if (Status != XST_SUCCESS) {
        return Status;
    }
    XScuGic_Enable(IntcInstancePtr, WriteIntrId);
    Xil_ExceptionInit();
    Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,
                (Xil_ExceptionHandler)XScuGic_InterruptHandler,
                IntcInstancePtr);    
    Xil_ExceptionEnable();
    XAxiVdma_SetCallBack(&AxiVdma_1, XAXIVDMA_HANDLER_GENERAL,
            WriteCallBack_1, (void *)&AxiVdma_1, XAXIVDMA_WRITE);
        XAxiVdma_SetCallBack(&AxiVdma_1, XAXIVDMA_HANDLER_ERROR,
            WriteErrorCallBack_1, (void *)&AxiVdma_1, XAXIVDMA_WRITE);
        XAxiVdma_IntrEnable(&AxiVdma_1, XAXIVDMA_IXR_ALL_MASK, XAXIVDMA_WRITE);


}

Прерывания для ethernet

Xil_ExceptionInit();
    XScuGic_DeviceInitialize(INTC_DEVICE_ID);
    Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,
            (Xil_ExceptionHandler)XScuGic_DeviceInterruptHandler,
            (void *)INTC_DEVICE_ID);
    XScuGic_RegisterHandler(INTC_BASE_ADDR, TIMER_IRPT_INTR,
                    (Xil_ExceptionHandler)timer_callback,
                    (void *)&TimerInstance);
    XScuGic_EnableIntr(INTC_DIST_BASE_ADDR, TIMER_IRPT_INTR); 
        Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ);
    XScuTimer_EnableInterrupt(&TimerInstance);
    XScuTimer_Start(&TimerInstance);

Так же я настаивал прерывания при помощи других функций, по примеру VDMA. Может кто сказать разницу в этих способах настройки прерываний? Как сделать что бы все работало по прерываниям?

Спасибо за внимание!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Делаю проект на Zynq, в проекте есть два VDMA(инициализированы и настроены по примеру в SDK) и ethernet (lwip, echo сервер ).

Проблема заключается в том, что когда настроены и разрешены прерывания VDMA, не работает прием пакетов ethernet ( а очень надо!)) ).

Решение у меня есть, но оно мне не нравиться, так как картинка идет менее качественная (субъективно видео чуть запаздывает). Я отключаю прерывания на VDMA и обрабатываю все в главном цикле. (Мне кажется, что это неправильно)

Подскажите как правильно настроить прерывания в проекте, что бы все работало вместе.

 

Здравствуйте!

Чисто из общих соображений:

1. приоритеты прерываний выставить/поменять можно?

2. А Вы очищаете в статус регистре VDMA бит о том, что произошло прерывание? Не получается ли так, что функция обработки прерываний от VDMA вызывается несколько раз?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1. Приоритеты выставить можно, более того, я это делал. все равно при приходе первого сообщения из ethernet работа VDMA прерывается.

2. Да, флаг прерывания я сбрасываю.

 

Спасибо за ответ.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А через какой порт у Вас подключен VDMA? Как выглядит дизайн?

Из предыдущих постов я так и не поняла, при настройке других прерываний ситуация с отваливанием VDMA повторяется?

А Вы часом не перезаписываете включенные прерывания? Не получается ли так, что Вы отключаете одни и включаете другие?

 

Я включала одновременно обработку прерываний от таймера и AXI DMA:

 
static XScuGic_Config *GicConfig;
XScuGic InterruptController;

int SetUpInterruptSystem(XScuGic *XScuGicInstancePtr)
{
    Xil_ExceptionInit();
    Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT, (Xil_ExceptionHandler) XScuGic_InterruptHandler, XScuGicInstancePtr);
    return XST_SUCCESS;
}

int InitializeInterruptSystem (deviceID)
{
    int Status;
    GicConfig = XScuGic_LookupConfig(deviceID);
    if(NULL==GicConfig){
        return XST_FAILURE;
    }
    Status = XScuGic_CfgInitialize(&InterruptController, GicConfig, GicConfig->CpuBaseAddress);
    if(Status!=XST_SUCCESS){
        return XST_FAILURE;
    }
    Status = SetUpInterruptSystem(&InterruptController);
    if(Status!=XST_SUCCESS){
        return XST_FAILURE;
    }
    Status = XScuGic_Connect(&InterruptController, XPAR_FABRIC_AXI_DMA_0_S2MM_INTROUT_INTR,
            (Xil_ExceptionHandler) DMA_interrupt, NULL);
    if(Status!=XST_SUCCESS){
        return XST_FAILURE;
    }

    XScuGic_SetPriorityTriggerType(&InterruptController, START_INTR, 0x10, 0x3);  //rising edge
    if(XScuGic_Connect(&InterruptController, START_INTR,
        (Xil_ExceptionHandler) StartIntrHandler, NULL)!=XST_SUCCESS)
    {
        xil_printf(" XScuGic_Connect(&InterruptController, START_INTR) wasn't done!\n");
        return XST_FAILURE;
    }
    XScuGic_Enable(&InterruptController, XPAR_FABRIC_AXI_DMA_0_S2MM_INTROUT_INTR);
    XScuGic_Enable(&InterruptController, START_INTR);
    Xil_ExceptionEnable();
    return XST_SUCCESS;
}

А для lwIP я вообще воспользовалась готовым тестовым приложением, и в обработку таймеров вставила обработку пакетов... Но это было без AXI DMA IP.

 

Изменено пользователем sheynmanyu

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приведенный выще код для ethernet и есть из примера lwip. Обработку для приема я переписал.

У меня было похожее с UART, но (как ни странно) проблема ушла тогда, когда я поставил объявление прерываний UART между инициализацией прерываний ethernet и их разрешением, дальше разбираться я не стал.

Если ставить в то же место инициализацию для VDMA, прерывания VDMA работают до момента прихода первого сообщения из ethernet, дальше прерывания от VDMA перестают работать, но сообщения от ethernet обрабатываются нормально. Я не до конца понимаю одну вещь, как мне кажется. Перед разрешением прерываний в ethernet, настраивается XScuTimer,а после к нему привязывают XPAR_SCUGIC_SINGLE_DEVICE_ID. И инициализация с помощью XScuGic_DeviceInitialize, а не XScuTimer_LookupConfig -> XScuTimer_CfgInitialize. Может в этом есть нюанс.

Ниже прикреплен Design

 

 

 

Спасибо за помощь!

post-99927-1527927911_thumb.png

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...