Memory Allocation Fails on FreeRTOS_Socket Call

Per request, I’ve started a new thread to discuss this issue I’ve been having. This is for a Zynq PicoZed 7030 project using Vitis.

In a nutshell, this function calls fails:
xListeningSocket = FreeRTOS_socket( FREERTOS_AF_INET4, <== this call fails
FREERTOS_SOCK_STREAM , FREERTOS_IPPROTO_TCP );
configASSERT( xListeningSocket != FREERTOS_INVALID_SOCKET );

Based on the documentation, it seems this is because of insufficient heap memory.

I found heap size setting in the Board Support Package Settings. I changed it to 1M from 64k and recompiled, but I still get the same error.

I’m looking for configSUPPORT_DYNAMIC_ALLOCATION defines, but haven’t found it yet in Vitis. Which file would this be found it?

I declared this in my FreeRTOSIPConfig.h file:
#define configSUPPORT_DYNAMIC_ALLOCATION 1

Recompiling and rerunning this still gives my the error.

Can you step through the code and see why is it returningFREERTOS_INVALID_SOCKET? If it is because of this pvPortMallocSocket call, you need to find which FreeRTOS heap are you using and increase the heap size accordingly.

I’m not calling pvPortMallocSocket. Do I need to?

You do not need to call it but the function FreeRTOS_socket internally calls it. Can you look at the files in your project and find out which FreeRTOS heap are you using? Alternatively, share your complete project and we can look at that.

I stepped into the socket function and found this is failing:

    if( prvDetermineSocketSize( xDomain, xType, xProtocolCpy, &uxSocketSize ) == pdFAIL )
    {
        /* MISRA Ref 11.4.1 [Socket error and integer to pointer conversion] */
        /* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-114 */
        /* coverity[misra_c_2012_rule_11_4_violation] */
        xReturn = FREERTOS_INVALID_SOCKET;
        break;
    }

Variables:
xDomain = 2
xType = 1
xProtocolCpy = 6
uxSocketSize = 1

Thanks. Can you step into the prvDetermineSocketSize function as well and see where it is failing?

This is setting xReturn to false:

if( xIPIsNetworkTaskReady() == pdFALSE )
{
xReturn = pdFAIL;
}

Here’s that function call:

/**

  • @brief Returns whether the IP task is ready.
  • @return pdTRUE if IP task is ready, else pdFALSE.
    */
    BaseType_t xIPIsNetworkTaskReady( void )
    {
    return xIPTaskInitialised;
    }

Seems like xIPTaskInitialised is 0.

That likely means that you are trying to create too early. Can you do move the socket creation to after the eNetworkUp event like here - https://github.com/FreeRTOS/FreeRTOS/blob/main/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/main_networking.c#L214?

1 Like

I’m not sure what to call. Do you mean to call this:
vStartTCPEchoClientTasks_SingleTasks( mainECHO_CLIENT_TASK_STACK_SIZE, mainECHO_CLIENT_TASK_PRIORITY );

Here’s my FreeRTOSIPConfig.h file:


#ifndef FREERTOS_IP_CONFIG_H
#define FREERTOS_IP_CONFIG_H

#define ipconfigUSE_DHCP 0
#define ipconfigUSE_DHCPv6 0
#define ipconfigUSE_IPv4 1
#define ipconfigUSE_IPv6 0

#define ipconfigNETWORK_MTU 1526
#define ipconfigTCP_MSS 1460
#define ipconfigTCP_TX_BUFFER_LENGTH ( 16 * ipconfigTCP_MSS )
#define ipconfigTCP_RX_BUFFER_LENGTH ( 16 * ipconfigTCP_MSS )

#define ipconfigBYTE_ORDER pdFREERTOS_LITTLE_ENDIAN

#define ipconfigZERO_COPY_RX_DRIVER 1
#define ipconfigZERO_COPY_TX_DRIVER 1

#define ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM 1
#define ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM 1

#define ipconfigNIC_N_TX_DESC 4
#define ipconfigNIC_N_RX_DESC 64 // 64 correct?

#define ipconfigUSE_DNS 0

#endif // FREERTOS_IP_CONFIG_H

Here’s my sequence:

pxZynq_FillInterfaceDescriptor(0, &( xInterfaces[0]));

FreeRTOS_FillEndPoint( &( xInterfaces[ 0 ] ), &( xEndPoints[ 0 ] ), ucIPAddress,
ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress );

FreeRTOS_IPInit_Multi();

xListeningSocket = FreeRTOS_socket( FREERTOS_AF_INET4, <== this call fails
FREERTOS_SOCK_STREAM , FREERTOS_IPPROTO_TCP );
configASSERT( xListeningSocket != FREERTOS_INVALID_SOCKET );

Can you look at this example as I mentioned above - https://github.com/FreeRTOS/FreeRTOS/blob/main/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/main_networking.c?

After calling FreeRTOS_IPInit_Multi(); you need to start the scheduler by calling vTaskStartScheduler. And then the following function gets called with eNetworkEvent = eNetworkUp when the network is ready.

    void vApplicationIPNetworkEventHook_Multi( eIPCallbackEvent_t eNetworkEvent,
                                               struct xNetworkEndPoint * pxEndPoint )

If you try to read the file I linked above, you should be able to follow.

I’m trying to follow the code for main_tcp_echo_client_tasks().

I see on line 184, this: vTaskStartScheduler(), but I don’t see a sys_thread_new() call anywhere. What thread is being started?

Thanks.

sys_thread_new is not a FreeRTOS API. The FreeRTOS API to create a task is xTaskCreate. You can see a call to vStartTCPEchoClientTasks_SingleTasks which then calls xTaskCreate.

Thanks.

I see main is calling vTaskStartScheduler() before any tasks are created. I thought at least one task had to be created before starting the scheduler?

The comments in vApplicationIPNetworkEventHook_Multi() says this gets called when the network connects or disconnects. How does that work? In this function, I see a xTaskCreate() where creates task prvEchoClientTask() which has the FreeRTOS_socket call.

I’m trying to understand how this all works.

Thanks again!

FreeRTOS_IPInit_Multi will create IP task which then calls vApplicationIPNetworkEventHook_Multi when the network is connected.

Thanks. Yes, I see the flow now.

So, I’m calling these functions now. I had to define ipconfigNIC_LINKSPEED_AUTODETECT for proper initialization.

pxZynq_FillInterfaceDescriptor()
FreeRTOS_FillEndPoint()
FreeRTOS_IPInit_Multi()
xTaskCreate(prvIPTask) <== task created here
vTaskStartScheduler()

I see prvTask has a ipFOREVER() loop with prvProcessIPEventsAndTimers() inside. There is a bunch of event decoding going on in here:
eNetworkDownEvent <== this should only occur once when establishing connection
eNetworkRxEvent
eNetworkTxEvent
eARPTimerEvent
eSocketBindEvent
eSocketCloseEvent
eStackTxEvent
eDHCPEvent
eSocketSelectEvent
eSocketSignalEvent
eTCPTimerEvent
eTCPAcceptEvent
eTCPNetStat
eSocketSetDeleteEvent
eNoEvent

Debugging this, I see eNetworkDownEvent on the first pass only which I think is correct. I see a bunch of eNoEvent with an occasional eARPTimerEvent. Is this correct?

I don’t see my assigned IP address when looking at the attached devices on my router. Should I? When can I ping it?

Do I still need to call FreeRTOS_socket(), FreeRTOS_setsockopt(), FreeRTOS_bind(), etc?

You DO NOT need to call xTaskCreate(prvIPTask) - that happens in the call to FreeRTOS_IPInit_Multi.

Does the function vApplicationIPNetworkEventHook_Multi get called with network up event? If not, you need to debug that first.

Yes - you need to create a task from the vApplicationIPNetworkEventHook_Multi when you get network up event. That task then should call these functions.

Yes, eNoEvent will occur when the xQueueReceive call to IP task’s event queue times out. This timeout will enable the timers to be processed (vCheckNetworkTimers) without indefinetely waiting for an event if there isn’t any.

As mentioned by @aggarg in the previous post please check if the call to vApplicationIPNetworkEventHook_Multi is enabled by setting ipconfigUSE_NETWORK_EVENT_HOOK in the FreeRTOSIPConfig.h file and is getting called once the network is up.

Thanks to both of you for helping.

I don’t call xTaskCreate(). I know it gets called in FreeRTOS_IPInit_Multi(). I just listed it for my own and others.

I don’t see a network up event listed in prvProcessIPEvnetsAndTimers(). Only those listed in my previous email. Should there be one?

I added this line to FreeRTOSIPConfig.h:
#define ipconfigUSE_NETWORK_EVENT_HOOK 1

When I compile, I get an undefined error on vApplicationIPNetworkEventHook_Multi(). Do I need to create this?

Yes. See FreeRTOS IP stack vApplicationIPNetworkEventHook() API Reference