打印
[综合信息]

华大HC32F460 内存使用注意事项(内存bug)

[复制链接]
7834|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tpgf|  楼主 | 2021-10-1 18:18 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
最近调试HC32F460出现各种奇怪问题,程序不断的从不同位置崩溃,比如增加了堆栈大小(注意,是增加,而且是增加的足够大),修改了一些无关代码,增加了一个啥都不做的线程,等等都会导致程序各种异常,而且调试也找不出原因,表现为与内存溢出一样,内存无然无故变了,但是可以肯定是内存没有溢出,还有的内存竟然无法修改,修改后自己复原了,心里一万个曹尼玛,还有这样的单片机。

但是通过两天的调试,最后怀疑可能是内存问题,之前发现HC32无法使用1,2,1这种方式对齐访问,而其他单片机则不影响,带着怀疑测试,将SRAMH与SRAM3屏蔽掉(不让编译器使用)


        
LR_IROM1 0x0010000 (416*1024)  {    ; load region size_region
  ER_IROM1 0x0010000 (416*1024)  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
   .ANY (+XO)
  }


  RW_IRAM3 0x20020000 (28*1024)  {  ; RW data SRAM3 28KB 支持ECC
  ; .ANY (+RW +ZI)
   .ANY (IRAM3)
  }

  RW_IRAM2 0x20010000 (64*1024)  {  ; RW data SRAM2 64KB
   .ANY (+RW +ZI)
   .ANY (IRAM2)
  }

  RW_IRAM1 0x20000000 (64*1024)  {  ; RW data SRAM1 64KB
   .ANY (+RW +ZI)
   .ANY (IRAM1)
  }


  ;SRAMH内存,高速内存;
  RW_IRAMH 0x1FFF8000 (32*1024)  {
  ; .ANY (+RW +ZI)
   .ANY (SRAMH)
  }
  ;Ret_SRAM 掉电保持SRAM 4KB
  RW_IRAM4 0x200F0000 (4*1024)  {
   .ANY (Ret_SRAM)
  }
}

注意,上面的SRAMH与IRAM3都没有被使用,这个时候程序奇迹般正常了,测试了很久都正常(之前也是没有开启SRAMH与IRAM3),最近才开启的,出现各种奇怪问题,带着疑问找资料(其实通过2天测试,发现UCOS如果分配的内存空间在IRAM3或者SRAMH则出问题几率很大)。



使用特权

评论回复
沙发
tpgf|  楼主 | 2021-10-1 18:19 | 只看该作者
果然,上面发现SRAM3是不能直接当做堆栈使用,必须设置等待延时为1,好的,这个问题找到了,单独屏蔽SRAM3,使能SRAMH继续测试,结果还是会出现不定时的复位,注意是直接复位,不是硬件中断中的复位,此时我就怀疑是SRAMH与SRAM1不能跨区域直接访问,带着疑问继续测试。


RW_IRAMH 0x1FFF8000 (32*1024-8)  {
   .ANY (+RW +ZI)
   .ANY (SRAMH)
  }
  ;Ret_SRAM 掉电保持SRAM 4KB
  RW_IRAM4 0x200F0000 (4*1024)  {
   .ANY (Ret_SRAM)
  }



将SRAMH故意去掉8字节,让内存不连续,这样避免了连续的内存分配,继续测试。

通过1个多小时测试,程序很稳定,现在主动编写一个测试代码测试,效果如下:



通过测试发现,如果SRAMH与SRAM1连续访问的时候,是32bit对齐的,则无任何问题,一旦出现非对齐访问,那就对不起了,这个值不知道如何产生的,果然有些坑还是要自己去规避的。


使用特权

评论回复
板凳
tpgf|  楼主 | 2021-10-1 18:20 | 只看该作者
国产单片机任重道远呀,这些细节不告知,会玩死开发者的,今天加了一个u16 a;结果程序异常,明天改了一个变量,结果程序异常,却找不到任何原因,而且会导致一个还未执行的代码影响到了前面执行的代码(内存分配顺序变动了),文档中SRAMH可以以最高速度执行,却还可以设置访问周期,而且不告知怎么设置也是醉了。

好了,上面就是我最近遇到的坑,大家请绕行吧,下面是最终的解决办法。


; V6: armclang
#! armclang --target=arm-arm-none-eabi -mcpu=cortex-m4 -E -x c
;使用了ARM V6编译器后无法使用宏定义设置ROM起始地址与大小,需要手动修改
; V5: armcc
;#! armcc -E
#include "BaseSetting.h"

       
LR_IROM1 0x0010000 (416*1024)  {    ; load region size_region
  ER_IROM1 0x0010000 (416*1024)  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
   .ANY (+XO)
  }

  ;如果使用IRAM3作为堆栈,则至少需要设置1个读写等待周期,此处就不用这个内存做堆栈,用于用户自定义内存区域
  RW_IRAM3 0x20020000 (28*1024)  {  ; RW data SRAM3 28KB 支持ECC
  ; .ANY (+RW +ZI)
   .ANY (IRAM3)
  }

  RW_IRAM2 0x20010000 (64*1024)  {  ; RW data SRAM2 64KB
   .ANY (+RW +ZI)
   .ANY (IRAM2)
  }

  RW_IRAM1 0x20000000 (64*1024)  {  ; RW data SRAM1 64KB
   .ANY (+RW +ZI)
   .ANY (IRAM1)
  }


  ;SRAMH内存,高速内存;不要使用SRAMH作为代码执行区域,然后故意少给8字节,避免与IRAM1连续,也避免了可能存在的非对齐跨区域访问异常
  RW_IRAMH 0x1FFF8000 (32*1024-8)  {
   .ANY (+RW +ZI)
   .ANY (SRAMH)
  }
  ;Ret_SRAM 掉电保持SRAM 4KB
  RW_IRAM4 0x200F0000 (4*1024)  {
   .ANY (Ret_SRAM)
  }
}



使用特权

评论回复
地板
zchong| | 2021-10-7 20:57 | 只看该作者
估计厂家也不知道这有坑,另外似乎国产的没有勘误手册,这个挺奇怪啊

使用特权

评论回复
5
zheng79| | 2021-10-22 23:25 | 只看该作者
本帖最后由 zheng79 于 2021-10-22 23:27 编辑

楼主的测试程序有问题,u32 *p = (u32 *)0x1ffffff2,  地址不是4字节对齐,在任何arm芯片上都是不正确的。

使用特权

评论回复
6
xing650721| | 2021-10-22 23:45 | 只看该作者
keil编译时,ARM结构的和51结构的u32的顺序是不一样

使用特权

评论回复
7
littlelida| | 2021-11-1 17:42 | 只看该作者
mark,
这个对我有点难,慢慢学习,也许后面遇到了问题,要回来看看

使用特权

评论回复
8
labasi| | 2021-11-4 10:52 | 只看该作者
有勘误手册说吗

使用特权

评论回复
9
wowu| | 2021-11-4 11:45 | 只看该作者
弱电的问题都比较难搞定

使用特权

评论回复
10
xiaoqizi| | 2021-11-4 11:46 | 只看该作者
内存还有bug?

使用特权

评论回复
11
木木guainv| | 2021-11-4 11:58 | 只看该作者
如何解决这个问题呢

使用特权

评论回复
12
labasi| | 2021-11-4 12:00 | 只看该作者
如何锁定出错位置呢

使用特权

评论回复
13
paotangsan| | 2021-11-4 12:00 | 只看该作者
如何选用对其方式呢

使用特权

评论回复
14
wubangmi| | 2021-11-8 15:01 | 只看该作者
对齐方式,不同的编译器有不同的方式,可以自行百度

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1897

主题

15568

帖子

11

粉丝