tpgf 发表于 2021-10-1 18:18

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

最近调试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

估计厂家也不知道这有坑,另外似乎国产的没有勘误手册,这个挺奇怪啊

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

对齐方式,不同的编译器有不同的方式,可以自行百度
页: [1]
查看完整版本: 华大HC32F460 内存使用注意事项(内存bug)