硬汉嵌入式论坛

 找回密码
 立即注册
查看: 2676|回复: 26
收起左侧

[其它] 可灵活申请的内存分配算法

  [复制链接]

2

主题

11

回帖

17

积分

新手上路

积分
17
发表于 2021-8-7 15:46:54 | 显示全部楼层 |阅读模式
本帖最后由 lenyound 于 2021-8-7 17:29 编辑

用此方式管理的内存,方便,灵活,用途很广
原理: 通常我们使用mallo申请内存的时候,可以申请任意大小,这样如果申请、释放次数多了以后很容易造成内存碎片。           本案例原理是从一大块已申请内存池中,根据设定的最小内存片尺寸,划分为n个内存片,根据需要灵活分配内存片,可以有效的解决内存碎片的问题。

特点:
1. 灵活的分配内存,可大可小,但是必须大于MM_CTRL_SIZE
2. 释放内存后具有合并功能
3. 具有安全的读写函数
4. 可以用于操作系统,当用于操作系统时,要先调用MM_SetFunc_Lock函数,实现加锁和解锁。

使用方法:
1. 创建内存池 MM_Create
        void *pMemBlock                                                内存池
        HY_U32 BlockSize                                        内存池尺寸(字节)
        HY_U32 PieceSize                                        划分的内存小片(最小可申请的内存片尺寸,因为申请一个内存片都要包含控制结构体,所以可以用用MM_PIECE_SIZE_SET(PieceSize)来转换。)
        MCB_StructDef *pStruct                                内存分配控制结构体
        例:
        #define STimGroupSize                                512
        #define STIM_PIECE_SIZE                                32 //每个内存小片尺寸
        char STimGroup[STimGroupSize];
        MCB_StructDef MM_CtrlStruct;
        MM_Create(&STimGroup, STimGroupSize, MM_PIECE_SIZE_SET(STIM_PIECE_SIZE), &MM_CtrlStruct);
2. 申请内存 MM_Get,申请成功则返回内存地址,失败则返回0
3. 释放内存 MM_Free


system_mem.rar

6.05 KB, 下载次数: 34

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106882
QQ
发表于 2021-8-8 08:33:26 | 显示全部楼层
谢谢分享。
回复

使用道具 举报

610

主题

3057

回帖

4907

积分

至尊会员

积分
4907
发表于 2021-8-8 09:08:06 | 显示全部楼层
这个内存貌似感觉蛮高大上的哟,
回复

使用道具 举报

73

主题

1195

回帖

1414

积分

至尊会员

积分
1414
发表于 2021-8-8 09:39:43 | 显示全部楼层
自己写的吗??谢谢分享
回复

使用道具 举报

2

主题

8

回帖

14

积分

新手上路

积分
14
发表于 2021-8-8 10:35:45 | 显示全部楼层
顶楼主,还给大家推荐一个内存管理的开源软件 bget 貌似用的人比较多。
回复

使用道具 举报

75

主题

685

回帖

910

积分

金牌会员

积分
910
发表于 2021-8-8 13:54:39 | 显示全部楼层
看上去就像是开辟一些等大的小内存来做内存池,碎片和利用率一样很大的,推荐你可以了解下TLSF,这个做得比较好。
回复

使用道具 举报

2

主题

11

回帖

17

积分

新手上路

积分
17
 楼主| 发表于 2021-8-9 08:30:50 | 显示全部楼层
庄永 发表于 2021-8-8 13:54
看上去就像是开辟一些等大的小内存来做内存池,碎片和利用率一样很大的,推荐你可以了解下TLSF,这个做得比 ...

是的,就是小内存片。可以扩展为分配不连续内存片。这样利用率就很高了。不过需要用专用函数读写。这个方法如果用于每次只需要一个片或者小于一个片尺寸的情况下,非常有用。
回复

使用道具 举报

610

主题

3057

回帖

4907

积分

至尊会员

积分
4907
发表于 2021-8-9 09:09:53 | 显示全部楼层
你好,貌似这个内存管理,我使用这个来播放 mp3 文件时会出现 内存溢出错误,

同样的工程文件,除了使用内存管理 函数不同以外,其他所有的程序都是一样的,而使用其他的 内存管理 函数播放 mp3 时,效果杠杠的,

请问下这个内存管理里面有哪些比较特殊的东东吗 ?
回复

使用道具 举报

2

主题

11

回帖

17

积分

新手上路

积分
17
 楼主| 发表于 2021-8-9 12:04:05 | 显示全部楼层
hpdell 发表于 2021-8-9 09:09
你好,貌似这个内存管理,我使用这个来播放 mp3 文件时会出现 内存溢出错误,

同样的工程文件,除了使用 ...

没有什么特殊的,实际上就是2个链表,空闲和已分配。我在项目上一直在使用,普通应用的话,只要调用GET和FREE,其他的都不要调用。还有使用之前必须要先CREATE。在函数内部对指针地址都做了安全判断,确保不会跳出范围。
回复

使用道具 举报

2

主题

11

回帖

17

积分

新手上路

积分
17
 楼主| 发表于 2021-8-9 12:11:48 | 显示全部楼层
hpdell 发表于 2021-8-9 09:09
你好,貌似这个内存管理,我使用这个来播放 mp3 文件时会出现 内存溢出错误,

同样的工程文件,除了使用 ...

如果可以的话,把相关代码贴出来。我们一起分析一下。
回复

使用道具 举报

610

主题

3057

回帖

4907

积分

至尊会员

积分
4907
发表于 2021-8-9 17:21:17 | 显示全部楼层
本帖最后由 hpdell 于 2021-8-10 10:21 编辑
lenyound 发表于 2021-8-9 12:11
如果可以的话,把相关代码贴出来。我们一起分析一下。

如果不进行播放 mp3 音乐文件的话,其他的使用 是没有问题的,

播放mp3 时,仿真时程序运行到 MP3InitDecoder();  这句时就会出现 溢出的错误

这个貌似是 mp3 解码库里面自带的函数


  #define  MP3_FREE(_size)     myfree(SDRAMEX, _size)          // 这个地方内存申请使用外部 sdram 还是单片机内部的 sram 结果都是一样的,但是使用其他的内存管理是没有问题的
  #define  MP3_MALLOC(_size)   mymalloc(SDRAMEX, _size)


这个函数展开
HMP3Decoder MP3InitDecoder(void)
{
        MP3DecInfo *mp3DecInfo;

        mp3DecInfo = AllocateBuffers();

        return (HMP3Decoder)mp3DecInfo;
}


MP3DecInfo *AllocateBuffers(void)
{
  MP3DecInfo *mp3DecInfo_pointer;
        FrameHeader *fh;
        SideInfo *si;
        ScaleFactorInfo *sfi;
        HuffmanInfo *hi;
        DequantInfo *di;
        IMDCTInfo *mi;
        SubbandInfo *sbi;

        mp3DecInfo_pointer = (MP3DecInfo *)MP3_MALLOC(sizeof(MP3DecInfo));
        if (!mp3DecInfo_pointer)
                return 0;
        ClearBuffer(mp3DecInfo_pointer, sizeof(MP3DecInfo));
       
        fh =  (FrameHeader *)     MP3_MALLOC(sizeof(FrameHeader));
        si =  (SideInfo *)        MP3_MALLOC(sizeof(SideInfo));
        sfi = (ScaleFactorInfo *) MP3_MALLOC(sizeof(ScaleFactorInfo));
        hi =  (HuffmanInfo *)     MP3_MALLOC(sizeof(HuffmanInfo));
        di =  (DequantInfo *)     MP3_MALLOC(sizeof(DequantInfo));
        mi =  (IMDCTInfo *)       MP3_MALLOC(sizeof(IMDCTInfo));
        sbi = (SubbandInfo *)     MP3_MALLOC(sizeof(SubbandInfo));

        mp3DecInfo_pointer->FrameHeaderPS =     (void *)fh;
        mp3DecInfo_pointer->SideInfoPS =        (void *)si;
        mp3DecInfo_pointer->ScaleFactorInfoPS = (void *)sfi;
        mp3DecInfo_pointer->HuffmanInfoPS =     (void *)hi;
        mp3DecInfo_pointer->DequantInfoPS =     (void *)di;
        mp3DecInfo_pointer->IMDCTInfoPS =       (void *)mi;
        mp3DecInfo_pointer->SubbandInfoPS =     (void *)sbi;

        if (!fh || !si || !sfi || !hi || !di || !mi || !sbi) {
                FreeBuffers(mp3DecInfo_pointer);        /* safe to call - only frees memory that was successfully allocated */
                return 0;
        }

        /* important to do this - DSP primitives assume a bunch of state variables are 0 on first use */
        //Optimized away.. hmm
    ClearBuffer(fh,  sizeof(FrameHeader));
        ClearBuffer(si,  sizeof(SideInfo));
        ClearBuffer(sfi, sizeof(ScaleFactorInfo));
        ClearBuffer(hi,  sizeof(HuffmanInfo));
        ClearBuffer(di,  sizeof(DequantInfo));
        ClearBuffer(mi,  sizeof(IMDCTInfo));
        ClearBuffer(sbi, sizeof(SubbandInfo));

        return mp3DecInfo_pointer;
}






回复

使用道具 举报

2

主题

11

回帖

17

积分

新手上路

积分
17
 楼主| 发表于 2021-8-10 11:38:19 | 显示全部楼层
hpdell 发表于 2021-8-9 17:21
如果不进行播放 mp3 音乐文件的话,其他的使用 是没有问题的,

播放mp3 时,仿真时程序运行到 MP3Init ...

1. 申请,释放内存有没在中断里面调用?中断函数里面使用的话就很有可能出问题。
2. 是否有操作系统?有系统的要加信号量。lock()里面申请信号量,unlock()发出信号量。
3. 有没有内存申请失败的情况?CREATE函数指定内存片尺寸时要大于12字节(控制字节就占了12字节)
4. 写入有没有超出申请量的情况?如果有的话,很有可能把后续内存片控制字节内容覆盖,造成不可预期的问题
   我感觉最有可能是这个问题。
回复

使用道具 举报

610

主题

3057

回帖

4907

积分

至尊会员

积分
4907
发表于 2021-8-10 14:32:55 | 显示全部楼层
lenyound 发表于 2021-8-10 11:38
1. 申请,释放内存有没在中断里面调用?中断函数里面使用的话就很有可能出问题。
2. 是否有操作系统?有 ...






1. 没有在中断里面调用
2. 有 os 操作系统,估计问题就出在这步了,我加上信号量试试看
3. 内存没有申请失败, #define  STIM_PIECE_SIZE        16
4. 写入是没有超过申请量的情况



回复

使用道具 举报

0

主题

10

回帖

10

积分

新手上路

积分
10
发表于 2021-8-10 16:14:08 | 显示全部楼层
这种内存分配方式是不是和 ThreadX 内存管理中的内存块池(BLCOK_POOL)比较类似?
回复

使用道具 举报

7

主题

19

回帖

40

积分

新手上路

积分
40
发表于 2021-8-10 18:06:05 | 显示全部楼层
感谢分享, 我是直接吧freertos内存管理挪过来用了, rtt的也不错。
回复

使用道具 举报

610

主题

3057

回帖

4907

积分

至尊会员

积分
4907
发表于 2021-8-11 08:57:13 | 显示全部楼层
lenyound 发表于 2021-8-10 11:38
1. 申请,释放内存有没在中断里面调用?中断函数里面使用的话就很有可能出问题。
2. 是否有操作系统?有 ...

你好,我吧 互斥信号量加上了,貌似也还是不行哟,
回复

使用道具 举报

610

主题

3057

回帖

4907

积分

至尊会员

积分
4907
发表于 2021-8-11 08:58:18 | 显示全部楼层
硬汉的小粉丝 发表于 2021-8-10 18:06
感谢分享, 我是直接吧freertos内存管理挪过来用了, rtt的也不错。

我吧 threadx 里面的 内存管理也抠出来使用,效果也还是非常不错,还有 ti 的蓝牙系统里面的 内存管理,貌似效果也非常的好哇
回复

使用道具 举报

610

主题

3057

回帖

4907

积分

至尊会员

积分
4907
发表于 2021-8-11 09:07:39 | 显示全部楼层
相关的应用函数


/*
***********************************************************************************************************
内存申请
***********************************************************************************************************
*/
void *mymalloc(MEMORY_DefType memx,uint32_t size)
{

        void * MallocAddr = NULL;
       
        if(!size) return MallocAddr;
       
        if(memx == SDRAMEX)
        {
                MallocAddr = MM_Get(&_ctrl_struct_sdram, size);                               
        }
        else if(memx == SRAM1)
        {
                MallocAddr = MM_Get(&_ctrl_struct_sram1, size);               
        }
        else if(memx == SRAM4)
        {
                MallocAddr = MM_Get(&_ctrl_struct_sram4, size);               
        }
        else if(memx == DTCMSRAM)
        {
                MallocAddr = MM_Get(&_ctrl_struct_dtcm, size);               
        }
       
        return MallocAddr;
       
}



/*
***********************************************************************************************************
内存释放
***********************************************************************************************************
*/
void myfree(MEMORY_DefType memx,void *ptr)
{
        if(!ptr) return ;
       
       
        if(memx == SDRAMEX)
        {
                MM_Free(&_ctrl_struct_sdram, ptr);                               
        }
        else if(memx == SRAM1)
        {
                MM_Free(&_ctrl_struct_sram1, ptr);               
        }
        else if(memx == SRAM4)
        {
                MM_Free(&_ctrl_struct_sram4, ptr);               
        }
        else if(memx == DTCMSRAM)
        {
                MM_Free(&_ctrl_struct_dtcm, ptr);               
        }

}


static OS_MUTEX  xMutexSram1 ;  // sram1 内存管理 使用
static OS_MUTEX  xMutexSram4 ;  // sram4 内存管理 使用
static OS_MUTEX  xMutexSdram ;  // sdram 内存管理 使用
static OS_MUTEX  xMutexDtcm ;   // dtcm  内存管理 使用



        OSMutexCreate(&xMutexSram1,
                                (CPU_CHAR  *)"xMutexSram1",
                                (OS_ERR    *)&err);
                               
        OSMutexCreate(&xMutexSram4,
                                (CPU_CHAR  *)"xMutexSram4",
                                (OS_ERR    *)&err);

        OSMutexCreate(&xMutexSdram,
                                (CPU_CHAR  *)"xMutexSdram",
                                (OS_ERR    *)&err);

        OSMutexCreate(&xMutexDtcm,
                                (CPU_CHAR  *)"xMutexDtcm",
                                (OS_ERR    *)&err);



void MEMORY_1_xMutexPhore(char _ch)
{
  OS_ERR    os_err;
        if(OSRunning == 1)                                        //OS开始跑了,才执行正常的调度处理, uCOS-III 系统使用
        {
                if(!_ch)
                {
                        OSMutexPend(&xMutexSram1,
              (OS_TICK  )0u,
              (OS_OPT   )OS_OPT_PEND_BLOCKING,
              (CPU_TS  *)NULL,
              (OS_ERR  *)&os_err);    //获取信号量资源
                }
                else
                {
                 //释放掉资源
                 (void)OSMutexPost(&xMutexSram1,
                   (OS_OPT   )OS_OPT_POST_NONE,
                   (OS_ERR  *)&os_err);
                }
        }
}

void MEMORY_4_xMutexPhore(char _ch)
{
  OS_ERR    os_err;
        if(OSRunning == 1)                                        //OS开始跑了,才执行正常的调度处理, uCOS-III 系统使用
        {
                if(!_ch)
                {
                        OSMutexPend(&xMutexSram4,
              (OS_TICK  )0u,
              (OS_OPT   )OS_OPT_PEND_BLOCKING,
              (CPU_TS  *)NULL,
              (OS_ERR  *)&os_err);    //获取信号量资源
                }
                else
                {
                 //释放掉资源
                 (void)OSMutexPost(&xMutexSram4,
                   (OS_OPT   )OS_OPT_POST_NONE,
                   (OS_ERR  *)&os_err);
                }
        }
}

void MEMORY_Sdram_xMutexPhore(char _ch)
{
  OS_ERR    os_err;
        if(OSRunning == 1)                                        //OS开始跑了,才执行正常的调度处理, uCOS-III 系统使用
        {
                if(!_ch)
                {
                        OSMutexPend(&xMutexSdram,
              (OS_TICK  )0u,
              (OS_OPT   )OS_OPT_PEND_BLOCKING,
              (CPU_TS  *)NULL,
              (OS_ERR  *)&os_err);    //获取信号量资源
                }
                else
                {
                 //释放掉资源
                 (void)OSMutexPost(&xMutexSdram,
                   (OS_OPT   )OS_OPT_POST_NONE,
                   (OS_ERR  *)&os_err);
                }
        }
}

void MEMORY_Dtcm_xMutexPhore(char _ch)
{
  OS_ERR    os_err;
        if(OSRunning == 1)                                        //OS开始跑了,才执行正常的调度处理, uCOS-III 系统使用
        {
                if(!_ch)
                {
                        OSMutexPend(&xMutexDtcm,
              (OS_TICK  )0u,
              (OS_OPT   )OS_OPT_PEND_BLOCKING,
              (CPU_TS  *)NULL,
              (OS_ERR  *)&os_err);    //获取信号量资源
                }
                else
                {
                 //释放掉资源
                 (void)OSMutexPost(&xMutexDtcm,
                   (OS_OPT   )OS_OPT_POST_NONE,
                   (OS_ERR  *)&os_err);
                }
        }
}


// -----------------------------------------------------------------------------------
static void mem_1_lock(void)
{
        MEMORY_1_xMutexPhore(0);
}

static void mem_1_unlock(void)
{
        MEMORY_1_xMutexPhore(1);
}

// -----------------------------------------------------------------------------------
static void mem_4_lock(void)
{
        MEMORY_4_xMutexPhore(0);
}

static void mem_4_unlock(void)
{
        MEMORY_4_xMutexPhore(1);
}

// -----------------------------------------------------------------------------------
static void mem_sdram_lock(void)
{
        MEMORY_Sdram_xMutexPhore(0);
}

static void mem_sdram_unlock(void)
{
        MEMORY_Sdram_xMutexPhore(1);
}

// -----------------------------------------------------------------------------------
static void mem_dtcm_lock(void)
{
        MEMORY_Dtcm_xMutexPhore(0);
}

static void mem_dtcm_unlock(void)
{
        MEMORY_Dtcm_xMutexPhore(1);
}

/*
***********************************************************************************************************
内存初始化
***********************************************************************************************************
*/
void bsp_MemoryInit(void)
{
        uint8_t  *_addr1=0;

        MM_Create((void *)SRAM1_RT_ADDR,    BYTE_POOL_SRAM1_SIZE, MM_PIECE_SIZE_SET(BYTE_PIECE_SIZE), &_ctrl_struct_sram1);
        MM_Create((void *)SRAM4_RT_ADDR,    BYTE_POOL_SRAM4_SIZE, MM_PIECE_SIZE_SET(BYTE_PIECE_SIZE), &_ctrl_struct_sram4);
        MM_Create((void *)DTCMSRAM_RT_ADDR, BYTE_POOL_DTCM_SIZE,  MM_PIECE_SIZE_SET(BYTE_PIECE_SIZE), &_ctrl_struct_dtcm);
        MM_Create((void *)SDRAM_RT_ADDR,    BYTE_POOL_SDRAM_SIZE, MM_PIECE_SIZE_SET(BYTE_PIECE_SIZE), &_ctrl_struct_sdram);
       
        // 使用 os 系统,需要设置 加锁及解锁函数,如果没有使用 os 功能,则可以不用设置这个加锁及解锁功能函数
        MM_SetFunc_Lock(&_ctrl_struct_sram1, mem_1_lock,     mem_1_unlock);
        MM_SetFunc_Lock(&_ctrl_struct_sram4, mem_4_lock,     mem_4_unlock);
        MM_SetFunc_Lock(&_ctrl_struct_dtcm,  mem_dtcm_lock,  mem_dtcm_unlock);
        MM_SetFunc_Lock(&_ctrl_struct_sdram, mem_sdram_lock, mem_sdram_unlock);
       
        // 貌似第一次申请到的内存地址不是 8 字节对齐的,所以初始化完成后就申请一次
        _addr1 = (uint8_t  *)mymalloc(SDRAMEX,  4);
        _addr1 = (uint8_t  *)mymalloc(SRAM1,    4);
        _addr1 = (uint8_t  *)mymalloc(SRAM4,    4);
        _addr1 = (uint8_t  *)mymalloc(DTCMSRAM, 4);
        _addr1 = _addr1;
}


/*
**************************************************************************************************************
内存申请,释放测试, 貌似测试时是完全没有问题的还有播放 *.ape, *.wav, *.flac 音乐都是没有问题的,就唯独 mp3 不行 ??
使用其他 的 内存管理 程序时,播放 mp3 则是完全没有任何问题的
---------------------------------------------------
_sdram_addr1 = 0xD0D0000C
_sdram_addr2 = 0xD2500078   25,165,932
_sdram_addr3 = 0xD2500078
_sdram_addr4 = 0xD260032C
_sdram_addr1 = 0xD0D0000C

---------------------------------------------------
_sram1_addr1 = 0x3000000C
_sram1_addr2 = 0x30000C40
_sram1_addr3 = 0x30000C40
_sram1_addr4 = 0x3000205C
_sram1_addr1 = 0x3000000C

---------------------------------------------------
_dtcm_addr1 = 0x2000000C
_dtcm_addr2 = 0x20000C40
_dtcm_addr3 = 0x20000C40
_dtcm_addr4 = 0x2000205C
_dtcm_addr1 = 0x2000000C

---------------------------------------------------
**************************************************************************************************************
*/
void bsp_memory_demo(void)
{
//        uint32_t _free,block_max,block_cnt,mem_used;
        uint8_t  *_sdram_addr1=0;
        uint8_t  *_sdram_addr2=0;
        uint8_t  *_sdram_addr3=0;
        uint8_t  *_sdram_addr4=0;
       
        uint8_t  *_sram1_addr1=0;
        uint8_t  *_sram1_addr2=0;
        uint8_t  *_sram1_addr3=0;
        uint8_t  *_sram1_addr4=0;
       
        uint8_t  *_dtcm_addr1=0;
        uint8_t  *_dtcm_addr2=0;
        uint8_t  *_dtcm_addr3=0;
        uint8_t  *_dtcm_addr4=0;
       
        {
                _sdram_addr1 = (uint8_t  *)mymalloc(SDRAMEX, 1024*1024*24+58);
                _sdram_addr2 = (uint8_t  *)mymalloc(SDRAMEX, 1024*1024*3);

                SYS_MemoryDebug("_sdram_addr1 = 0x%X \r\n", _sdram_addr1);
                SYS_MemoryDebug("_sdram_addr2 = 0x%X \r\n", _sdram_addr2);
                myfree(SDRAMEX,_sdram_addr2) ;
               
                _sdram_addr3 = (uint8_t  *)mymalloc(SDRAMEX, 1024*1024+647);
                _sdram_addr4 = (uint8_t  *)mymalloc(SDRAMEX, 1024*5-275);
                SYS_MemoryDebug("_sdram_addr3 = 0x%X \r\n", _sdram_addr3);
                SYS_MemoryDebug("_sdram_addr4 = 0x%X \r\n", _sdram_addr4);
                myfree(SDRAMEX,_sdram_addr1) ;
                myfree(SDRAMEX,_sdram_addr3) ;
                myfree(SDRAMEX,_sdram_addr4) ;
               
                _sdram_addr1 = (uint8_t  *)mymalloc(SDRAMEX, 1024*1024*3+36);
                SYS_MemoryDebug("_sdram_addr1 = 0x%X \r\n", _sdram_addr1);
                myfree(SDRAMEX,_sdram_addr1) ;
                SYS_MemoryDebug("\r\n---------------------------------------------------\r\n");
        }
       
        {
                _sram1_addr1 = (uint8_t  *)mymalloc(SRAM1, 1024*3);
                _sram1_addr2 = (uint8_t  *)mymalloc(SRAM1, 1024*32+65);

                SYS_MemoryDebug("_sram1_addr1 = 0x%X \r\n", _sram1_addr1);
                SYS_MemoryDebug("_sram1_addr2 = 0x%X \r\n", _sram1_addr2);
                myfree(SRAM1,_sram1_addr2) ;
               
                _sram1_addr3 = (uint8_t  *)mymalloc(SRAM1, 1024*5);
                _sram1_addr4 = (uint8_t  *)mymalloc(SRAM1, 1024*5);
                SYS_MemoryDebug("_sram1_addr3 = 0x%X \r\n", _sram1_addr3);
                SYS_MemoryDebug("_sram1_addr4 = 0x%X \r\n", _sram1_addr4);
                myfree(SRAM1,_sram1_addr1) ;
                myfree(SRAM1,_sram1_addr3) ;
                myfree(SRAM1,_sram1_addr4) ;
               
                _sram1_addr1 = (uint8_t  *)mymalloc(SRAM1, 1024*3);
                SYS_MemoryDebug("_sram1_addr1 = 0x%X \r\n", _sram1_addr1);
                myfree(SRAM1,_sram1_addr1) ;
                SYS_MemoryDebug("\r\n---------------------------------------------------\r\n");
        }

        {
                _dtcm_addr1 = (uint8_t  *)mymalloc(DTCMSRAM, 1024*3);
                _dtcm_addr2 = (uint8_t  *)mymalloc(DTCMSRAM, 1024*32+57);

                SYS_MemoryDebug("_dtcm_addr1 = 0x%X \r\n", _dtcm_addr1);
                SYS_MemoryDebug("_dtcm_addr2 = 0x%X \r\n", _dtcm_addr2);
                myfree(DTCMSRAM,_dtcm_addr2) ;
               
                _dtcm_addr3 = (uint8_t  *)mymalloc(DTCMSRAM, 1024*5);
                _dtcm_addr4 = (uint8_t  *)mymalloc(DTCMSRAM, 1024*5);
                SYS_MemoryDebug("_dtcm_addr3 = 0x%X \r\n", _dtcm_addr3);
                SYS_MemoryDebug("_dtcm_addr4 = 0x%X \r\n", _dtcm_addr4);
                myfree(DTCMSRAM,_dtcm_addr1) ;
                myfree(DTCMSRAM,_dtcm_addr3) ;
                myfree(DTCMSRAM,_dtcm_addr4) ;
               
                _dtcm_addr1 = (uint8_t  *)mymalloc(DTCMSRAM, 1024*3);
                SYS_MemoryDebug("_dtcm_addr1 = 0x%X \r\n", _dtcm_addr1);
                myfree(DTCMSRAM,_dtcm_addr1) ;
                SYS_MemoryDebug("\r\n---------------------------------------------------\r\n");
        }

}





回复

使用道具 举报

38

主题

291

回帖

405

积分

高级会员

积分
405
发表于 2021-8-11 10:22:50 | 显示全部楼层
动态内存分配算法,推荐一下这个 https://github.com/mattconte/tlsf
实际项目中使用过,效果可以
回复

使用道具 举报

610

主题

3057

回帖

4907

积分

至尊会员

积分
4907
发表于 2021-8-11 11:53:40 | 显示全部楼层
wanglehui_12 发表于 2021-8-11 10:22
动态内存分配算法,推荐一下这个 https://github.com/mattconte/tlsf
实际项目中使用过,效果可以

好的,我试试看,多谢多谢啊
回复

使用道具 举报

2

主题

11

回帖

17

积分

新手上路

积分
17
 楼主| 发表于 2021-8-11 15:03:34 | 显示全部楼层
hpdell 发表于 2021-8-11 09:07
相关的应用函数

兄弟,目前我也没啥辙,只有通过调试看数据分析。或者可以把分配的内存比实际使用的大,你再试试。
回复

使用道具 举报

2

主题

11

回帖

17

积分

新手上路

积分
17
 楼主| 发表于 2021-8-11 15:11:40 | 显示全部楼层
hpdell 发表于 2021-8-11 09:07
相关的应用函数

但是信号量我是这么用的。没那么复杂。

初始化的时候先创建信号量,并赋值1
#if OS_ENABLE > 0
        OS_EVENT*  OSEvent_SysTimer;
        OSEvent_SysTimer = OSSemCreate(1);
#endif

void SysFun_TimerLock(void)
{
#if OS_ENABLE > 0
        INT8U err;
        OSSemPend(OSEvent_SysTimer, 0, &err);
#endif       
}
void SysFun_TimerUnlock(void)
{
#if OS_ENABLE > 0
        OSSemPost(OSEvent_SysTimer);
#endif
}

然后调用这个函数把加锁和解锁赋值给内存控制结构体
MM_SetFunc_Lock(MCB_StructDef *pStruct,void(*pLock)(void),void(*pUnlock)(void));
回复

使用道具 举报

2

主题

11

回帖

17

积分

新手上路

积分
17
 楼主| 发表于 2021-8-11 15:17:20 | 显示全部楼层
hpdell 发表于 2021-8-11 09:07
相关的应用函数

然后这个内存管理没有内存对齐。如果申请到的内存必须8字节对齐,这个要慎重。
回复

使用道具 举报

610

主题

3057

回帖

4907

积分

至尊会员

积分
4907
发表于 2021-8-11 16:48:31 | 显示全部楼层
wanglehui_12 发表于 2021-8-11 10:22
动态内存分配算法,推荐一下这个 https://github.com/mattconte/tlsf
实际项目中使用过,效果可以

你好,你提供的这个内存管理,貌似 移植到单片机上提示

#include <intrin.h>  这个头文件找不到啊 ?? 0110.png




回复

使用道具 举报

610

主题

3057

回帖

4907

积分

至尊会员

积分
4907
发表于 2021-8-11 16:49:15 | 显示全部楼层
lenyound 发表于 2021-8-11 15:17
然后这个内存管理没有内存对齐。如果申请到的内存必须8字节对齐,这个要慎重。

我再捣鼓试试看
回复

使用道具 举报

610

主题

3057

回帖

4907

积分

至尊会员

积分
4907
发表于 2021-8-12 10:05:44 | 显示全部楼层
wanglehui_12 发表于 2021-8-11 10:22
动态内存分配算法,推荐一下这个 https://github.com/mattconte/tlsf
实际项目中使用过,效果可以

你好,编译时出现 这个警告 ? 如下图框框里面的

2202-2.png


2202-1.png

size_t 类型定义:
2202-0.png

函数定义的参数为 size_t 这个,
static block_header_t* offset_to_block(const void* ptr, size_t size)

如上图里面提示上面的内容,是不是需要改成    ???
block = offset_to_block(mem,  0xFFFFFFFF - (tlsfptr_t)block_header_overhead);



回复

使用道具 举报

610

主题

3057

回帖

4907

积分

至尊会员

积分
4907
发表于 2021-8-17 15:54:42 | 显示全部楼层
本帖最后由 hpdell 于 2021-8-17 16:34 编辑
lenyound 发表于 2021-8-11 15:17
然后这个内存管理没有内存对齐。如果申请到的内存必须8字节对齐,这个要慎重。

修改成 8 字节对齐 终于成功了

#define HY_ALIGN_TYPE                 (sizeof(void *) * 2)

//内存片控制结构体
typedef struct
{
        void *pNext;                                                                                        //链表-指向下一个内存地址
        HY_U32 PieceSize;                                                                                //本内存片尺寸
        void *pPre;                                                                                                //链表-指向上一个内存地址
        
        //-------------------------------------------------------------------------
        HY_U32 *pNull;                                                                                //这个不使用,只是为了凑够 地址大小为 8 的倍数而已,增加了这个后 计算出 MPB_StructDef 这个的大小字节为 16 byte了
                                          //HY_U32 类型的,数据字节是 4字节, 相当于 uint32_t 的大小字节数
                                         // 这个地方貌似就是传说中的 占着茅坑不拉屎的节奏 ...
}MPB_StructDef;



// 内存申请 也捣鼓成 8 的倍数
void *MM_Get(MCB_StructDef *pStruct, HY_U32 MemSize)
{
        HY_U32  align_size;
        
        //是否有不合法的地方
        if ((MemSize == 0) || (pStruct == 0) || (pStruct->pUsableLink == 0))
        {
                return 0;
        }
        
        /* Round the memory size up to the next size that is evenly divisible by
                 an ALIGN_TYPE (this is typically a 32-bit ULONG).  This guarantees proper alignment.  
       */
        align_size   = MemSize % HY_ALIGN_TYPE;
        if(align_size > 0)  // 说明大小不是 HY_ALIGN_TYPE 这个的倍数,需要进行差值运算进行弥补
                MemSize   =  MemSize + (HY_ALIGN_TYPE - align_size);


    ... ....
}


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-8 19:52 , Processed in 0.749636 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表