STM32单片机

文章数:1121 被阅读:2938180

账号入驻

一个使用外部 SRAM 导致死机的案例

最新更新时间:2017-07-02
    阅读数:

问题:

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

调研:

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

结论:

软件中对 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 的初始化。


=================================

往期话题链接:

1、STM32L4中STOP2 模式下的漏电流分析

2、获取ST MCU技术资料及相关支持的方式与途径

3、STM32F30x ADC 采样的傅立叶变换示例

4、一个基于STM32 HID例程生成不多于64字节传输的示范

5、关于USB DFU IAP例程移植的两个话题

6、串口工作在DMA模式下有时接收异常的案例分享



最新有关STM32单片机的文章

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: TI培训

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved