Skip to content

rt_memheap_free assertion failure #3812

@diewelt

Description

@diewelt

I faced an assertion failure from rt_memheap_free(). Due to the complexity of the algorithm I'm working on I need an extra heap on SDRAM(MT48LC4M32B2 16MB with 16 bit data width) bside the heap on the internal SRAM. I set necessary macros and called rt_memheap_init() function. And assertion failed in rt_memheap_free(). I am sure that I didn't overwrite the allocated memory region. But rt_memheap_free() gave an assertion failure. I attached the test source at the end.

It looks some weird things happening inside rt_memheap_alloc() and rt_memheap_free().

=====> error messages on console <=====

[D/drv.sdram] Writing the 23068672 bytes data, waiting....
[D/drv.sdram] Write data success, total time: 1.559S.
[D/drv.sdram] start Reading and verifying data, waiting....
[D/drv.sdram] SDRAM test success!
get memory :4 byte at c0000018
free memory :4 byte at c0000018
get memory :8 byte at c0000018
free memory :8 byte at c0000018
get memory :16 byte at c0000018
free memory :16 byte at c0000018
get memory :32 byte at c0000018
free memory :32 byte at c0000018
get memory :64 byte at c0000018
free memory :64 byte at c0000018
get memory :128 byte at c0000018
free memory :128 byte at c0000018
get memory :256 byte at c0000018
free memory :256 byte at c0000018
get memory :512 byte at c0000018
((header_ptr->magic & RT_MEMHEAP_MASK) == RT_MEMHEAP_MAGIC) assertion failed at function:rt_memheap_free, line number:515 

=====> Some important SDRAM settings for MT48LC4M32B2 in board/ports/sdram_port.h <=====

/* column bit numbers: 8, 9, 10, 11 */
#define SDRAM_COLUMN_BITS               11
/* row bit numbers: 11, 12, 13 */
#define SDRAM_ROW_BITS                  12
/* cas latency clock number: 1, 2, 3 */
#define SDRAM_CAS_LATENCY               2

#define SDRAM_SIZE                      ((uint32_t)0x1600000)

I checked the memory R/W with 1B, 2B and 4B width and no problem was found, whose test involves memory RW at every Mega Byte boundary. And sdram_test() from drv_sdram.c was also done by setting DRV_DEBUG macro.

CPPDEFFLAGS += ' -DDRV_DEBUG'

And then, I want an extra heap on SDRAM, from (0xc0000000) with the size of 0x01600000. So I set the necessary macros by calling "scons --menuconfig".

=====> memory heap management related macros in rtconfig.h <=====

/* Memory Management */

#define RT_USING_MEMHEAP
#define RT_USING_SMALL_MEM
#define RT_USING_HEAP

==============================> test.c <==============================

#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>

#include "sdram_port.h"

#define SDRAM_TEST_NAME      "sdrmtest"
#define SDRAM_TEST_STACKSIZE 8192
#define SDRAM_TEST_PRIORITY  24
#define SDRAM_TEST_TIMESLICE     5

static struct rt_memheap _sdrmheap;

static inline void *smalloc(unsigned long size)
{
    return rt_memheap_alloc(&_sdrmheap, size);
}

static inline void sfree(void *ptr)
{
    rt_memheap_free(ptr);
}

void sdram_task(void *arg)
{
    int i;
    int j;
    uint8_t *ptr = RT_NULL; /* memory block pointer */
    uint32_t size;
    uint32_t tmp;

#ifdef DRV_DEBUG
    sdram_test();
#endif

    rt_memheap_init(&_sdrmheap, "extsdrm", SDRAM_BANK_ADDR, 16*1024*1024);

    for(i=0; i<20; i++)
    {
        size = 1 << i;
        /* memory space for allocating (1 << i) bytes each time */
        ptr = smalloc(size);

        /* if allocated successfully */
        if(ptr != RT_NULL)
        {
            for(j=0; j<size; j++)
            {
                *((uint8_t *)ptr + j) = 0xac;
            }
            for(j=0; j<size; j++)
            {
                tmp = *((uint8_t *)(ptr + j));
                if(tmp != 0xac)
                    rt_kprintf("SDRAM 1B rw error %02x at %p\n", tmp, ptr + j);
            }
            /* 2B being written over 1B allocated area will be fine thanks to 4B alignment */
            for(j=0; j<size/2; j++)
            {
                *((uint16_t *)(ptr + 2*j)) = 0xdead;
            }
            for(j=0; j<size/2; j++)
            {
                tmp = *((uint16_t *)(ptr + 2*j));
                if(tmp != 0xdead)
                    rt_kprintf("SDRAM 2B rw error %04x at %p => \n",
                                                           tmp, ptr + j, tmp);
            }
            /* 4B being written over 1B, 2B, 3B allocated area will be fine thanks to 4B alignment */
            for(j=0; j<size/4; j++)
            {
                *((uint32_t *)(ptr + 4*j)) = 0xdeadbeef;
            }
            for(j=0; j<size/4; j++)
            {
                tmp = *((uint32_t *)(ptr + 4*j));
                if(tmp != 0xdeadbeef)
                    rt_kprintf("SDRAM 4B rw error %08x at %p\n", tmp, ptr + j);
            }
            rt_kprintf("get memory :%d byte at %p\n", size, ptr);
            /* release memory block */
            rt_memheap_free(ptr);
            rt_kprintf("free memory :%d byte at %p\n", size, ptr);
            ptr = RT_NULL;
        }
        else
        {
            rt_kprintf("try to get %d byte memory failed!\n", size);
            return;
        }
    }
}

int sdram_task_init(void) {
    rt_thread_t tid;

    tid = rt_thread_create(SDRAM_TEST_NAME, sdram_task, RT_NULL,
             SDRAM_TEST_STACKSIZE, SDRAM_TEST_PRIORITY, SDRAM_TEST_TIMESLICE);
    if (tid != RT_NULL)
        rt_thread_startup(tid);

    return 0;
}

==============================> END <==============================

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions