RT-thread 之 你的RAM被写穿了

目录

一、引言:

二、实验环境

2.1、软件环境

2.2、硬件环境

三、实验内容简介

3.1 H750内存分布

3.2 问题实操

四、总结


一、引言:

       今天菜哥在搞项目的时候遇到了一个很神奇的问题,东问西问也没找到好的解决方案(实则是自己太菜了),后面听说是“内存被写穿了”?菜哥觉得这很神奇哇,内存还能被写穿了呢?进过一番折腾,项目也跑起来了,不过菜哥想在这里为大家提提“内存被写穿了”是怎么一会事情!(其实,最终还是由于自己的失误,造成了内存被写穿了)

二、实验环境

2.1、软件环境

RT-Thread studio,mobaxterm

2.2、硬件环境

ART-PI开发板、一根type-c数据线

三、实验内容简介

3.1 H750内存分布

首先我们来先说一说stm32H750d的RAM,H750的RAM分布就比较多啦,总共是分为5个部分,其中最大的连续区域是512KB,而我们使用的也就是这512KB内存空间;下图是H750的内存分布图

       从上面可以看出,STM32H7 的内存分成:ITCM、DTCM、AXI SRAM、SRAM1~4 等几个 部分,其中地址连续的区域分成 5 大块:ITCM(64KB)、DTCM(128KB)、AXI SRAM(512KB) 、SRAM1~3(288KB)和 SRAM4(64KB), 因为内存管理的内存池,必须是地址连续的内存 空间,因此,STM32H7 内部内存需要 5 个内存池来管理。

      另外,需要特别注意一下两点:

      第一点:ITCM 和 DTCM 这两个内存块,仅 CPU 和 MDMA 可以直接访问,其他外设不可以直 接访问!

      第二点:以太网的 DMA 描述符等必须是定义在 SRAM3 里面才可以正常工作,因此我们一般把 SRAM3(32KB)独立给以太网使用,并不用作内存管理!

3.2 问题实操

     下面我们来复原菜哥所遇到的问题现场,首先看一下出错的代码片段:

static void test_demo()
{
    char *str = (char*)"qwertyuiqw";

    char *pdata = NULL;

    pdata = (char*)rt_malloc(sizeof(char)*10);

    if(pdata == RT_NULL)
        return;

    sprintf(pdata, (char*)"user data:%s", str);

    rt_kprintf("str data:%s\n", pdata);

    rt_free(pdata);

}

我相信屏幕前机智的你肯定能看出来,这代码肯定是有问题的哇!明显pdata申请的内存空间不够呀!不错,的确是出错了,请看下面

出错的地方在rt_free这个地方,你在rt_malloc的时候, 是不会出错的,因为你还没有使用;但是你一旦使用完了之后,你再释放的时候就会出现一系列的问题了!比如这里的“内存被写穿了”!刚开始我怀疑是自己的堆空间开辟的太小了,导致没有足够的空间去分配了,后面才意识到是自己开辟的内存空间过小,放不小自己的数据,导致内存被写穿了,以至于出现上面的状况了!

       那有什么解决方法呢?针对我上面出现的问题啊,菜哥是有一种解决方法的!那就是把sprintf函数换成snprintf函数,snprintf函数多了一个参数,那就是能够限定写入的字符数据个数;具体的操作请看下面的代码!

static void test_demo()
{
    char *str = (char*)"qwertyuiqw";

    char *pdata = NULL;

    pdata = (char*)rt_malloc(sizeof(char)*10);

    if(pdata == RT_NULL)
        return;

    snprintf(pdata, 10, (char*)"user data:%s", str);
    //sprintf(pdata, (char*)"user data:%s", str);

    rt_kprintf("str data:%s\n", pdata);

    rt_free(pdata);

}

 

这样做,是不是会好一点呢,至少不会报错误,有的小伙伴会说,那你的数据没有完全写进去呀!是的我的数据是没有完全写进去,可是我能够通过输出的数据得出一个结论,那就是我申请的内存空间小了,我需要把它矿大一些;这样,我相信你能更快的解决问题,而不是漫无目的的去找错误的原因! 

四、总结

       最近,好久没有更新博客了,主要是在弄公司的项目,暂时没有时间写文章,这篇文章还是抽取空闲时间写的,稳重若是有写的不对的地方,欢迎大家在下方留言,博主是一个又菜又爱玩的人!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值