конструктор — Cortex M4 Hard Fault на C ++ инициализаторе

У меня очень странная проблема. Мне кажется, что это известная проблема, но я не могу найти никаких реальных решений или каких-либо твердых объяснений этого.

Вот моя установка:
Ведущий: ПК Win7, много оперативной памяти.
Цель: STM32F303RE Cortex M4 @ 64 МГц, на плате Nucleo32 со встроенным ST-LINK 2.1
Toolchain: uVision V5.16
Символы препроцессора: USE_STDPERIPH_DRIVER, STM32F303xE, __ CPLUSPLUS__FPU_PRESENT, __ FPU_USED

Разное Управление: —C99 —cpp

Все хорошо строит. Все оптимизации отключены.

Проблема во время выполнения. Процессор оказывается в обработчике hardfault после нескольких экземпляров объекта C ++. Где именно? Я отметил это, разделив мой фрагмент кода. Теперь я немного знаком с деталями и внутренними принципами C ++, но, похоже, у меня та же проблема, что и у этого парня: Ошибка сегментации, вызванная / устраненная путем изменения порядка файлов исходного кода в 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 "FuzzyRuleConfter.h" #include "FuzzyOutput.h" #include "FuzzyInput.h" #include "FuzzyIO.h" # include "FuzzySet.h" #include "FuzzyRuleAntecedent.h"
Нечеткий * нечеткий = новый Нечеткий ();

int main (void)
{
/ *************************************
* Вход 1
************************************ /
// Два набора "пересечения рампы" для rowWidth, т.е. "допуск" строки
FuzzyInput * rowWidth = new FuzzyInput (1);

FuzzySet * lowTolerance = новый FuzzySet (0.0f, 0.0f, 0.0f, 120.0f);
rowWidth-> addFuzzySet (lowTolerance);
FuzzySet * highTolerance = новый FuzzySet (0.0f, 120.0f, 120.0f, 120.0f);
rowWidth-> addFuzzySet (highTolerance);

Нечетко-> addFuzzyInput (rowWidth);
USART1_puts ("ширина строки добавлена ​​как нечеткий ввод ..");

/ *************************************
* Вход 2
************************************ /
// Пять наборов для "разницы между расстояниями R и L" FuzzyInput * distDiff = new FuzzyInput (2);

FuzzySet * tooFarRight = новый FuzzySet (-60.0f, -60.0f, -54.0f, -30.0f);
distDiff-> addFuzzySet (tooFarRight);
FuzzySet * right = новый FuzzySet (-54.0f, -30.0f, -30.0f, 0.0f);
distDiff-> addFuzzySet (справа);
FuzzySet * центрированный = новый FuzzySet (-30,0f, 0,0f, 0,0f, 30,0f);
distDiff-> addFuzzySet (по центру);
FuzzySet * left = новый FuzzySet (0.0f, 30.0f, 30.0f, 54.0f);
distDiff-> addFuzzySet (слева);
FuzzySet * tooFarLeft = новый FuzzySet (30.0f, 54.0f, 60.0f, 60.0f);
distDiff-> addFuzzySet (tooFarLeft);

Нечетко-> addFuzzyInput (distDiff);
USART1_puts («центрирование dist добавлено как нечеткий вход ...»);

/ *************************************
* Выход 1
************************************ /
FuzzyOutput * motorSpeedDiff = new FuzzyOutput (1);

// Семь комплектов для режимов рулевого управления (закрыть узкие, дальние - шире)
FuzzySet * hardRight = новый FuzzySet (-30.0f, -30.0f, -30.0f, -15.0f);
motorSpeedDiff-> addFuzzySet (hardRight);
USART1_puts ( "\ thardRight");
FuzzySet * lightRight = новый FuzzySet (-15.0f, -5.0f, -5.0f, 0.0f);
motorSpeedDiff-> addFuzzySet (lightRight);
USART1_puts ( "\ tlightRight");

Это последнее последовательное сообщение, которое я вижу в терминале «lightRight». При следующем вызове нового FuzzySet () ниже этой строки возникает серьезная ошибка.


FuzzySet * nomRight = новый FuzzySet (-30.0f, -15.0f, -15.0f, -5.0f);
motorSpeedDiff-> addFuzzySet (nomRight);
USART1_puts ( "\ tnomRight");
FuzzySet * lightLeft = новый FuzzySet (0.0f, 5.0f, 5.0f, 15.0f);
motorSpeedDiff-> addFuzzySet (lightLeft);
USART1_puts ( "\ tlightLeft");
FuzzySet * goStraight = новый FuzzySet (-5,0f, 0,0f, 0,0f, 5,0f);
motorSpeedDiff-> addFuzzySet (goStraight);
USART1_puts ( "\ tgoStraight");
FuzzySet * nomLeft = новый FuzzySet (5.0f, 15.0f, 15.0f, 30.0f);
motorSpeedDiff-> addFuzzySet (nomLeft);
USART1_puts ( "\ tnomLeft");
FuzzySet * hardLeft = новый FuzzySet (15.0f, 30.0f, 30.0f, 30.0f);
motorSpeedDiff-> addFuzzySet (hardLeft);
USART1_puts ( "\ thardLeft");

Нечетко-> addFuzzyOutput (motorSpeedDiff);
USART1_puts («рулевое управление двигателем добавлено как нечеткий выход»);

lotsMoreSetupCode ();

в то время как (1)
{
USART1_puts ( "Готово!");
остановки (1); // Мерцание светодиода навсегда
}
}

Ясно, что я просто делаю кучу этих нечетких наборов, каждый из которых представляет собой набор из 4-х чисел, но где-то летит указатель le-wild?

Вот конструктор, найденный в FuzzySet.cpp: (Часть библиотеки нечеткой логики, которую я не писал). Эта ЖЕ программа работает на 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;
}

[/ NOEDIT]

Это звучит как что-то, связанное со статическими переменными, доступ к которым имеют другие статически объявленные функции в других контекстах.

Но я ничего не объявил статичным.

Кто-то в ссылке на обмен стека говорит, что это может быть ошибка компоновщика. Ты согласен? Как это починить?

Есть идеи о том, что на самом деле происходит?

Я установил хороший обработчик сложных ошибок, который печатает информацию о регистре, но, очевидно, ошибка происходит еще до main (). Поэтому переход к ассемблерному коду, когда все перемешано, не кажется полезным.

Как это сделать? Спасибо за ваш опыт C ++!

3

Решение

Попробуйте изменить кучу и размер стека вашего кода в соответствии с микроконтроллером, который вы используете из файла 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 у вас также есть 2 вкладки в левом нижнем углу, где вы можете переключаться между «Текстовым редактором» и «Мастером настройки», чтобы изменить кучу кода и размеры стека.

0

Другие решения

Других решений пока нет ...