We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hello, I am using Keil uVision3 V3.55 for Si-labs C8051F02X series. I am using "init_mempool" function, so that I can use the functions like "malloc", "free", etc. Here is my source code --
#include<c8051f020.h> #include<stdlib.h> void main(void) { unsigned char xdata *ptr, *ptr1; init_mempool(0x05,15); ptr = malloc(10); ptr1 = malloc(5); *ptr++ = 11; *ptr++ = 22; *ptr++ = 33; *ptr++ = 44; *ptr1++ = 1; *ptr1++ = 2; *ptr1++ = 3; }
I am expecting that, all the above data to be put from the locations 0x05(in xdata) onwards. But, I found that "ptr1" points to 0x00(in xdata), and "ptr" points to 0x09(in xdata). So, what is the role of "init_mempool" function here? Why does "malloc" allocate memory from 0x00??
Thanks in advance,
Regards, Heramb Phadke
Your call to init_mempool:
init_mempool(0x05,15);
allocates only 15 bytes of memory. That's an awfully small memory pool. There is some overhead (a few bytes for the block size and a pointer to the next free block) associated with each block allocated from the pool. So, a pool that's only 15 bytes long isn't going to hold much. Typically, the memory pool should be 1K or larger to really be useful. Allocating only 15 bytes doesn't require dynamic memory to do.
See more information here: http://www.keil.com/support/man/docs/c51/c51_init_mempool.htm
Jon
In this case, the second malloc call returned 0x09. The heap started at 0x05, and the heap consumed four bytes fixed overhead. 0x05 + 4 => 0x09, i.e. the lowest possible return address from malloc() in your case - if we also ignores the NULL pointer you did chose to ignore.
With the 4 bytes of static overhead, a 15 byte heap would have 11 bytes available to allocate from. And since each allocated block needs one pointer and one block size, I would guess that the best possible allocation from this tiny heap would be 11-4 = 7 bytes. Using a 15 byte large heap just to manage a single 7 byte allocation, while at the same time reducing the possible addressing modes available to the compiler is not a good tradeoff.
There are some few situations where a heap may be good to have in an 8051 processor. Most of the time, malloc() usage in a 8051 program is a sign of an incorrect software design. The biggest reason for Keil to supply malloc() is probably that less informed customers shopping for a compiler expects the compiler to support malloc().
Whenever the application releases memory in a random order compared to the allocations, and constantly allocates new data without ever releasing everything, you will have big problems with memory fragmentation that may make allocations fail even when there are a lot of memory free on the heap.
This problem goes away if all blocks have a fixed size - but then you could replace malloc() with a better alternative, and possibly use a bitmap to keep track of free block.
A solution where blocks are always released in the reverse order of the allocations would also work well - but that would basically be a stack, in which case you can implement a custom solution that is faster and with less memory overhead.
A solution where allocations happens only on startup is also free from fragmentation problems. But then there would not be a need for malloc(). It would be enough with one big array of memory, and then just step one pointer forward n steps for each n byte allocation. Much less code, and only the size of this pointer as RAM overhead. Zero RAM overhead if the pointer is reused after the startup code has performed the allocations.
When you really do need random allocations of blocks of varying size, you may need to use add a second indirection, allowing the allocation routines to store a pointer/offset to each allocated block. Then you could regularly compact the heap, as long as you don't an interrupt to do an indirection while the compactation is being done.
But in the end, malloc() really is a concept intended for environments with infinite RAM or where you can accept a failed allocation.
Thanks to all, for their valuable suggestions.
The intension behind allocating only 15 bytes of memory is that, to learn 'malloc', 'calloc'. I have used these functions in C(by using compilers like Turbo C). But, in case of 8051, I wanted to know, how do these functions work.
Thanks once again.