How to use the library without a heap.

Basically, the library uses malloc function to allocate space on a heap. On some embedded system developers cannot afford the use of an operating system and, many times it is not possible to have a heap. Here is a trick that can be used to avoid the use of a heap.

First of all state machine are usually not made to be dynamic. In this library once you've started a state machine you cannot allocate any more structure in it. So if you are using the compilation option USE_PRE_ALLOCATED_BUF and if you follow carefully the advises in this section , the state machine will never have to call the free() function and will never allocate any space after having been started. Starting from this, you may think that you can use a static buffer to give memory space to the state machine. All that you need is to know the amount of memory the state machine will claim during initialisation time. So let's move on...

Warning:
The library allocate a buffer when started, you have to start it to know the exact amount of space needed.
The library call the malloc function through a macro, the macro is defined in the file PreProcessing.h:
#define fake_malloc(X, Y, Z) malloc(X * Y)
It is possible to intercept this call by writing a function and overwriting this macro like this:

In a separated file (outside the library):

unsigned long int type1 = 0, type2 = 0, type3 = 0, type4 = 0, type5 = 0;
void* my_malloc(unsigned short int nb, unsigned long int size, unsigned char type)
{ 
    switch(type)
    {
        case 1:
            type1 += nb;
            break;
        case 2:
            type2 += nb;
            break;
        case 3:
            type3 += nb;
            break;
        case 4:
            type4 += nb;
            break;
        case 5:
            type5 += nb;
            break;
    }
    return malloc(nb * size);
}
In file PreProcessing.h:
/*#define fake_malloc(X, Y, Z) malloc(X * Y)*/
#define fake_malloc(X, Y, Z) my_malloc(X, Y, Z)
void* my_malloc(unsigned short int nb, unsigned long int size, unsigned char type);

Note that typeX variable are stored at global scope. Now if you allocate a state machine, start it and try to display the 5 variables typeX you can know how much space the library need to work. Let's describe a bit. The first parameter 'nb' is the number of element the library want to allocate and the 'size' parameter is the size of one element. Usually you call the malloc function this way: malloc(nb*sizeof(MyStruct)). Here, it is the same, but splited into two distinct variables. The last variable is an kind of ID:

So now you have everything to calculate which amount of space you need. And even if you are running your programm in a computer that is not the final target of it, you can calculate the amount of space needed. You know exactly how many allocation of every kind the system need. If you know the size of the elements in the final target you're done.

Let's imagine the result after a state machine instantiation and this line of code:

printf("Allocated %ld StateMachine, %ld State, %ld ParallelState, %ld transitions and %ld void*\n", type1, type2, type3, type4, type5);
The output is:
Allocated 1 StateMachine, 6 State, 0 ParallelState, 7 transitions and 27 void*
Assuming that on the target system: The total amount of space needed is: 1 * 56 + 6 * 96 + 0 * 40 + 7 * 16 + 27 * 8 = 960

The final step is to implement our own function:

char MY_HEAP[960];
void* ptr = MY_HEAP;
void* my_malloc(unsigned long int size)
{
    void* temp = ptr;
    ptr+=size;
    return temp;
}

And you're done with your super heap. Don't try to free the memory :)

Previous: How to build the library.


Generated on Sat Sep 18 15:39:57 2010 for Easy C State Machine by  doxygen 1.5.8