当前位置: 首页 > ds >正文

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

最近调试HC32F460出现各种奇怪问题,程序不断的从不同位置崩溃,比如增加了堆栈大小(注意,是增加,而且是增加的足够大),修改了一些无关代码,增加了一个啥都不做的线程,等等都会导致程序各种异常,而且调试也找不出原因,表现为与内存溢出一样,内存无然无故变了,但是可以肯定是内存没有溢出,还有的内存竟然无法修改,修改后自己复原了,心里一万个曹尼玛,还有这样的单片机。

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

	
LR_IROM1 0x0010000 (416*1024)  {    ; load region size_regionER_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 4KBRW_IRAM4 0x200F0000 (4*1024)  {.ANY (Ret_SRAM)}
}

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

果然,上面发现SRAM3是不能直接当做堆栈使用,必须设置等待延时为1,好的,这个问题找到了,单独屏蔽SRAM3,使能SRAMH继续测试,结果还是会出现不定时的复位,注意是直接复位,不是硬件中断中的复位,此时我就怀疑是SRAMH与SRAM1不能跨区域直接访问,带着疑问继续测试。

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

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

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

 

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

 国产单片机任重道远呀,这些细节不告知,会玩死开发者的,今天加了一个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_regionER_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 4KBRW_IRAM4 0x200F0000 (4*1024)  {.ANY (Ret_SRAM)}
}

http://www.xdnf.cn/news/11422.html

相关文章:

  • 函数----ModifyStyle
  • STC15单片机自带的AD功能的使用
  • VirtualBox虚拟机网络设置(四种方式)
  • 两台电脑如何建立局域网?三种简便方法推荐
  • 运行程序提示access violation at address的解决方法
  • 阿姆达尔定律的演进:古斯塔夫森定律
  • Intel Developer Cloud - AI 模型性能评估
  • 【odoo15】在Action设置里增添一个自己的list
  • 多日之苦终得救:“威金”专杀工具发布(转)
  • 制作img镜像文件的5种方法
  • Matlab:自定义等高线图的填充颜色
  • 【贝加莱PLC基础教学】1.AutiomationStudio软件安装
  • viper4android fx 驱动,ViPER4Android FX 音效驱动社区版安
  • 前端知识2-CSS
  • 传奇私服架设(温故2002,自己制作传奇私服服务器)
  • MIPI 系列之 DCS
  • 软件可靠性、可维护性、可用性
  • 使用PowerDesigner设计数据库保姆级教程
  • 什么是android market?国内三大类android market知多少?
  • JSP内置对象:使用getparametervalues()获取数据
  • C# Span 入门
  • Extjs多标签关闭,支持关闭左侧和右侧标签。
  • 黑客是如何攻破一个网站的?
  • oracle常见问题、了解知识点及简单命令学习
  • 开源文档管理软件KnowledgeTree安装
  • Openbravo ERP介绍(一)
  • 分享88个ASP整站程序源码,总有一款适合您
  • 黑客是怎么通过IP地址攻击的?
  • Linux共享磁盘分区,linux中ISCSI(网络共享磁盘)
  • Windows server——部署web服务