我有一个非常奇怪的问题。听起来这是一个已知的问题,但我找不到任何实际的解决方案,或者对它有任何可靠的解释。
这是我的设置:
主机: Win7 PC,充足的内存
目标: STM32F303RE Cortex M4 @ 64 MHz,位于带有集成ST-LINK 2.1的Nucleo32板上
工具链: uVision V5.16
预处理器符号: USE_STDPERIPH_DRIVER,STM32F303xE,__ CPLUSPLUS__FPU_PRESENT,__ FPU_USED
其他控制: --C99 --cpp
一切都很好。所有优化都已关闭。
问题出在运行时。在几个C ++对象实例化之后,处理器最终进入硬件处理程序。到底在哪里?我已经通过拆分我的代码片段来标记这一点。现在,我对C ++细节和内部工作有点新鲜,但听起来我和这个家伙有同样的问题:Segmentation fault caused/avoided by changing source file order in 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 ++专业知识!
答案 0 :(得分:0)
尝试根据您在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中,您还可以在左下角有两个标签,您可以在其中切换&#34;文本编辑器&#34;和#34;配置向导&#34;更改代码堆和堆栈大小。