[综合信息] 华大HC32F460 内存使用注意事项(内存bug)

[复制链接]
8837|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则出问题几率很大)。

watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAY3AxMzAw,size_20,color_FFFFFF,t_70,g_se,x_16.jpg



 楼主| 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个多小时测试,程序很稳定,现在主动编写一个测试代码测试,效果如下:


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

 楼主| 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 | 显示全部楼层
估计厂家也不知道这有坑,另外似乎国产的没有勘误手册,这个挺奇怪啊
zheng79 发表于 2021-10-22 23:25 来自手机 | 显示全部楼层
本帖最后由 zheng79 于 2021-10-22 23:27 编辑

楼主的测试程序有问题,u32 *p = (u32 *)0x1ffffff2,  地址不是4字节对齐,在任何arm芯片上都是不正确的。
xing650721 发表于 2021-10-22 23:45 来自手机 | 显示全部楼层
keil编译时,ARM结构的和51结构的u32的顺序是不一样
littlelida 发表于 2021-11-1 17:42 | 显示全部楼层
mark,
这个对我有点难,慢慢学习,也许后面遇到了问题,要回来看看
labasi 发表于 2021-11-4 10:52 | 显示全部楼层
有勘误手册说吗
wowu 发表于 2021-11-4 11:45 | 显示全部楼层
弱电的问题都比较难搞定
xiaoqizi 发表于 2021-11-4 11:46 | 显示全部楼层
内存还有bug?
木木guainv 发表于 2021-11-4 11:58 | 显示全部楼层
如何解决这个问题呢
labasi 发表于 2021-11-4 12:00 | 显示全部楼层
如何锁定出错位置呢
paotangsan 发表于 2021-11-4 12:00 | 显示全部楼层
如何选用对其方式呢
wubangmi 发表于 2021-11-8 15:01 | 显示全部楼层
对齐方式,不同的编译器有不同的方式,可以自行百度
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2415

主题

17754

帖子

21

粉丝
快速回复 在线客服 返回列表 返回顶部