C++初始化程序上的Cortex M4硬故障

Cortex M4 Hard Fault on C++ Initializer

本文关键字:M4 硬故障 Cortex 初始化 程序上 C++      更新时间:2023-10-16

我有一个非常奇怪的问题。在我看来,这是一个已知的问题,但我找不到任何实际的解决方案,也找不到对它的任何可靠解释

这是我的设置:
主机:Win7 PC,充足的RAM
目标:STM32F303RE Cortex M4@64 MHz,在Nucleo32板上,集成ST-LINK 2.1
工具链:uVision V5.16
预处理器符号:USE_STDPERIPH_DRIVER、STM32F3303xE、__CPLUPLUS__FPU_PRESENT、__FPU_USED

其他控件:--C99-cpp

所有构建都很好。所有优化关闭。

问题出现在运行时。经过几次C++对象实例化后,处理器最终成为一个硬故障处理程序。具体在哪里?我已经通过拆分代码片段对此进行了标记。现在,我对C++细节和内部工作有点陌生,但听起来我和这个家伙有同样的问题:在Makefile 中更改源文件顺序导致/避免了分段故障

但也没有明确的解决办法。也许这不是C++实例化的错误。尽管没有找到解决方案。以下是我的程序的要点,它演示了这个问题:第一部分代码"看起来"运行得很好,直到我为您分离出的部分块为止。

#include"main.h"#包括"stm32f30x.h"#包括"stdint.h"#包括"stdio.h"#包括"string.h"#包括"math.h"#包括"usart.h"#包括"can.h"#包括"utils.h"#包括"led.h"#包括"i2c.h"#包括"sabertoth.h"#包括"FuzzyRule.h"#包括"FuzzyComposition.h"#包括"模糊.h"#包括"FuzzyRuleConsequent.h"#包括"模糊输出.h"#包括"FuzzyInput.h"#包括"FuzzyIO.h"#包括"FuzzySet.h"#包括"FuzzyRuleAntecedent.h"Fuzzy*Fuzzy=new Fuzzy();int main(void){/**************************************输入1************************************///rowWidth的两组"交叉坡道",即行的"公差"FuzzyInput*rowWidth=新的FuzzyInput(1);FuzzySet*lowTolerance=新的FuzzySet(0.0f,0.0f,0.0.0f,120.0f);rowWidth->addFuzySet(lowTolerance);FuzzySet*highTolerance=新的FuzzySet(0.0f,120.0f,120.09f,120.0 f);rowWidth->addFuzySet(highTolerance);fuzzy->addFuzyInput(rowWidth);USART1_puts("作为模糊输入添加的行宽度..");/**************************************输入2************************************///"R和L距离之差"的五个集合FuzyInput*distDiff=新的FuzyInput(2);FuzzySet*tooFarRight=新的FuzzySet(-60.0f,-60.0f、-54.0f、-30.0f);distDiff->addFuzySet(tooFarRight);FuzzySet*right=新的FuzzySet(-54.0f,-30.0f,30.0f,0.0f);distDiff->addFuzySet(右);FuzzySet*centered=新的FuzzySet(-30.0f,0.0f,0.0f,30.0f);distDiff->addFuzySet(居中);FuzzySet*left=新的FuzzySet(0.0f,30.0f,30.0ff,54.0f);distDiff->addFuzySet(左);FuzzySet*tooFarLeft=新的FuzzySet(30.0f,54.0f,60.0f,60.0 f);distDiff->addFuzySet(tooFarLeft);fuzzy->addFuzyInput(distDiff);USART1_puts("作为模糊输入添加的居中dist…");/**************************************输出1************************************/FuzzyOutput*motorSpeedDiff=新的FuzzyOutput(1);//可采用七种转向模式(近距离、窄距离、宽距离)模糊集*hardRight=新模糊集(-30.0f,-30.0f、-30.0f和-15.0f);motorSpeedDiff->addFuzySet(hardRight);USART1_puts("\thardRight");FuzzySet*lightRight=新的FuzzySet(-15.0f,-5.0f,-5..0f,0.0f);motorSpeedDiff->addFuzySet(lightRight);USART1_puts("\tlightRight")

这是我在终端"lightRight"中看到的最后一条串行消息硬故障发生在此行下一次调用新的FuzzySet()时。

FuzzySet*nomRight=新的FuzzySet(-30.0f,-15.0f,.15.0f,-5.0f);motorSpeedDiff->addFuzySet(nomRight);USART1_puts("\tnomRight");FuzzySet*lightLeft=新的FuzzySet(0.0f,5.0f,5.0f,15.0f);motorSpeedDiff->addFuzySet(lightLeft);USART1_puts("\tlightLeft");FuzzySet*goStraight=新的FuzzySet(-5.0f,0.0f,0.0f,5.0f);motorSpeedDiff->addFuzySet(goStraight);USART1_puts("\tgoStraight");模糊集*nomLeft=新模糊集(5.0f,15.0f,15.0 f,30.0f);motorSpeedDiff->addFuzySet(nomLeft);USART1_puts("\tnomLeft");FuzzySet*hardLeft=新的FuzzySet(15.0f,30.0f,30.0ff,30.0f);motorSpeedDiff->addFuzySet(hardLeft);USART1_puts("\thardLeft");fuzzy->addFuzyOutput(motorSpeedDiff);USART1_puts("添加电机转向作为模糊输出");lotsMoreSetupCode();而(1){USART1_puts("完成!");停止(1);//LED永远闪烁}}

很明显,我只是在做一堆模糊集,每个模糊集都是4个浮点的集合,但一个狂野的指针会飞到哪里?

这是FuzzySet.cpp中的构造函数:(我没有写的模糊逻辑库的一部分)这个SAME程序在Arduino上运行得很好,但在这个处理器上运行得不好。编译器的区别?

FuzzySet::FuzzySet(){
}
FuzzySet::FuzzySet(float a, float b, float c, float d){
this->a = a;
this->b = b;
this->c = c;
this->d = d;
this->pertinence = 0.0;
}

这听起来像是与其他上下文中其他静态声明的函数访问静态变量有关。

但我没有任何东西是静态的。

堆栈交换链接中有人说这可能是链接器故障。你同意吗?如何修复?

对实际发生的事情有什么想法吗?

我已经设置了一个很好的硬故障处理程序,它可以打印寄存器信息,但很明显,错误甚至发生在main()之前。因此,当事情变得混乱时,使用汇编代码似乎没有什么用处。

如何着手修复这个?感谢您的C++专业知识!

根据startup_stm32fxxx.s文件中使用的微控制器,尝试更改代码的堆和堆栈大小

这是的例子

;******************** (C) COPYRIGHT 2016 STMicroelectronics ********************
;* File Name          : startup_stm32f407xx.s
;* Author             : MCD Application Team
;* Version            : V2.4.3
;* Date               : 22-January-2016
;* Description        : STM32F407xx devices vector table for MDK-ARM toolchain. 
;*                      This module performs:
;*                      - Set the initial SP
;*                      - Set the initial PC == Reset_Handler
;*                      - Set the vector table entries with the exceptions ISR address
;*                      - Branches to __main in the C library (which eventually
;*                        calls main()).
;*                      After Reset the CortexM4 processor is in Thread mode,
;*                      priority is Privileged, and the Stack is set to Main.
;* <<< Use Configuration Wizard in Context Menu >>>   
;*******************************************************************************
; 
;* Redistribution and use in source and binary forms, with or without modification,
;* are permitted provided that the following conditions are met:
;*   1. Redistributions of source code must retain the above copyright notice,
;*      this list of conditions and the following disclaimer.
;*   2. Redistributions in binary form must reproduce the above copyright notice,
;*      this list of conditions and the following disclaimer in the documentation
;*      and/or other materials provided with the distribution.
;*   3. Neither the name of STMicroelectronics nor the names of its contributors
;*      may be used to endorse or promote products derived from this software
;*      without specific prior written permission.
;*
;* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
;* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
;* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
;* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
;* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
;* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
;* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
;* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
;* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
;* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
; 
;*******************************************************************************
; Amount of memory (in bytes) allocated for Stack
; Tailor this value to your application needs
; <h> Stack Configuration
;   <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
Stack_Size      EQU     0x200  ; <your stack size>
AREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem       SPACE   Stack_Size
__initial_sp

; <h> Heap Configuration
;   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
Heap_Size      EQU     0x400  ; <your heap size>
AREA    HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem        SPACE   Heap_Size
__heap_limit
PRESERVE8
THUMB

; Vector Table Mapped to Address 0 at Reset
AREA    RESET, DATA, READONLY
EXPORT  __Vectors
EXPORT  __Vectors_End
EXPORT  __Vectors_Size

堆栈的值由该行设置

Stack_Size      EQU     0x200  ; <your stack size>

和堆

Heap_Size      EQU     0x400  ; <your heap size>

在Keil uVision中,左下角还有两个选项卡,您可以在"文本编辑器"answers"配置向导"之间切换,以更改代码堆和堆栈大小。