malloc behaviour on an embedded system

前端 未结 5 1904
执笔经年
执笔经年 2020-12-09 02:17

I\'m currently working on an embedded project (STM32F103RB, CooCox CoIDE v.1.7.6 with arm-none-eabi-gcc 4.8 2013q4) and I\'m trying to understand how malloc() b

5条回答
  •  萌比男神i
    2020-12-09 03:06

    Using standard c malloc it's very hard to distinguish and malloc is seems buggy from my view. So you can manage memory by implementing some custom malloc using your RAM address.

    I am not sure may this help you but i have done some custom malloc in my controller related project it's as follows

    #define LENGTH_36_NUM   (44)
    #define LENGTH_52_NUM   (26)
    #define LENGTH_64_NUM   (4)
    #define LENGTH_128_NUM  (5)
    #define LENGTH_132_NUM  (8)
    #define LENGTH_256_NUM  (8)
    #define LENGTH_512_NUM  (18)    
    #define LENGTH_640_NUM  (8) 
    #define LENGTH_1536_NUM (6) 
    
    #define CUS_MEM_USED        (1)
    #define CUS_MEM_NO_USED     (0)
    
    #define CALC_CNT    (0)
    #define CALC_MAX    (1)
    
    #define __Ram_Loc__         (0x20000000) ///This is my RAM address
    #define __TOP_Ram_Loc__     (0x20000000 + 0x8000 -0x10) //Total 32K RAM and last 16 bytes reserved for some data storage
    
    typedef struct _CUS_MEM_BLOCK_S {
        char used;
        int block_size;
        char *ptr;
        char *next;
    } cus_mem_block_s;
    
    static struct _MEM_INFO_TBL_S {
        int block_size;
        int num_max;
        cus_mem_block_s *wm_head;
        int calc[2];
    } memInfoTbl[] = {
    
     {36,  LENGTH_36_NUM  , 0, {0,0} },
     {52,  LENGTH_52_NUM  , 0, {0,0} },
     {64,  LENGTH_64_NUM  , 0, {0,0} },
     {128, LENGTH_128_NUM , 0, {0,0} },
     {132, LENGTH_132_NUM , 0, {0,0} },
     {256, LENGTH_256_NUM , 0, {0,0} },
     {512, LENGTH_512_NUM , 0, {0,0} },
     {640, LENGTH_640_NUM , 0, {0,0} },
     {1536,LENGTH_1536_NUM, 0, {0,0} },
    };
    #define MEM_TBL_MAX     (sizeof(memInfoTbl)/sizeof(struct _MEM_INFO_TBL_S))
    
    BOOL MemHeapHasBeenInitialised = FALSE;
    

    This basically macro defines for RAM address and have manually chose more block number for block size which frequently require to allocate,Like 36 bytes required me more so i take more number for it.

    This is init function for mem init

    void cus_MemInit(void)
    {
        int i,j;
        cus_mem_block_s *head=NULL;
        unsigned int addr;
    
        addr = __Ram_Loc__;
    
        for(i=0; iused =CUS_MEM_NO_USED;
                head->block_size = memInfoTbl[i].block_size;
                head->ptr = (char *)(addr + sizeof(cus_mem_block_s));
                addr += (memInfoTbl[i].block_size + sizeof(cus_mem_block_s));
                head->next =(char *)addr;
                head = head->next;
                if(head > __TOP_Ram_Loc__) 
                {
                    printf("%s:error.\n",__FUNCTION__);
                    return;
                }
            }
        }
        head->ptr = 0;
        head->block_size = 0;
        head->next = __Ram_Loc__;
    
        MemHeapHasBeenInitialised=TRUE;
    }
    

    This one for allocation

    void* CUS_Malloc( int wantedSize )
    {
        void *pwtReturn = NULL;
        int i;
        cus_mem_block_s *head;
    
        if(MemHeapHasBeenInitialised == FALSE) 
                goto done_exit;
    
        for(i=0; iptr)
                {
                    if(head->used == CUS_MEM_NO_USED)
                    {
                        head->used = CUS_MEM_USED;
                        pwtReturn = head->ptr;
                        goto done;
                    }
                    head = head->next;
                }
                goto done;
    
            }
        }
     done:
    
    
        if(pwtReturn)
        {
            for(i=0; iblock_size)
                {
    
                    memInfoTbl[i].calc[CALC_CNT]++;
                    if(memInfoTbl[i].calc[CALC_CNT] > memInfoTbl[i].calc[CALC_MAX] )
                        memInfoTbl[i].calc[CALC_MAX]=memInfoTbl[i].calc[CALC_CNT];
                    break;
                }
            }
        }
      done_exit:
        return pwtReturn;
    }
    

    This one for free

    void CUS_Free(void *pm)
    {
        cus_mem_block_s *head;
        char fault=0;
    
    
        if( (pm == NULL) || (MemHeapHasBeenInitialised == FALSE) )
            goto done;
        if( (pm < __RamAHB32__) && (pm > __TOP_Ram_Loc__) )
        {
            printf("%s:over memory range\n",__FUNCTION__);
            goto done;
        }
    
        head = pm-sizeof(cus_mem_block_s);
    
    
        if(head->used)
            head->used = CUS_MEM_NO_USED;
        else
        {
            printf("%s:free error\n",__FUNCTION__);
            fault=1;
        }
    
    
        if(fault)
            goto done;
        int i;
        for(i=0;iblock_size)
            {
                memInfoTbl[i].calc[CALC_CNT]--;
                goto done;
            }
        }
     done:;
    
    }
    

    After all you can use above function like

    void *mem=NULL;
    mem=CUS_Malloc(wantedsize);
    

    Then can also watch your used memory as follows

    void CUS_MemShow(void)
    {
        int i;
        int block_size;
        int block_cnt[MEM_TBL_MAX];
        int usedSize=0, totalSize=0;
        cus_mem_block_s *head;
    
        if(MemHeapHasBeenInitialised == FALSE)
                return;
    
        memset(block_cnt, 0, sizeof(block_cnt));
    
        head = memInfoTbl[0].wm_head;
        i=0;
        block_size = head->block_size;
        vTaskSuspendAll();
        while( head->ptr !=0)
        {
            if(head->used == CUS_MEM_USED )
            {
                block_cnt[i]++;
                usedSize +=head->block_size;
            }
            usedSize += sizeof(cus_mem_block_s);
    
            totalSize += (head->block_size+ sizeof(cus_mem_block_s));
    
            /* change next memory block */  
            head = head->next;
            if( block_size != head->block_size)
            {
                block_size = head->block_size;
                i++;
            }
        }
        xTaskResumeAll();
    
        usedSize += sizeof(cus_mem_block_s);
        totalSize+= sizeof(cus_mem_block_s);
    
        dprintf("----Memory Information----\n");
    
        for(i=0; i

    In general have pre-calculated the memory first then give as i have.

提交回复
热议问题