malloc for reserved memory banks

Dependencies:   mbed

main.cpp

Committer:
tecnosys
Date:
2012-06-03
Revision:
0:1f96d36a994f

File content as of revision 0:1f96d36a994f:

#include "mbed.h"

#include <stdio.h>
#include <string.h>

// Found on the web @
// http://simplestcodings.blogspot.com.au/2010/08/custom-malloc-function-implementation.html

extern "C" void HardFault_Handler() {
    printf("Hard Fault!\n");
}

Serial pc(USBTX, USBRX); // tx, rx

char extmem[0x4000] __attribute__((section("AHBSRAM1")));

typedef
struct
{
    int is_available;
    int size;
} MCB, *MCB_P;


char *mem_start_p;
int max_mem;
int allocated_mem; /* this is the memory in use. */
int mcb_count;

char *heap_end;

MCB_P memallocate(MCB_P ,int );

enum {NEW_MCB=0,NO_MCB,REUSE_MCB};
enum {FREE,IN_USE};


void * myalloc(int elem_size) {
    /* check whether any chunk (allocated before) is free first */

    MCB_P p_mcb;
    int flag = NO_MCB;
    int sz;

    p_mcb = (MCB_P)mem_start_p;


    sz = sizeof(MCB);

    if ( (elem_size + sz) > (max_mem - (allocated_mem + mcb_count * sz ) ) ) {
        return NULL;
    }
    while ( heap_end > ( (char *)p_mcb + elem_size + sz) ) { //<<-- problem here doesnt iterate the first block

        if ( p_mcb->is_available == 0) {

            if ( p_mcb->size == 0) {
             //   printf("\NEW mem: %d ",p_mcb->size);  
                flag = NEW_MCB;
                break;
            }
            if ( p_mcb->size >= (elem_size + sz) ) {
             //   printf("\REUSE mem: %d ",p_mcb->size); 
                flag = REUSE_MCB;
                break;
            }
        }
        p_mcb = (MCB_P) ( (char *)p_mcb + p_mcb->size);


    }

    if ( flag != NO_MCB) {
        p_mcb->is_available = 1;

        if ( flag == NEW_MCB) {
            p_mcb->size = elem_size + sizeof(MCB);
        } else if ( flag == REUSE_MCB) {
            elem_size = p_mcb->size - sizeof(MCB);
        }
        mcb_count++;
        allocated_mem += elem_size;
        return ( (char *) p_mcb + sz);
    }

    return NULL;


    /* if size of the available chunk is equal to greater than required size, use that chunk */


}

void myfree(void *p) {
    /* Mark in MCB that this chunk is free */
   
    MCB_P ptr = (MCB_P)p;
    ptr--;

    if (ptr->is_available != FREE) {
        mcb_count--;
        ptr->is_available = FREE;
        allocated_mem -= (ptr->size - sizeof(MCB));
    }
    
    /* Mark in MCB that this chunk is free */  
    /*
    MCB_P ptr = (MCB_P)p;   
    ptr--;  
 
    mcb_count--;  
    ptr->is_available = FREE;  
    printf("\nAllocated mem: %d ",ptr->size);  
    allocated_mem -= (ptr->size - sizeof(MCB));  
    printf("\nAllocated mem: %d ",allocated_mem);  
    printf("\nMemory Freed...");  
    */
}

void * myrealloc(void *p) {
    //I would like to implement this
    return NULL;
}

void InitMem(char *ptr, int size_in_bytes) {
    /* store the ptr and size_in_bytes in global variable */

    max_mem = size_in_bytes;
    mem_start_p = ptr;
    mcb_count = 0;
    allocated_mem = 0;
    heap_end = mem_start_p + size_in_bytes;
    memset(mem_start_p,0x00,max_mem);
    myalloc(2); //<<-- myalloc doesnt iterate the first block, added as temporary fix
    /* This function is complete :-) */

}


int main() {

    pc.baud(57600);
    InitMem(extmem,sizeof(extmem));

    int blockSize = 256;
    int i = 1;

    printf("Checking extmem memory with blocksize %d char ...\n", blockSize);
    while (true) {
        char *p = (char *) myalloc(i * blockSize);
        printf("%d @ 0x%08X\n", i * blockSize, p);
      //  printf("\nMCB count: %-3d \tAllocated Memory: %-10d",mcb_count,allocated_mem); 
        if (p == NULL)
            break;
        myfree(p);
        ++i;
    }
    printf("%d\n\r",(i - 1) * blockSize);

/*
   printf("Checking main memory with blocksize %d char ...\n", blockSize);
    while (true) {
        char *p = (char *) malloc(i * blockSize);
        printf("%d @ 0x%08X\n", i * blockSize, p);
        if (p == NULL)
            break;
        free(p);
        ++i;
    }
    printf("%d\n\r",(i - 1) * blockSize);
*/
}