I am using FreeRTOS v6.0.0 and memory module Heap_2.c.
I print the available memory using xPortGetFreeHeapSize(). After using pvPortMalloc() to allocate 48 bytes, then freeing the memory using vPortFree(), my available memory has increased a net gain of 32 bytes?
5944 bytes available from the heap store.
Allocating 48 bytes using pvPortMalloc().
Releasing memory using vPortFree().
5976 bytes available from the heap store.
I have tried simply just allocating and freeing blocks, and I always end up where I started.
Could you provide a little more information on how to replicate the problem? For example, the sequence of events to get into the starting condition, which value 5976 or 5944 is actually correct (if either), etc. Thanks.
I wonder where the file is including the xPortGetFreeHeapSize() function. I searched all locations and could not find it in FreeRTOS demo project and source folders.
If there was no need to “split” the block - pxBlock->xBlockSize contains
a wrong value, because it has not been touched/adjusted and contians a value
from a previous call (i guess it comes from xStart.pxNextFreeBlock).
Richard told me to send in some code to prove that issue but i wasn’t able so far to do that - too much work. Hopefully i can perfom this task on sunday evening.
The base heap size (configTOTOAL_HEAP_SIZE = 31K).
portBYTE_ALIGNMENT = 8;
In my environment, I have roughly 20 tasks running. Most of these tasks will allocate memory using pvPortMalloc(), but not release it. I have one task that performs pvPortMalloc() and vPortFree() with various sizes. In my previous post you see that I have about 5K available from the original 31K. What is strange, this failure is not consistent which make me wonder if its related to how the heap blocks get split, or am I starting to see some effect from fragmentation?
I will try some experiments to see how many times I call pvPortMalloc() and vPortFree() with associated sizes. This might shed some light on the issue.
Note: In my previous post, the value 5944 bytes available from the heap store was before the allocation of 48 bytes. The value 5976 was after I released the memory using vPortFree(). For a net gain of 32 bytes.
Hi guys,
i’ve added added a sample application to the bug tracker entry. Hopefully that helps to find the error.
I have discovered also another strange error with heap2.c. I’ve build the following code for testing.
When iam running in this loop, no other allocations or deallocations are being made, but sadly after i>=300, pvPortMalloc fails. And this is strange, because there can’t be any fragmentation…
When iam running in this loop, no other allocations or deallocations are being made, but sadly after i>=300, pvPortMalloc fails. And this is strange, because there can’t be any fragmentation…
Why do you say that. To me it looks like that code does nothing other than fragment the heap.
Hi dave,
why is the heap being fragmented? I thought fragmentation is something like this:
Alloc a) 100 bytes
Alloc b) 100 bytes
Alloc c) 100 bytes
Alloc d) 100 bytes
Alloc e) 100 bytes
If i free b and d, i have 200 bytes returned but can not allocate 200 bytes at once due to the fragmentation. But i could allocate two times 100 bytes, that would work. Thats fragmentation to me…
What i did was the following:
Alloc a) 1000 bytes (just at startup) - will never be freed.
Alloc b) 500 bytes (just at startup) - will never be freed.
Alloc c) 1 byte
Free c
Alloc c) 2 bytes
Free c
To me, there should not be any fragmentation at all. The returned pointer of c should be always the same. (But i didn’t checked that, in fact).
Probably you can explain to me how heap2.c handles the allocation.
Having looked at your test code I would suggest you had a couple of fundamental misunderstandings about how the memory allocation works with heap_2. A couple of pointers:
1) Your tasks have an incorrect prototype. I’m not sure if this has any effect or not as you are not using the parameter anyway.
2) The loop you use to allocate the memory will definitely result in heavy fragmentation, and you will find that pvPortMalloc() will be returning NULL. You don’t check for this in your code, so will be passing NULL to vPortFree(). Again I’m not sure what effect this will have exactly, but it won’t be good.
I will wait a few days to see if you can provide a short piece of code that definitely exhibits buggy behaviour - if not I will close the bug report down.
As a result, if heap_2 is working as you described, its not being suitable for using with USB stacks, where i need to allocate memory when inserting a device and free the allocated memory when ejecting the device. So i should use heap_3 instead, right?
The described error is happening when allocating and releasing memory like in a USB scenario: xPortGetFreeHeapSize() is becoming invalid because a higher value is being returned than ever requested. You can see that in the provided heap_2.c and in the log-file.
The incorrect prototype does not effect anything - and it was only for testing and a quick and dirty implementation.
Thanks anyway.
I would tend not to dynamically allocate or free anything at run time. If you do, then always allocate the same size block, and you will not have a problem. It is unlikely that heap_3 would work with your test code either, but that would depend on the implementation of malloc() and free() that come with your compiler.
Hi Richard,
thanks for your reply. Heap_3.c which is using the compiler provided malloc()/free() functions (in my case C32 by Microchip) behaves as expected. If i allocate all needed static memory first and keep an area for the USB stack which needs different block sizes dynamically created and freed there is not a problem. The code, which causes fragments with heap_2.c is now working.