AntLip 0 1 июня, 2018 Опубликовано 1 июня, 2018 · Жалоба Добрый день! Делаю проект на 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 0 1 июня, 2018 Опубликовано 1 июня, 2018 · Жалоба Делаю проект на Zynq, в проекте есть два VDMA(инициализированы и настроены по примеру в SDK) и ethernet (lwip, echo сервер ). Проблема заключается в том, что когда настроены и разрешены прерывания VDMA, не работает прием пакетов ethernet ( а очень надо!)) ). Решение у меня есть, но оно мне не нравиться, так как картинка идет менее качественная (субъективно видео чуть запаздывает). Я отключаю прерывания на VDMA и обрабатываю все в главном цикле. (Мне кажется, что это неправильно) Подскажите как правильно настроить прерывания в проекте, что бы все работало вместе. Здравствуйте! Чисто из общих соображений: 1. приоритеты прерываний выставить/поменять можно? 2. А Вы очищаете в статус регистре VDMA бит о том, что произошло прерывание? Не получается ли так, что функция обработки прерываний от VDMA вызывается несколько раз? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AntLip 0 1 июня, 2018 Опубликовано 1 июня, 2018 · Жалоба 1. Приоритеты выставить можно, более того, я это делал. все равно при приходе первого сообщения из ethernet работа VDMA прерывается. 2. Да, флаг прерывания я сбрасываю. Спасибо за ответ. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sheynmanyu 0 1 июня, 2018 Опубликовано 1 июня, 2018 (изменено) · Жалоба А через какой порт у Вас подключен 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. Изменено 1 июня, 2018 пользователем sheynmanyu Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AntLip 0 2 июня, 2018 Опубликовано 2 июня, 2018 · Жалоба Приведенный выще код для ethernet и есть из примера lwip. Обработку для приема я переписал. У меня было похожее с UART, но (как ни странно) проблема ушла тогда, когда я поставил объявление прерываний UART между инициализацией прерываний ethernet и их разрешением, дальше разбираться я не стал. Если ставить в то же место инициализацию для VDMA, прерывания VDMA работают до момента прихода первого сообщения из ethernet, дальше прерывания от VDMA перестают работать, но сообщения от ethernet обрабатываются нормально. Я не до конца понимаю одну вещь, как мне кажется. Перед разрешением прерываний в ethernet, настраивается XScuTimer,а после к нему привязывают XPAR_SCUGIC_SINGLE_DEVICE_ID. И инициализация с помощью XScuGic_DeviceInitialize, а не XScuTimer_LookupConfig -> XScuTimer_CfgInitialize. Может в этом есть нюанс. Ниже прикреплен Design Спасибо за помощь! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться