Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: AXI VDMA & Ethernet(lwip)
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Системы на ПЛИС - System on a Programmable Chip (SoPC)
AntLip
Добрый день!
Делаю проект на 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. Может кто сказать разницу в этих способах настройки прерываний? Как сделать что бы все работало по прерываниям?
Спасибо за внимание!
sheynmanyu
Цитата(AntLip @ Jun 1 2018, 08:32) *
Делаю проект на Zynq, в проекте есть два VDMA(инициализированы и настроены по примеру в SDK) и ethernet (lwip, echo сервер ).
Проблема заключается в том, что когда настроены и разрешены прерывания VDMA, не работает прием пакетов ethernet ( а очень надо!)) ).
Решение у меня есть, но оно мне не нравиться, так как картинка идет менее качественная (субъективно видео чуть запаздывает). Я отключаю прерывания на VDMA и обрабатываю все в главном цикле. (Мне кажется, что это неправильно)
Подскажите как правильно настроить прерывания в проекте, что бы все работало вместе.


Здравствуйте!
Чисто из общих соображений:
1. приоритеты прерываний выставить/поменять можно?
2. А Вы очищаете в статус регистре VDMA бит о том, что произошло прерывание? Не получается ли так, что функция обработки прерываний от VDMA вызывается несколько раз?
AntLip
1. Приоритеты выставить можно, более того, я это делал. все равно при приходе первого сообщения из ethernet работа VDMA прерывается.
2. Да, флаг прерывания я сбрасываю.

Спасибо за ответ.
sheynmanyu
А через какой порт у Вас подключен 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.
AntLip
Приведенный выще код для ethernet и есть из примера lwip. Обработку для приема я переписал.
У меня было похожее с UART, но (как ни странно) проблема ушла тогда, когда я поставил объявление прерываний UART между инициализацией прерываний ethernet и их разрешением, дальше разбираться я не стал.
Если ставить в то же место инициализацию для VDMA, прерывания VDMA работают до момента прихода первого сообщения из ethernet, дальше прерывания от VDMA перестают работать, но сообщения от ethernet обрабатываются нормально. Я не до конца понимаю одну вещь, как мне кажется. Перед разрешением прерываний в ethernet, настраивается XScuTimer,а после к нему привязывают XPAR_SCUGIC_SINGLE_DEVICE_ID. И инициализация с помощью XScuGic_DeviceInitialize, а не XScuTimer_LookupConfig -> XScuTimer_CfgInitialize. Может в этом есть нюанс.
Ниже прикреплен Design



Спасибо за помощь!
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.