`vApplicationMallocFailedHook` getting triggered on FreeRTOS_send (Zynq 7000)

Hello,

I am trying to create a server socket on my Zynq 7000 dev board which can received packets from my PC and reply back. Here are my platform details:

Platform: Xilinx Zynq-7000 SoC on a Cora-Z7-10 development-kit.
OS: FreeRTOS 10+ port for Xilinx

I am successfully able to use FreeRTOS_recv and get data from the PC. But when I try to echo that data back, my program crashes and I see that the vApplicationMallocFailedHook function is triggering an assert. I believe this has something to do with my memory allocation and buffer sizes but I’m not sure what is causing the problem.

Here is a link to my Git repo that has my project in its current state.

I have also added the tcp_mem_stats tool to my project but have yet to figure out a way to get it to work.

Any help would be greatly appreciated.

Thank you,
Sid

You can increase the size of the heap - how that is done depends on the allocation scheme you are using https://www.freertos.org/a00111.html

You can also tune the RAM used by your buffers https://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_IP_Configuration_Examples.html or statically allocate your buffers https://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Ethernet_Buffer_Management.html

…but in all cases running out of heap should not be a critical error, but handled gracefully. The malloc failed hook is just a convenient notification that it happened.

The only way I have had success so far has been by disabling the ipconfigUSE_TCP_WIN flag. From my understanding, it is beneficial to use windowing so I am trying to get things to work with the flag enabled but am failing at it…

Windowing greatly increases throughput, because you can send packet 2 (or more) before waiting for the acknowledgment for packet 1, but it costs you memory, as you need to keep track of all the packets that have been sent and not yet acknowledged as you may need to resend them. It sounds like you haven’t given your heap enough memory.

1 Like

I have also added the tcp_mem_stats tool to my project
but have yet to figure out a way to get it to work.

In order to use memory statistics, you need a good logging channel, like e.g. a serial link.

The tools can be found here, as tcp_mem_stats.c. The MD file explains how to use it.
More in formation in this PR #1828.

Richard Damon wrote:

It sounds like you haven’t given your heap enough memory.

Could you attach both FreeRTOSConfig.h and FreeRTOSIPConfig.h files?

1 Like

So I found out what was happening with my heap allocation. It turns out, the Xilinx IDE, Vitis, creates multiple copies of the FreeRTOSConfig.h file. One of them lives with the auto-generated BSP, and the other lives in a separate include folder that is included in the project. The HeapSize needs to be configured in the BSP version of the file since that is where heap_4.c gets compiled. If I bump up the heap size there, things start working.

So Richard was right in saying that I had not given my heap enough memory. I was setting the variable in the wrong file.

This is very poorly done by Xilinx and I will be setting up a new project without making use of the auto BSP generation features.

My FreeRTOSConfig.h and IPConfig.h files can both be found here: https://gitlab.com/siddhantmodi/freertos-tcp-plus-test

Thank you,
Sid

Thanks for reporting back.

You are not the first person that faces the problem of multiple configuration files :frowning_face:

Now you can turn on ipconfigUSE_TCP_WIN again?

Mind you, the following defines set the default sizes for your TCP stream buffers:

#define ipconfigTCP_RX_BUFFER_LENGTH			( 0x4000 )
#define ipconfigTCP_TX_BUFFER_LENGTH			( 0x4000 )

That is 16KB in both directions, which is good.

If you need a high-speed TCP connection, e.g. when streaming video, you can set the properties in a sock option called FREERTOS_SO_WIN_PROPERTIES.

Hello Hein,

Do you know if there is any best known method to get around the multiple configuration files problem? My guess is that all I can do is set up my entire repo on my own and not rely on the IDE doing anything for me?

I set the heap size to 256 * 1024 and turned ipconfigUSE_TCP_WIN on again and everything worked fine.

Now the plan is to set up about 5 different servers on the board for 5 independent tasks. Do you think it is a good idea to have multiple servers running on different ports at the same time?

Thank you,
Sid

Do you know if there is any best known method to
get around the multiple configuration files problem?

( this is about FreeRTOSConfig.h and FreeRTOSIPConfig.h )

The best method, I think is to keep the config files in an include directory that is private to your project. And also make sure that there are no other config files stored in public directories.

I once did a search on my disk, and added the following line to each config file found: #error I should not be included.

My guess is that all I can do is set up my entire repo on
my own and not rely on the IDE doing anything for me?

Yes absolutely. Once you have a working project, I wouldn’t let the IDE “manage” the project.
Personally, I like Makefile projects, also when I work with Eclipse.

Do you think it is a good idea to have multiple servers
running on different ports at the same time?

Do you mean that you want to create 5 TCP-servers, each one with a different port number? Sure, why not?
Hein

Personally, I like Makefile projects, also when I work with Eclipse.

What do you mean exactly? You write your own Makefiles and then import them into Eclipse?
I would say I am a beginner when it comes to Makefiles. I can understand them for the most part when reading one but I have never created one from scratch. Do you use the automatically generated Makefiles from Eclipse as a template?

Thank you,
Sid

Once I looked up: “how to write a Linux device driver?”.

The answer was: don’t!

It was recommended to take an existing “similar” driver as an example and start from there. That would spare you lots of troubles.

Likewise, I once started with a good existing makefile and a config.mk. The makefile can be reused for any embedded GCC project, the config.mk is specific per project.

Within Eclipse, you can either let it generate makefiles for you, or let it call make with the makefile that you provide.

There is an option “import makefile project”.

1 Like

Hein is an expert and writes his own Makefiles :sunglasses: Hence he has full control about what’s built and how. So do I :slight_smile:
I guess you can tell Eclipse to use a user provided Makefile as most other IDEs do.

1 Like