Memory Allocation Fails on FreeRTOS_Socket Call

I’m looking through the Zynq specific code and see this:

main() calls
  pxZynq_FillInterfaceDescriptor() which calls
    xZynqNetworkInterfaceInitialise() which creates task
      prvEMACHandlerTask() which has the following code in an infinite loop
        if( ( pxEMAC_PS->isr_events & EMAC_IF_ALL_EVENT ) == 0 ) {
          /* No events to process now, wait for the next. */
          ulTaskNotifyTake( pdFALSE, ulMaxBlockTime );
        }

        if( ( pxEMAC_PS->isr_events & EMAC_IF_RX_EVENT ) != 0 ) {
            pxEMAC_PS->isr_events &= ~EMAC_IF_RX_EVENT;
            xResult = emacps_check_rx( pxEMAC_PS, pxMyInterfaces[ xEMACIndex ] );
        }

        if( ( pxEMAC_PS->isr_events & EMAC_IF_TX_EVENT ) != 0 ) {
            pxEMAC_PS->isr_events &= ~EMAC_IF_TX_EVENT;
            emacps_check_tx( pxEMAC_PS );
        }

        if( ( pxEMAC_PS->isr_events & EMAC_IF_ERR_EVENT ) != 0 ) {
            pxEMAC_PS->isr_events &= ~EMAC_IF_ERR_EVENT;
            emacps_check_errors( pxEMAC_PS );
        }

This seems to imply that EMAC_IF_RX_EVENT should be triggered on a RX event. I never see this. All I ever get is EMAC_IF_ALL_EVENT which implies nothing to process.

It might be possible to find an eval board that is close enough.

Well, I’ve been going through a lot of the code for this and I’m still not getting this to work.

I’ve traced through many functions and I see the MAC and PHY registers getting initialized.

However, there is a function called XEmacPs_IntrHandler() which is the master interrupt handler which never gets executed. There is a comment here that states:

* Master interrupt handler for EMAC driver. This routine will query the
* status of the device, bump statistics, and invoke user callbacks.
*
* This routine must be connected to an interrupt controller using OS/BSP
* specific methods.

The second statement about the BSP specific methods confuses me. What does this mean? How do I connect this?

Do you see a refernce to this ISR in your IVT?

I’m not sure how to read the elf file, but I found this section which I think is the right one:

          _vector_table:
00100000:   b       0x1000c4 <_prestart>
00100004:   b       0x100040 <FreeRTOS_Undefined>
00100008:   ldr     pc, [pc, #20]   ; 0x100024 <_swi>
0010000c:   b       0x100080 <FreeRTOS_PrefetchAbortHandler>
00100010:   b       0x100060 <FreeRTOS_DataAbortHandler>
00100014:   nop     {0}
00100018:   ldr     pc, [pc]        ; 0x100020 <_irq>
0010001c:   b       0x100030 <FreeRTOS_FIQHandler>
          _irq:
00100020:   andseq  r12, r3, r0, ror #14
          _swi:
00100024:   andseq  r12, r3, r0, asr r6
00100028:   andeq   r0, r0, r0
0010002c:   andeq   r0, r0, r0
          FreeRTOS_FIQHandler:
00100030:   push    {r0, r1, r2, r3, r12, lr}
          FIQLoop:
00100034:   bl      0x14852c <FIQInterrupt>
00100038:   pop     {r0, r1, r2, r3, r12, lr}
0010003c:   subs    pc, lr, #4
          FreeRTOS_Undefined:
00100040:   push    {r0, r1, r2, r3, r12, lr}
00100044:   ldr     r0, [pc, #104]  ; 0x1000b4 <vPortInstallFreeRTOSVectorTable+20>
00100048:   sub     r1, lr, #4
0010004c:   str     r1, [r0]
00100050:   bl      0x148554 <UndefinedException>
00100054:   pop     {r0, r1, r2, r3, r12, lr}
00100058:   movs    pc, lr
0010005c:   andeq   r0, r0, r0
          FreeRTOS_DataAbortHandler:
00100060:   dsb     sy
00100064:   push    {r0, r1, r2, r3, r12, lr}
00100068:   ldr     r0, [pc, #72]   ; 0x1000b8 <vPortInstallFreeRTOSVectorTable+24>
0010006c:   sub     r1, lr, #8
00100070:   str     r1, [r0]
00100074:   bl      0x14857c <DataAbortInterrupt>
00100078:   pop     {r0, r1, r2, r3, r12, lr}
0010007c:   subs    pc, lr, #4
          FreeRTOS_PrefetchAbortHandler:
00100080:   dsb     sy
00100084:   push    {r0, r1, r2, r3, r12, lr}
00100088:   ldr     r0, [pc, #44]   ; 0x1000bc <vPortInstallFreeRTOSVectorTable+28>
0010008c:   sub     r1, lr, #4
00100090:   str     r1, [r0]
00100094:   bl      0x148590 <PrefetchAbortInterrupt>
00100098:   pop     {r0, r1, r2, r3, r12, lr}
0010009c:   subs    pc, lr, #4
          vPortInstallFreeRTOSVectorTable:
001000a0:   ldr     r0, [pc, #24]   ; 0x1000c0 <vPortInstallFreeRTOSVectorTable+32>
001000a4:   mcr     15, 0, r0, cr12, cr0, {0}
001000a8:   dsb     sy
001000ac:   isb     sy
001000b0:   bx      lr
001000b4:   subeq   lr, r0, r8, ror #20
001000b8:   subeq   lr, r0, r0, ror r10
001000bc:   subeq   lr, r0, r12, ror #20
001000c0:   andseq  r0, r0, r0
          _prestart:
001000c4:   mrc     15, 0, r1, cr0, cr0, {5}
001000c8:   and     r1, r1, #15
001000cc:   cmp     r1, #0
001000d0:   beq     0x1000dc <CheckEFUSE>
          EndlessLoop0:
001000d4:   wfe     
001000d8:   b       0x1000d4 <EndlessLoop0>
          CheckEFUSE:
001000dc:   ldr     r0, [pc, #748]  ; 0x1003d0 <finished+20>
001000e0:   ldr     r1, [r0]
163               ands r1,r1,#0x80                        /* Check whether device is having single core */
001000e4:   ands    r1, r1, #128    ; 0x80
164       	beq OKToRun
001000e8:   beq     0x100114 <OKToRun>
167               ldr     r0,=SLCRUnlockReg               /* Load SLCR base address base + unlock register */
001000ec:   ldr     r0, [pc, #736]  ; 0x1003d4 <finished+24>
168               ldr     r1,=SLCRUnlockKey               /* set unlock key */
001000f0:   ldr     r1, [pc, #736]  ; 0x1003d8 <finished+28>
169               str     r1, [r0]                        /* Unlock SLCR */
001000f4:   str     r1, [r0]
171       	ldr r0,=SLCRCPURSTReg
001000f8:   ldr     r0, [pc, #732]  ; 0x1003dc <finished+32>
172       	ldr r1,[r0]                             /* Read CPU Software Reset Control register */
001000fc:   ldr     r1, [r0]
173       	orr r1,r1,#0x22
00100100:   orr     r1, r1, #34     ; 0x22
174               str r1,[r0]                             /* Reset CPU1 */
00100104:   str     r1, [r0]
176               ldr	r0,=SLCRlockReg         	/* Load SLCR base address base + lock register */
00100108:   ldr     r0, [pc, #720]  ; 0x1003e0 <finished+36>
177       	ldr	r1,=SLCRlockKey	        	/* set lock key */
0010010c:   ldr     r1, [pc, #720]  ; 0x1003e4 <finished+40>
178       	str	r1, [r0]	        	/* lock SLCR */
00100110:   str     r1, [r0]

This is very specific to your vendor and not related to FreeRTOS - you are likely to get better answers on Xilinx forums.

Search your source code base for _vector_table. Typically there is a .asm or .c file named vectors.asm/.c (or startup.c/.am) that contains this section. That file should be made up of a long list of function entry points to which your IVT entries map. Check whether there is an entry to XEmacPs_IntrHandler() to it. You need to check with your MCU reference manual at which offset in the table your network ISR is located and figure out whether that entry will eventually invoke your XEmacPs_IntrHandler() or points to some default ISR.

I put a post on the Xilinx forum about this. Hopefully, I’ll get a response.

As far as the files, I found vectors.c:

/**
* @file vectors.c
*
* This file contains the C level vectors for the ARM Cortex A9 core.
*
******************************************************************************/
/***************************** Include Files *********************************/

#include "xil_exception.h"
#include "vectors.h"

/************************** Constant Definitions *****************************/

/**************************** Type Definitions *******************************/

/***************** Macros (Inline Functions) Definitions *********************/

/************************** Variable Definitions *****************************/

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


/*****************************************************************************/
/**
*
* This is the C level wrapper for the FIQ interrupt called from the vectors.s
* file.
*
* @return	None.
*
******************************************************************************/
void FIQInterrupt(void)
{
	XExc_VectorTable[XIL_EXCEPTION_ID_FIQ_INT].Handler(XExc_VectorTable[
					XIL_EXCEPTION_ID_FIQ_INT].Data);
}

/*****************************************************************************/
/**
*
* This is the C level wrapper for the IRQ interrupt called from the vectors.s
* file.
*
* @return	None.
*
******************************************************************************/
void IRQInterrupt(void)
{
	XExc_VectorTable[XIL_EXCEPTION_ID_IRQ_INT].Handler(XExc_VectorTable[
					XIL_EXCEPTION_ID_IRQ_INT].Data);
}

#if !defined (__aarch64__)
/*****************************************************************************/
/**
*
* This is the C level wrapper for the Undefined exception called from the
* vectors.s file.
*
* @return	None.
*
******************************************************************************/
void UndefinedException(void)
{
	XExc_VectorTable[XIL_EXCEPTION_ID_UNDEFINED_INT].Handler(XExc_VectorTable[
					XIL_EXCEPTION_ID_UNDEFINED_INT].Data);
}

/*****************************************************************************/
/**
*
* This is the C level wrapper for the SW Interrupt called from the vectors.s
* file.
*
* @return	None.
*
******************************************************************************/
void SWInterrupt(void)
{
	XExc_VectorTable[XIL_EXCEPTION_ID_SWI_INT].Handler(XExc_VectorTable[
					XIL_EXCEPTION_ID_SWI_INT].Data);
}

/*****************************************************************************/
/**
*
* This is the C level wrapper for the DataAbort Interrupt called from the
* vectors.s file.
*
* @return	None.
*
******************************************************************************/
void DataAbortInterrupt(void)
{
	XExc_VectorTable[XIL_EXCEPTION_ID_DATA_ABORT_INT].Handler(
		XExc_VectorTable[XIL_EXCEPTION_ID_DATA_ABORT_INT].Data);
}

/*****************************************************************************/
/**
*
* This is the C level wrapper for the PrefetchAbort Interrupt called from the
* vectors.s file.
*
* @return	None.
*
******************************************************************************/
void PrefetchAbortInterrupt(void)
{
	XExc_VectorTable[XIL_EXCEPTION_ID_PREFETCH_ABORT_INT].Handler(
		XExc_VectorTable[XIL_EXCEPTION_ID_PREFETCH_ABORT_INT].Data);
}
#else

/*****************************************************************************/
/**
*
* This is the C level wrapper for the Synchronous Interrupt called from the vectors.s
* file.
*
* @return	None.
*
******************************************************************************/
void SynchronousInterrupt(void)
{
	XExc_VectorTable[XIL_EXCEPTION_ID_SYNC_INT].Handler(XExc_VectorTable[
					XIL_EXCEPTION_ID_SYNC_INT].Data);
}

/*****************************************************************************/
/**
*
* This is the C level wrapper for the SError Interrupt called from the
* vectors.s file.
*
* @return	None.
*
******************************************************************************/
void SErrorInterrupt(void)
{
	XExc_VectorTable[XIL_EXCEPTION_ID_SERROR_ABORT_INT].Handler(
		XExc_VectorTable[XIL_EXCEPTION_ID_SERROR_ABORT_INT].Data);
}

#endif

I also found asm_vectors.S:

/******************************************************************************
* Copyright (c) 2009 - 2021 Xilinx, Inc.  All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/

/*****************************************************************************/
/**
* @file vectors.c
*
* This file contains the C level vectors for the ARM Cortex A9 core.
*
******************************************************************************/
/***************************** Include Files *********************************/

#include "xil_exception.h"
#include "vectors.h"

/************************** Constant Definitions *****************************/

/**************************** Type Definitions *******************************/

/***************** Macros (Inline Functions) Definitions *********************/

/************************** Variable Definitions *****************************/

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


/*****************************************************************************/
/**
*
* This is the C level wrapper for the FIQ interrupt called from the vectors.s
* file.
*
* @return	None.
*
******************************************************************************/
void FIQInterrupt(void)
{
	XExc_VectorTable[XIL_EXCEPTION_ID_FIQ_INT].Handler(XExc_VectorTable[
					XIL_EXCEPTION_ID_FIQ_INT].Data);
}

/*****************************************************************************/
/**
*
* This is the C level wrapper for the IRQ interrupt called from the vectors.s
* file.
*
* @return	None.
*
******************************************************************************/
void IRQInterrupt(void)
{
	XExc_VectorTable[XIL_EXCEPTION_ID_IRQ_INT].Handler(XExc_VectorTable[
					XIL_EXCEPTION_ID_IRQ_INT].Data);
}

#if !defined (__aarch64__)
/*****************************************************************************/
/**
*
* This is the C level wrapper for the Undefined exception called from the
* vectors.s file.
*
* @return	None.
*
******************************************************************************/
void UndefinedException(void)
{
	XExc_VectorTable[XIL_EXCEPTION_ID_UNDEFINED_INT].Handler(XExc_VectorTable[
					XIL_EXCEPTION_ID_UNDEFINED_INT].Data);
}

/*****************************************************************************/
/**
*
* This is the C level wrapper for the SW Interrupt called from the vectors.s
* file.
*
* @return	None.
*
******************************************************************************/
void SWInterrupt(void)
{
	XExc_VectorTable[XIL_EXCEPTION_ID_SWI_INT].Handler(XExc_VectorTable[
					XIL_EXCEPTION_ID_SWI_INT].Data);
}

/*****************************************************************************/
/**
*
* This is the C level wrapper for the DataAbort Interrupt called from the
* vectors.s file.
*
* @return	None.
*
******************************************************************************/
void DataAbortInterrupt(void)
{
	XExc_VectorTable[XIL_EXCEPTION_ID_DATA_ABORT_INT].Handler(
		XExc_VectorTable[XIL_EXCEPTION_ID_DATA_ABORT_INT].Data);
}

/*****************************************************************************/
/**
*
* This is the C level wrapper for the PrefetchAbort Interrupt called from the
* vectors.s file.
*
* @return	None.
*
******************************************************************************/
void PrefetchAbortInterrupt(void)
{
	XExc_VectorTable[XIL_EXCEPTION_ID_PREFETCH_ABORT_INT].Handler(
		XExc_VectorTable[XIL_EXCEPTION_ID_PREFETCH_ABORT_INT].Data);
}
#else

/*****************************************************************************/
/**
*
* This is the C level wrapper for the Synchronous Interrupt called from the vectors.s
* file.
*
* @return	None.
*
******************************************************************************/
void SynchronousInterrupt(void)
{
	XExc_VectorTable[XIL_EXCEPTION_ID_SYNC_INT].Handler(XExc_VectorTable[
					XIL_EXCEPTION_ID_SYNC_INT].Data);
}

/*****************************************************************************/
/**
*
* This is the C level wrapper for the SError Interrupt called from the
* vectors.s file.
*
* @return	None.
*
******************************************************************************/
void SErrorInterrupt(void)
{
	XExc_VectorTable[XIL_EXCEPTION_ID_SERROR_ABORT_INT].Handler(
		XExc_VectorTable[XIL_EXCEPTION_ID_SERROR_ABORT_INT].Data);
}

#endif

No mention of XEmacPs_IntrHandler().

I’m thinking now that I need to call function XScuGic_Connect() to connect the GEM0 interrupt to the controller like I’ve done to my other PL interrupts.

The function looks like this:

/*****************************************************************************/
/**
*
* Makes the connection between the Int_Id of the interrupt source and the
* associated handler that is to run when the interrupt is recognized. The
* argument provided in this call as the Callbackref is used as the argument
* for the handler when it is called.
*
* @param	InstancePtr is a pointer to the XScuGic instance.
* @param	Int_Id contains the ID of the interrupt source and should be
*		in the range of 0 to XSCUGIC_MAX_NUM_INTR_INPUTS - 1
* @param	Handler to the handler for that interrupt.
* @param	CallBackRef is the callback reference, usually the instance
*		pointer of the connecting driver.
*
* @return
*
*		- XST_SUCCESS if the handler was connected correctly.
*
* @note
*
* WARNING: The handler provided as an argument will overwrite any handler
* that was previously connected.
*
****************************************************************************/
s32  XScuGic_Connect(XScuGic *InstancePtr, u32 Int_Id,
				Xil_InterruptHandler Handler, void *CallBackRef)

This function “void XEmacPs_IntrHandler(void *XEmacPsPtr)” should get called when the interrupt gets triggered.

I want to do this:

	Status = XScuGic_Connect(&xInterruptController, XPS_GEM0_INT_ID,
			(Xil_ExceptionHandler)XEmacPs_IntrHandler, (void *)XEmacPsPtr);

I’m not sure what XEmacPsPtr is? I have it set to NULL in my other interrupts.

Any help?

RTM? Should be documented by Xilinx, methinks.

Getting a little farther now.

I added this:

Status = XScuGic_Connect(&xInterruptController, XPS_GEM0_INT_ID,
  (Xil_ExceptionHandler)XEmacPs_IntrHandler, (void *)&xInterruptController);

And then I added this to enable the interrupt:

XScuGic_Enable(&xInterruptController, XPS_GEM0_INT_ID);

So now I’m getting the interrupt and XEmacPs_IntrHandler is getting called, but the second assert is failing. I think the last parameter in the XScuGic_Connect() function is wrong:

void XEmacPs_IntrHandler(void *XEmacPsPtr)
{
	u32 RegISR;
	u32 RegSR;
	u32 RegCtrl;
	u32 RegQ1ISR = 0U;
	XEmacPs *InstancePtr = (XEmacPs *) XEmacPsPtr;

	Xil_AssertVoid(InstancePtr != NULL);
	Xil_AssertVoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);  <= this fails
...

I seem to be at a standstill and haven’t made any progress.

Is there paid support available?

Have you tried contacting Xilinx? Your questions target their platform rather than FreeRTOS.

I normally offer consultancy for these kinds of things but do not currently have capacity, sorry…

Yes, they have very limited responses.