繁体   English   中英

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

[英]Cortex M4 Hard Fault on C++ Initializer

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

这是我的设置:
主机: Win7 PC,大量内存。
目标:采用集成ST-LINK 2.1的Nucleo32板上的STM32F303RE Cortex M4 @ 64 MHz
工具链: uVision V5.16
预处理器符号: USE_STDPERIPH_DRIVER,STM32F303xE,__ CPLUSPLUS__FPU_PRESENT,__ FPU_USED

其他控件: - C99 --cpp

一切都很好。 关闭所有优化。

问题出在运行期间。 在几个C ++对象实例化之后,处理器最终进入硬件处理程序。 到底在哪里? 我已经通过拆分我的代码片段来标记这一点。 现在,我对C ++细节和内部工作有点新鲜,但听起来我和这个bloke有同样的问题: 在Makefile中更改源文件顺序导致/避免了分段错误

但是,解释不清楚的解决方案。 也许这不是C ++实例化的错误。 虽然找不到解决方案。 这是我的程序的要点,它演示了这个问题:第一部分代码“看起来”运行良好,直到我已经分开的部分块供你注意。

#include "main.h"
    #include "stm32f30x.h"
    #include "stdint.h"
    #include "stdio.h"
    #include "string.h"
    #include "math.h"
    #include "usart.h"
    #include "can.h"
    #include "utils.h"
    #include "led.h"
    #include "i2c.h"
    #include "sabertooth.h"

    #include "FuzzyRule.h"
    #include "FuzzyComposition.h"
    #include "Fuzzy.h"
    #include "FuzzyRuleConsequent.h"
    #include "FuzzyOutput.h"
    #include "FuzzyInput.h"
    #include "FuzzyIO.h"
    #include "FuzzySet.h"
    #include "FuzzyRuleAntecedent.h"

    Fuzzy* fuzzy = new Fuzzy();

    int main(void)
    {
      /*************************************
       * Input 1
       ************************************/
      // Two "crossing ramp" sets for rowWidth i.e. "tolerance" of the row
      FuzzyInput* rowWidth = new FuzzyInput(1);

      FuzzySet* lowTolerance  = new FuzzySet(0.0f, 0.0f, 0.0f, 120.0f);
      rowWidth->addFuzzySet(lowTolerance);
      FuzzySet* highTolerance = new FuzzySet(0.0f, 120.0f, 120.0f, 120.0f);
      rowWidth->addFuzzySet(highTolerance);

      fuzzy->addFuzzyInput(rowWidth);
      USART1_puts("row width added as fuzzy input..");

      /*************************************
       * Input 2
       ************************************/
      // Five Sets for "difference between R and L distances"
      FuzzyInput* distDiff = new FuzzyInput(2);

      FuzzySet* tooFarRight   = new FuzzySet(-60.0f, -60.0f, -54.0f, -30.0f);
      distDiff->addFuzzySet(tooFarRight);
      FuzzySet* right         = new FuzzySet(-54.0f, -30.0f, -30.0f, 0.0f);
      distDiff->addFuzzySet(right);
      FuzzySet* centered      = new FuzzySet(-30.0f, 0.0f, 0.0f, 30.0f);
      distDiff->addFuzzySet(centered);
      FuzzySet* left          = new FuzzySet(0.0f, 30.0f, 30.0f, 54.0f);
      distDiff->addFuzzySet(left);
      FuzzySet* tooFarLeft    = new FuzzySet(30.0f, 54.0f, 60.0f, 60.0f);
      distDiff->addFuzzySet(tooFarLeft);

      fuzzy->addFuzzyInput(distDiff);
      USART1_puts("centering dist added as fuzzy input...");

      /*************************************
       * Output 1
       ************************************/
      FuzzyOutput* motorSpeedDiff = new FuzzyOutput(1);

      // Seven sets for steering modes to take (close ones narrow far ones wider)
      FuzzySet* hardRight   = new FuzzySet(-30.0f, -30.0f, -30.0f, -15.0f);
      motorSpeedDiff->addFuzzySet(hardRight);
      USART1_puts("\thardRight");
      FuzzySet* lightRight  = new FuzzySet(-15.0f, -5.0f, -5.0f, 0.0f);
      motorSpeedDiff->addFuzzySet(lightRight);
      USART1_puts("\tlightRight");

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

FuzzySet* nomRight    = new FuzzySet(-30.0f, -15.0f, -15.0f, -5.0f);
      motorSpeedDiff->addFuzzySet(nomRight);
      USART1_puts("\tnomRight");
      FuzzySet* lightLeft   = new FuzzySet(0.0f, 5.0f, 5.0f, 15.0f);
      motorSpeedDiff->addFuzzySet(lightLeft);
      USART1_puts("\tlightLeft");
      FuzzySet* goStraight  = new FuzzySet(-5.0f, 0.0f, 0.0f, 5.0f);
      motorSpeedDiff->addFuzzySet(goStraight);
      USART1_puts("\tgoStraight");
      FuzzySet* nomLeft     = new FuzzySet(5.0f, 15.0f, 15.0f, 30.0f);
      motorSpeedDiff->addFuzzySet(nomLeft);
      USART1_puts("\tnomLeft");
      FuzzySet* hardLeft    = new FuzzySet(15.0f, 30.0f, 30.0f, 30.0f);
      motorSpeedDiff->addFuzzySet(hardLeft);
      USART1_puts("\thardLeft");

      fuzzy->addFuzzyOutput(motorSpeedDiff);
      USART1_puts("motor steering added as fuzzy output");

      lotsMoreSetupCode();

      while(1)
      {
        USART1_puts("Done!");
        stop(1); // Blink LED forever
      }
    }

很明显,我只是制作了一堆这些模糊集,每个模糊集都是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的值由该行设置

Stack_Size      EQU     0x200  ; <your stack size>

和堆

Heap_Size      EQU     0x400  ; <your heap size>

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM