STM32F407IGT6使用外部SRAM导致死机该如何解决

2019-08-13 16:34:10

该问题由某客户提出,发生在 STM32F407IGT6 器件上。据其工程师讲述:为了满足软件对大容量内存的需求,将软件中的部分变量从内部 SRAM 转移到片外的 SRAM当中。而这一改变,导致该软件不能运行,每次复位后,随即发生死机。在此之前,对 FSMC 的初化代码,以及片外SRAM 的读写均做过测试,并确认是没有问题的。其内存分配如下表(一)所示。
sram内存分配表
调研:
 
使用 Keil MDK 创建工程,测试其所用的FSMC 初始化代码,结果表明该段代码正确无误。修改内存分配,删除其中对外部 SRAM 的分配,如下表(三)所示。重新对其软件编译运行。结果表明,在这种内存分配方式下,其软件可以正常运行。修改其软件代码,在初始化FSMC 之后加入对外部 SRAM 的读写测试,重新编译运行。测试结果表明,此时对外部SRAM 的读写也是正确的。查找其软件对 FSMC 初始化函数调用的位置,发现该函数是在该软件的main()函数中调用的。修改代码,将该函数的调用位置移至 SystemInit()中,并且恢复原来的内存分配,如上表(一)。重新编译并运行,此时该软件正确运行。
sram内存分配表2

结论:
 
软件中对 FSMC 做初始化的位置不对,导致程序在访问外部SRAM时 FSMC 还未被初始化,从而造成总线访问出错,从而产生 HardFault 中断,最终程序停留在 HardFault中断服务程序中,使得程序对外表现出“死机”的现象。
 
处理:
 
一般来说, main()函数是 C 语言的入口,C 语言代码从这里开始执行。然而,具体结合到STM32的应用工程,这并不是工程运行的起点。往往在main()函数执行之前,还有一段启动初始化代码,为硬件做最基本的时钟和中断矢量配置等;为 C 语言代码的执行创建一个运行环境。这里主要涉及两个函数,即SystemInit()和__main()。其中__main()是编译系统提供的一个函数,负责完成C库函数和应用程序执行环境的初始化,之后跳转到用户main()。在__main()做 C 环境初始化的时候,会访问相关的存贮器。如果此时,相应的存贮器不可用,就会出现错误。在STM32启动的文件里,SystemInit()函数先于__main()的执行。所以,如果在SystemInit()函数里先对 FSMC 的做好初始化就可以避免后面__main()运行时访问相关内存出现异常的问题。
 
修改代码,将对 FMSC 初始化函数的调用放在SystemInit()函数中,以保证在 C 环境初始化之前完成对FMSC 的初始化。

本文关键词:SRAM


相关文章:VTI508NL16低功耗SRAM芯片


深圳市英尚微电子有限公司是一家专业的静态随机记忆体产品及方案提供商,十年来专业致力代理分销存储芯片IC, SRAM、MRAM、pSRAM、 FLASH芯片、SDRAM(DDR1/DDR2/DDR3)等,为客人提供性价比更高的产品及方案。
英尚微电子中国区指定的授权代理:VTI、NETSOL、JSC济州半导体(EMLSI)、Everspin 、IPSILOG、LYONTEK、ISSI、CYPRESS、ISOCOME、PARAGON、SINOCHIP、UNIIC; 著名半导体品牌的专业分销商  如:RAMTROM、ETRON、FUJITSU、LYONTEK、WILLSEMI。
 

​更多资讯关注SRAMSUN.   www.sramsun.com         0755-66658299

技术支持