0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

memheap死机问题的分析与解决

冬至子 来源:张世争 作者:张世争 2023-06-07 14:56 次阅读

验证环境

NUCLEO-L476RG 开发板,板载 STM32L476RGT6(96K SARM1 + 32K SRAM2)

Win10 64 位

Keil MDK 5.36

RT-Thread 5.0.1 版本(2023-05-28 master 主线)

bsp : bsp\\stm32\\stm32l476-st-nucleo

功能描述

最近在研究 RT-Thread 内存的管理,熟悉了一下 memheap 的功能实现,并且了解到 memheap 支持多块内存(物理地址不连续)的管理,当开启 memheap 后,rt_malloc 可以遍历所有注册过的 memheap 内存块,并且进行 内存的申请与释放。

当前 STM32L476RGT6 支持两块 SRAM,其中 SRAM1 96KB,还有一块 SRAM2 32KB,SRAM2 默认没有使用,尝试开启 SRAM2

环境搭建

stm32l476-st-nucleo 开启 memheap 的方法

1.jpg

stm32l476-st-nucleo 开启 SRAM2 的方法

#define HEAP_SRAM2_BEGIN (0x10000000)

#define HEAP_SRAM2_SIZE (32 * 1024)

static struct rt_memheap memheap_sram2;

int system_sram2_init(void)

{

return rt_memheap_init(&memheap_sram2, "sram2", (void *)HEAP_SRAM2_BEGIN, (rt_size_t)HEAP_SRAM2_SIZE);

}

INIT_BOARD_EXPORT(system_sram2_init);

功能测试

写两个测试命令:一直申请内存直到无法申请内存,一直释放所以申请的内存,确认 rt_malloc 会自动到新增加的 memheap SRAM2 中申请内存

功能验证通过,但是遇到死机问题

测试的函数

void *user_alloc(rt_size_t size)

{

return rt_memheap_alloc(&memheap_sram2, size);

}

void user_free(void *ptr)

{

rt_memheap_free(ptr);

}

void user_alloc_test(void)

{

for (int i = 0; i < MEMHEAP_BLOCK_NUM; i++)

{

user_ptr[i] = user_alloc(500);

if (!user_ptr[i])

{

rt_kprintf("malloc failed, index = %d\\n", i);

return;

}

else

{

rt_kprintf("[%d] : 0x%08x\\n", i, user_ptr[i]);

}

}

}

MSH_CMD_EXPORT(user_alloc_test, user_alloc_test);

void user_free_test(void)

{

for (int i = 0; i < MEMHEAP_BLOCK_NUM; i++)

{

if (user_ptr[i])

{

rt_kprintf("[%d] : 0x%08x\\n", i, user_ptr[i]);

user_free(user_ptr[i]);

}

}

}

MSH_CMD_EXPORT(user_free_test, user_free_test);

死机的信息

1.jpg

死机后,打印线程,发现 idle 线程栈异常

1.jpg

开启 CmBacktrace 组件后,发现死机的问题不是固定的,申请申请一个小内存,都会触发异常

问题分析

idle 线程的结构数据被破坏了,这就说明,内存越界了,但是测试例程只调用了 RT-Thread memheap 的 内存申请与释放 API,并没有其他的操作

手动申请一块内存,没有触发死机, list thread 发现,idle 线程的栈数据,依旧是异常的!

1.jpg

由于 开发板可以 单步调试,所以经过单步调试,加上分析,确认内存的范围,各个线程栈的内存范围,发现了一个奇怪的问题: 申请的内存偶尔会与线程栈的【静态内存】重叠

由于死机问题并不是必现,但是 idle 线程栈数据异常是必现的。当前怀疑 memheap 的内存范围设置存在问题,通过对比其他开发板的 bsp,发现了问题所在。

原来 bsp stm32l476-st-nucleo 系统的内存 HEAP_BEGIN 设置有问题,直接设置的 第一块内存的起始地址:

#define STM32_SRAM1_START (0x20000000)

#define HEAP_BEGIN STM32_SRAM1_START

初步看上去好像没有问题,其实RT-Thread 开机后,静态的内存数据、线程栈,依旧会占用一些内存,也就是其实内存地址,不能设置为 STM32_SRAM1_START,而是 【剩余内存】

【剩余内存】或者叫【空闲内存】的获取方法如下:

#if defined(__ARMCC_VERSION)

extern int Image$$

RW_IRAM1

ZI

Limit;

#define HEAP_BEGIN ((void *)&Image

RW_IRAM1

ZI

Limit)
#elif ICCARM
#pragma section="CSTACK"
#define HEAP_BEGIN (__segment_end("CSTACK"))
#else
extern int __bss_end;
#define HEAP_BEGIN ((void *)&__bss_end)
#endif
如在 Keil MDK5 上,是 #define HEAP_BEGIN ((void *)&Image

RW_IRAM1

ZI$$Limit), 也就是 SRAM1 的 剩余内存作为系统 堆内存使用,而不是 SRAM1 的全部内存作为 堆内存使用

解决方法

如上,重新设置 HEAP_BEGIN 即可

编译发现 RW_IRAM1 不存在,需要修改链接文件:bsp\\stm32\\stm32l476-st-nucleo\\board\\linker_scripts\\link.sct,增加 RW_IRAM1 的定义

1.jpg

RW_IRAM1 0x20000000 0x00018000 { ; RW data

.ANY (+RW +ZI)

}

以上修改后,memheap 内存测试通过,不再触发死机

小结

memheap 使用起来还是比较的简单,可以通过设置 开启 RT_USING_MEMHEAP_AUTO_BINDING,也就是 勾选 [*] Use all of memheap objects as heap,决定新增加的 memheap 的内存是否参与系统常规的内存管理,如 rt_malloc、rt_free

用户可以单独的实现自己的 memheap 内存块 alloc、free 函数,这样只操作特定的 memheap。

当前的一个小缺点:如果 memheap 内存块较多,超过2个,如 RAM1、RAM2、RAM3,并且开启了 [*] Use all of memheap objects as heap,想实现 RAM1与 RAM2 作为系统通用内存管理,RAM3 用户专用内存管理,那么当前的 memheap 机制做不到,因为 rt_malloc 依旧会在 RAM1、RAM2 不能申请内存时,去 RAM3 申请内存。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • RAM
    RAM
    +关注

    关注

    8

    文章

    1368

    浏览量

    114651
  • SRAM芯片
    +关注

    关注

    0

    文章

    65

    浏览量

    12059
  • RT-Thread
    +关注

    关注

    31

    文章

    1285

    浏览量

    40095
  • STM32L476
    +关注

    关注

    0

    文章

    7

    浏览量

    3781
收藏 人收藏

    评论

    相关推荐

    求解,rtthread内存管理部分memheap使用问题讨论

    rtthread中源码这部分memheap我看官方文档中都说的很模糊,也没有做过多的解释说明,这个对于新手去使用这部分功能十分不友好,这里我有几点看法和大家交流下,也先挖个坑占个位置。1.内存连续
    发表于 04-19 09:34

    讲解使用memheap内存管理算法对内部RAM和片外的SDRAM进行管理的方法

    if (ptr != RT_NULL) break;} } ... ... // 省去分析无关代码 return ptr;}  分析上述源码我们可以看到首先调用了 rt_memheap
    发表于 05-11 14:45

    请问rt_memheap_free引起的死机该如何解决呢?

    我使用了rtthread v4.0.4版本的内核,并且开启了RT_USING_MEMHEAP和RT_USING_MEMHEAP_AS_HEAP本来是将内部ram和sdram合并成一个大的ram空间
    发表于 02-08 11:16

    rt_memheap_init初始化外部sram死机是何原因呢?

    的 //rt_memheap_init(&Strucmem,"memexram", rt_heap_exram,打开,即只要一初始化片外sram 就会死机,我该如何查呢 ?其中,片外sram 使用的fsmc 驱动
    发表于 02-20 15:09

    路由器死机掉线问题原因分析

    路由器死机掉线问题原因分析 今天,作者就对宽带路由器死机掉线问题进行客观分析,看看到底是什么原因造成了这些问题。
    发表于 10-20 09:21 1117次阅读

    手机死机的原因有哪些?

    手机死机的原因有哪些? 我们对电脑的死机蓝屏都习以为常,死机以后无非就是热启或者是RESET,但是我们对手机的死机常常抱怨,
    发表于 10-26 16:32 4034次阅读

    笔记本重启/死机 五项分析以及对策

    笔记本重启/死机 五项分析以及对策 电脑包括笔记本电脑重启和死机故障,都是电脑维修过程中的热点问题,其中牵涉到的问题也
    发表于 01-19 11:00 359次阅读

    路由器死机的原因分析

      本文主要给大家总结了路由器死机的四大类主要原因,并且就针对不同的问题给出了不同的解答,相信看过此文会对你以后解决死机问题有所帮助。   路由器死机
    发表于 08-19 11:53 472次阅读

    电脑死机问题分析

      从电脑出现至今就一直被死机伴随着,几乎没有谁的电脑从不遭遇死机。在使用过程中,偶尔一次死机应该算是正常现象,如果经常死机,电脑就存在一定的问题了。那么,
    发表于 08-19 14:51 608次阅读

    Linux系统死机的软硬件问题分析

      系统出现死机,一般分为两种情况:一是硬件问题;二是软件问题。   一、硬件问题   可以考虑分析以下几点:   1、不要超频CPU,如果已经超
    发表于 09-25 10:57 2220次阅读

    工控机死机现象分析

    死机是工控机故障中较为常见的一种,同时它也是最令人头疼的一种。因为其故障点可大可小,而且产生死机的原因有很多种,另外其故障现象也是多种多样的,我们可以把故障现象总的归为两大类一一规律性死机和随机性
    发表于 10-23 14:10 11次下载

    PLC死机的软件或硬件原因分析

    plc运行时可能会出现死机的情况,这给工业生产造成不可预估的损失,因此,首先要了解PLC死机的原因,针对原因进行排查,软件或硬件错误都有可能导致PLC死机
    发表于 03-24 09:12 2949次阅读

    RT-Thread 学习笔记:memheap 死机问题的分析与解决

    memheap 的功能实现,并且了解到 memheap 支持多块内存(物理地址不连续)的管理,当开启 memheap 后,rt_malloc 可以遍历所有注册过的 memheap
    的头像 发表于 05-29 18:05 1848次阅读
    RT-Thread 学习笔记:<b class='flag-5'>memheap</b> <b class='flag-5'>死机</b>问题的<b class='flag-5'>分析</b>与解决

    变量位置不同会死机?郭天祥老师视频的遗留问题分析答案

    在郭天祥老师视频里有一个问题分享,是EXMC初始化里的一个变量定义和初始化位置不同会导致程序死机,最终定位到程序是进入hardfault死机,但暂时没有后续分析了,这里我们来继续分析
    的头像 发表于 02-26 09:12 363次阅读
    变量位置不同会<b class='flag-5'>死机</b>?郭天祥老师视频的遗留问题<b class='flag-5'>分析</b>答案

    Air780E/Air780EP/Air780EQ/Air201模块遇到内存死机如何分析

    Air780E/Air780EP/Air780EQ/Air201模块遇到内存死机如何分析简介本文档适用于合宙Air780E、Air780EP、Air780EQ、Air201关联文档和使用工具:移芯
    的头像 发表于 07-19 16:07 522次阅读
    Air780E/Air780EP/Air780EQ/Air201模块遇到内存<b class='flag-5'>死机</b>如何<b class='flag-5'>分析</b>