打印
[信息]

【实战经验】使用外部 SRAM 导致死机

[复制链接]
1266|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 香水城 于 2017-8-17 14:01 编辑

使用外部 SRAM 导致死机

问题:
该问题由某客户提出,发生在 STM32F407IGT6 器件上。据其工程师讲述:为了满足软件对大容量内存的需求,将软件中的部变量从内部 SRAM 转移到片外的 SRAM当中。而这一改变,导致该软件不能运行,每次复位后,随即便发生死机。在此之前,对 FSMC 的初化代码,以及片外 SRAM 的读写匀做过测试,并确认是没有问题的。其内存分配如表(一)所示,FSMC 的初始化代码如表(二)所示。

调研:
使用 Keil MDK 创建工程,测试其所用的 FSMC 初始化代码,结果表明该段代码正确无误。修改内存分配,删除其中对外部 SRAM 的分配,如表(三)所示。重新对其软件编译,运行,结果表明,在这种内存分配方式下,其软件可以正常运行。修改其软件代码,在初始化 FSMC 之后加入对外部 SRAM 的读写测试,重新编译运行。测试结果表明,此时对外部 SRAM 的读写是正确的。查找其软件对 FSMC 初始化函数调用的位置,发现该函数是在该软件的 main()函数中调用的。修改代码,将该函数的调用位置移至 SystemInit()中,并且恢复原来的内存分配,如表(一)。重新编译并运行,此时该软件可以正确的运行。

结论:
软件中对 FSMC 做初始化的位不对,导致程序在访问外部 SRAM 时 FSMC 还未被初始化,从而造成总线访问出错,从而产生 Hard Fault 中断,最终程序流程停留在 Hard Fault中断服务程序中,使得程序对外表出“死机”的现象。

处理:
修改软件,将对 FMSC 初始化函数的调用位置放在 SystemInit()函数中,以保证在 C 语言初始化之前完成对 FMSC 的初始化。

建议:
一般来说 main()函数是 C 语言的入口函数,C 语言代码从这里开始执行。然而,整个应用程序的执行起点却不是这里。通常在 main()函数执行之前,要有一段初始化代码,为 C 语言代码的执行创建一个运行环境。比如要对 C 语言代码所使用的内存清零,还要对 C 语所定义的全局变量、静态变量付初值等等。这段初始化代码是由 C 语言开发工具中的链接器(Linker)加到应用程序当中的。它在做 C 语言运行环境初始化的时候,会访问相关的存贮器。如果此时,对应的存贮器不可用,就会出现错误。所以,对 FSMC 的初始化一定要在 C 语言运行环境初始化之前完成。在 ST 的标准外设库中给出的工程模板中,有一个能在 C 语言初始化之前得以执行的函数,就是 SystemInit()函数。于是,可以把有以上要求的初始化函数,在该函数中调用。因为 SystemInit()函数是在 C 语言初始化之前执行,所以,如果该函数,或者被该函数调用的函数中使用了全局变量或者静态变量,只能自行付初值,否则这些变量的初值是随机的。

对应的pdf:使用外部 SRAM 导致死机
更多实战经验请看:【ST MCU实战经验汇总贴】


沙发
mark0668| | 2015-8-13 11:09 | 只看该作者
感谢分享,学习了

使用特权

评论回复
板凳
lanjackg2003| | 2015-8-13 11:12 | 只看该作者
mark,学习了

使用特权

评论回复
地板
songchenping| | 2015-8-13 12:10 | 只看该作者
学习了。

使用特权

评论回复
5
mmuuss586| | 2015-8-13 19:04 | 只看该作者

谢谢分享;

使用特权

评论回复
6
橙子0_0| | 2021-3-30 21:32 | 只看该作者
学习了

使用特权

评论回复
7
香水城|  楼主 | 2021-3-30 22:08 | 只看该作者

#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
/**
  * @brief  Setup the external memory controller.
  *         Called in startup_stm32f4xx.s before jump to main.
  *         This function configures the external memories (SRAM/SDRAM)
  *         This SRAM/SDRAM will be used as program data memory (including heap and stack).
  * @param  None
  * @retval None
  */
void SystemInit_ExtMemCtl(void)
{
  __IO uint32_t tmp = 0;
#if defined (DATA_IN_ExtSDRAM) && defined (DATA_IN_ExtSRAM)
  register uint32_t tmpreg = 0, timeout = 0xFFFF;
  register uint32_t index;

使用特权

评论回复
评论
橙子0_0 2021-3-31 13:12 回复TA
香版主,我使用的是stm32H755芯片,库使用的是HAL库,没有找到这个函数,有相关历程吗 
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:意法半导体(中国)投资有限公司
简介:STM32技术专家

596

主题

17108

帖子

288

粉丝