Zync UDP/TCP with DMA IP

I am attempting to use FreeRTOS on the Zynq platform to build an application that uses AXI Dma to transfer data from the Zynq fabric to the Zynq processor. Then process the data and use TCP to transfer the processed data to the real world. Just to be clear I am new to the FreeRTOS environment. I made the following steps to get to where I am now to be sure I understand each step. 1) Made an application that would get Dma interrupts from data generated in the Zynq fabric. The application did not use FreeRTOS, it was just a bare metal application that got the interrupts and looked at the data to be sure I got the correct amount and correct values. 2) Made an application that implemented the blinky demo and used the FreeRTOS labs UDP demo to write messages. From this I know I can write messages to the UDP terminal from a basic Zynq application. No great accomplishment. 3) I then made several attempts to merge the DMA application into the UDP/Blinky application and I seem to be unable to get the DMA interrupt to fire. In the DMA Handler I simply write to the UDP server that the interrupt was processed. The Zynq hardware is setup to generate one single interrupt, thats what it does in the first application, but I can’t seem get it to fire in the combined version. I can post the combined hardware setup if it might help. The difference between the UDP/Blinky application and the UDP/Blinky/DMA is that the DMA requires memory to be reserved and I can’t yet see where FreeRTOS allows for the block of memory to be blocked . I have two devices in the Zynq fabric and maybe this is causing my problem, I suspect not but just want to be understand better. Is there a way to mask these segments from FreeRTOS? ~~~ #define XPARCCMAXIREGISTER0DEVICEID 0 #define XPARCCMAXIREGISTER0S00AXIBASEADDR 0x43C00000 #define XPARCCMAXIREGISTER0S00AXIHIGHADDR 0x43C0FFFF
#define XPAR_AXI_DMA_0_DEVICE_ID 0
#define XPAR_AXI_DMA_0_BASEADDR 0x40400000
#define XPAR_AXI_DMA_0_HIGHADDR 0x4040FFFF
~~~

Zync UDP/TCP with DMA IP

It is not clear to me why you wouldn’t get DMA interrupts in the merged application. I’m afraid I can not help you with device specific settings such as XPAR_CCMAXIREGISTER_0_xxx and XPAR_AXI_DMA_0_xxx. Note that DMA and memory caching aren’t friends. Before passing memory to the DMA controller, you have to flush the memory, and after reading to cached memory, you’ll have to refresh it. In the FreeRTOS+TCP driver for Zynq, it was decided to reserve 1 MB of SDRAM as uncached memory (see src/uncached_memory.c). Depending on the size that you need, you might want to call:
uint8_t *pucGetUncachedMemory( uint32_t ulSize );
and get a chunk of aligned / uncached memory. +TCP is also using DMA. What happens if you don’t initialise the stack, i.e. never call FreeRTOS_IPInit()? Do you get your DMA interrupt?
In the DMA Handler I simply write to the UDP server that the interrupt was processed
If this DMA Handler is called as an interrupt, it is likely to get into trouble. FreeRTOS+TCP API’s may only be called from within a normal task code, not from an interrupt context (with the exception of a few fromISR() functions). When using FreeRTOS (+TCP), I would let the DMA handler send a message, or give to a semaphore, or notify a task: ~~~~ xQueueSendFromISR() xSemaphoreGiveFromISR() xTaskNotifyFromISR() ~~~~ Immediately after the interrupt is finished, the DMA-handling task will wake-up on either: ~~~~ xQueueReceive() xSemaphoreTake() xTaskNotifyWait() ~~~~ Please define “configASSERT_DEFINED = 1” while testing. See the comments in vPortValidateInterruptPriority() in portable/GCC/ARM_CA9/port.c for an explanation why. Regards.

Zync UDP/TCP with DMA IP

I no onger think the storage allocated for the Zynq IP is an issue. I think the issue is all in allocating the memory shared with the interrupt controller. I changed the size of the uncached memory in uncached_memory and use uint8t *pucGetUncachedMemory( uint32t ulSize ); to allocate the BdRing , I saw what you did in the TCP stack and tried to mimick it. A real issue is I broke the USB port on the board and was hoping I could use it a little while longer before I have to replace it. I am a contractor and will have to pay for it in advance. I can’t see any output except from the UDP server. I will try using a queue or task notification to test the interrupt. I do appreciate your help. Thank you.

Zync UDP/TCP with DMA IP

broke the USB port on the board I am a contractor and will have to pay for it in advance
I’m sorry to hear that. The USB connector is indeed very delicate. How do you put new firmware on your device? With an SD-card? Can’t you ask your boss for a replacement print? That may be a lot quicker and therefore cheaper 🙂 Do you have UDPLoggingPrintf.c working? It starts a low-priority task that collects logging lines and sends them as UDP messages to a predefined IP-address and port. Every log-line is preceded by a timestamp with uS precision, such as: ~~~~ 0.000.599 [SvrWork] prvServerWorkTask: Creating files 0.000.732 [SvrWork] Mount SD-card 0.001.491 [SvrWork] SD card V2 0.006.225 [SvrWork] sddecodecsd: speed 25000000 0.008.282 [SvrWork] 4-bit bus width enabled. 0.009.688 [SvrWork] SD/MMC card ready ~~~~ Note that lUDPLoggingPrintf() may not be called from an interrupt context. The standard gcc s[v][n]printf() functions also cause problems when called from an interrupt. If you use a later version of printf-stdarg.c (>= 160112), s[v][n]printf() is interrupt-safe. Regards.

Zync UDP/TCP with DMA IP

I use a Digilent JTAG HS3 Program Cable, I need to write to the Zynq fabric as well. I didn’t think I could write to the fabric over the serial port. I am using UDPLogginePrintf as my only debus aid in the PS. I can debug the PLwith JTAG and ILA IP. You probably hit the problem on the head, :). I got in a mode where I just replaces Xil_printf with the Logging printf and that was how I knew it worked before. Not sure I know where my brain was on that one 🙁

Zync UDP/TCP with DMA IP

I now have a better idea of what is going on. I took the blinky task ans slowed it down and added a UDP log print so every second the application would report it is still alive. When I exercise the hardware to initiate an interrupt it seems the application has crashed. There are no more blinky messages to the UDP server. All I want to know here is if I have the correct idea, if I am thinking about this correctly. I think the issue is allocation memory for the BD’s and the buffer. I tried to keep it as clost to tha application that worked to eliminate too many options. In the application that worked, the BD’s and the Buffer were allocated in memory as: ~~~

define MEMBASEADDR 0x01000000

// BD space

define BDSPACEBASE (MEMBASEADDR)

define BDSPACEHIGH (MEMBASEADDR + 0x0000FFFF)

// Buffer space

define BUFFERBASE (MEMBASE_ADDR + 0x00100000)

define BUFFERHIGH (MEMBASE_ADDR + 0x002FFFFF)

~~~ memory was taken up to 0x00300000; First I changed uncashed_memory.c to include this space: ~~~ //#define UNCACHEDMEMORYSIZE 0x00100000ul

define UNCACHEDMEMORYSIZE 0x00300000ul

~~~ And I changed the allocation for the BD space to be: ~~~ UBaseTypet pBDSize = BDSPACEHIGH – BDSPACEBASE + 1; UINTPTR pBDSpace = ( UINTPTR )( pucGetUncachedMemory ( pBDSize ) ); FreeRTOSprintf((“Bd allocate %x, %xrn”, pBDSize, pBDSpace)); ~~~ and the output for this is: 10000, 423000 I allocated the buffer as a static array of size 0x0200000 which is the same as the size of the original buffer and it still doesn’t work. I assume something is going on before I get the network to come up, or the errors are written to the serial port and will have to wait until I get a device with the USB connector.

Zync UDP/TCP with DMA IP

Hi! I am trying to achieve the same thing and my DMA interrupt never comes. I have my bare metal software working but I am trying to migrate the DMA transfer to the FreeRTOS. Do you get it working? Thank you! Kind Regards Kin