OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 1720|回复: 8

为何mymalloc会分配同一块内存?

[复制链接]

12

主题

74

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
337
金钱
337
注册时间
2014-10-30
在线时间
98 小时
发表于 2024-9-11 11:53:24 | 显示全部楼层 |阅读模式
原子哥和众兄弟好,最近调试H750板子,出现莫名BUG, 最后跟踪到是两个不同的指针在使用原子哥的函数(void*)mymalloc(SRAMIN ,size) 进行分配时,被分配到了同样的地址。其中一处指针是硬件初始化时申请内存,另一处是线程内模块初始化时申请内存。

为何会出现申请内存为同样地址呢? 请各位不吝赐教,多谢了
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

12

主题

74

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
337
金钱
337
注册时间
2014-10-30
在线时间
98 小时
 楼主| 发表于 2024-9-11 13:50:29 | 显示全部楼层
补充下,硬件初始化申请内存是不释放的,最先申请,线程内模块申请的是后面运行时申请,退出模块会释放。就是这个后面申请的指针与初始化时申请的重复了。非常奇怪。多谢各位!
回复 支持 反对

使用道具 举报

2

主题

446

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4133
金钱
4133
注册时间
2018-5-14
在线时间
902 小时
发表于 2024-9-11 16:11:27 | 显示全部楼层
szszjdb 发表于 2024-9-11 13:50
补充下,硬件初始化申请内存是不释放的,最先申请,线程内模块申请的是后面运行时申请,退出模块会释放。就 ...

rtos在有个全局buff用作heap,如果你的mymalloc的内存池和这个buff有重叠部分,那么这种情况不就正常了。如果两个池都是用uint8_t heap_buff[length]定义的话不会出这样的问题,内存由编译器给定,如果其中有一个是uint8_t* heap_buff=地址,这时候编译器是无法确定地址重叠的。
回复 支持 反对

使用道具 举报

12

主题

74

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
337
金钱
337
注册时间
2014-10-30
在线时间
98 小时
 楼主| 发表于 2024-9-11 17:01:11 | 显示全部楼层
姚先起 发表于 2024-9-11 16:11
rtos在有个全局buff用作heap,如果你的mymalloc的内存池和这个buff有重叠部分,那么这种情况不就正常了。 ...

多谢兄弟,
目前我也是用UCOS, 任务堆栈是静态分配,如 __align(8) static OS_STK MAIN_TASK_STK[MAIN_STK_SIZE]; 估计UCOS使用了系统堆区, 然后系统堆栈和堆都是在.S文件分配好的,如Heap_Size       EQU     0x0000f000
我使用了原子哥的内存管理系统,内存池都是静态数组,主要问题就是 mymalloc 两次分配会给出同样的地址,似乎跟HEAP没什么关系?
再次感谢!
回复 支持 反对

使用道具 举报

2

主题

446

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4133
金钱
4133
注册时间
2018-5-14
在线时间
902 小时
发表于 2024-9-12 08:33:08 | 显示全部楼层
szszjdb 发表于 2024-9-11 17:01
多谢兄弟,
目前我也是用UCOS, 任务堆栈是静态分配,如 __align(8) static OS_STK MAIN_TASK_STK[MAIN_ST ...

不明白你为啥要用正点的内存分配,rtos的malloc函数优化的比正点好多了,正点碎片太多了
回复 支持 反对

使用道具 举报

12

主题

74

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
337
金钱
337
注册时间
2014-10-30
在线时间
98 小时
 楼主| 发表于 2024-9-12 14:56:18 | 显示全部楼层
姚先起 发表于 2024-9-12 08:33
不明白你为啥要用正点的内存分配,rtos的malloc函数优化的比正点好多了,正点碎片太多了

一般RTOS不支持这么灵活的片内片外内存管理吧? 正点的简单,就几十行代码
回复 支持 反对

使用道具 举报

2

主题

446

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4133
金钱
4133
注册时间
2018-5-14
在线时间
902 小时
发表于 2024-9-12 16:35:42 | 显示全部楼层
szszjdb 发表于 2024-9-12 14:56
一般RTOS不支持这么灵活的片内片外内存管理吧? 正点的简单,就几十行代码

没有这个说法的,片外内存是因为链接脚本没有添加section所以定义数据和变量无法定义在外部,一般做法就是通过直接指定地址使用。
做法1:freertos可以魔改heap_4.c文件直接指定地址。
做法2:在keil sct文件添加外部ram的section(stmcube中修改stm32xxx.ld文件添加section),然后找到heap.c指定heapbuff到外部ram的section中。

stm32cube示例:
MEMORY
{
FLASH (rx)      : ORIGIN = 0x8000000, LENGTH = 1024K
RAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 192K
CCMRAM (rw)      : ORIGIN = 0x10000000, LENGTH = 64K
//外部ram
SDRAM (xrw)      : ORIGIN = 0xD0000000, LENGTH = 4M
}

//添加外部RAM的section
  _sidramdata = LOADADDR(.sdram);
  .sdram :
  {
     . = ALIGN(4);
     _sdramdata = .;   
     *(.sdram)
     . = ALIGN(4);
     _edramdata = .;
  } >SDRAM AT> FLASH

C 代码 heap_4.c 中:
uint8_t __attribute__((section(".sdram"))) ucHeap[ configTOTAL_HEAP_SIZE ];

//SDRAM初始化后执行把代码中定义的常量拷贝到SDRAM
extern unsigned int _sidramdata;
extern unsigned int _sdramdata;
extern unsigned int _edramdata;

static void LoopCopyDataInit(unsigned int* from, unsigned int* region_begin,
                                                   unsigned int* region_end)
{
          unsigned int *p = region_begin;
          while (p < region_end)
            *p++ = *from++;
}
void sdram_init(void)

{
   //初始化总线

//初始化时序

//拷贝常量
LoopCopyDataInit(&_sidramdata, &_sdramdata, &_edramdata);
}
回复 支持 反对

使用道具 举报

12

主题

74

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
337
金钱
337
注册时间
2014-10-30
在线时间
98 小时
 楼主| 发表于 2024-9-13 18:03:07 | 显示全部楼层
多谢兄弟,直接分配内存是可以将变量分配到各种内存,但是如果用MALLCO/FREE等动态函数就搞不懂了
回复 支持 反对

使用道具 举报

12

主题

74

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
337
金钱
337
注册时间
2014-10-30
在线时间
98 小时
 楼主| 发表于 2024-9-14 10:11:12 | 显示全部楼层
malloc/free之类默认只能用系统heap,所以无法动态分配到SDRAM等处吧?
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 08:44

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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