2016-04-12 10 views
3

Ich habe ein sehr seltsames Problem. Es klingt für mich, dass dies ein bekanntes Problem ist, aber ich kann keine wirklichen Lösungen oder irgendwelche solide Erklärungen dafür finden.Cortex M4 Schwerer Fehler auf C++ Initialisierer

Hier ist mein Setup:
Host: Win7 PC, viel RAM.
Target: STM32F303RE Cortex M4 @ 64 MHz, auf Nucleo32 Platine mit integriertem ST-LINK 2.1
Toolchain: uVision V5.16
Präprozessorsymbole: USE_STDPERIPH_DRIVER, STM32F303xE, __ CPLUSPLUS__FPU_PRESENT, __ FPU_USED

Verschiedene Steuerungen: --C99 --cpp

Alle baut gut. Alle Optimierung wurde deaktiviert.

Das Problem ist während der Laufzeit. Der Prozessor endet nach wenigen C++ - Objekt-Instanziierungen in einem Hardfault-Handler. Wo genau? Ich habe dies markiert, indem ich mein Code-Snippet geteilt habe. Nun, ich bin irgendwie neu in C++ - Details und inneren Arbeiten, aber es klingt wie ich das gleiche Problem wie dieser Kerl haben: Segmentation fault caused/avoided by changing source file order in Makefile

Aber auch nicht klare Lösung wird erläutert. Vielleicht ist es nicht die C++ Instanziierung bei Fehler. Obwohl keine Lösung gefunden wurde. Hier ist der Kern meines Programms, der das Problem aufzeigt: Dieser erste Codeabschnitt "scheint" gut zu laufen, bis ich den Abschnittblock für Ihre Aufmerksamkeit getrennt habe.

 

    #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"); 

Dies ist die letzte serielle Nachricht I im Terminal siehe „lightRight“ Harte Fehler zu neuen FuzzySet in nächstem Aufruf erfolgt() unterhalb dieser Linie.

 

     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 
     } 
    } 

So klar, ich mache nur ein paar dieser Fuzzy-Sets, die jeweils eine Sammlung von vier Schwimmer sind, aber irgendwo ein le-Wild Zeiger fliegt?

Hier ist der Konstruktor gefunden in FuzzySet.cpp: (Teil einer Fuzzy-Logik-Bibliothek, die ich nicht geschrieben habe) Das gleiche Programm läuft gut auf einem Arduino, aber nicht dieser Prozessor. Compiler-Unterschied?

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; 
} 

Es klingt wie etwas mit statischen Variablen zu tun, die von anderen staticly deklarierten Funktionen in anderen Kontexten zugegriffen wird.

Aber ich habe nichts statisch erklärt.

Jemand in der Stack-Austausch-Link sagt, es könnte ein Linker-Fehler sein. Sind Sie einverstanden? Wie repariere ich das?

Irgendwelche Ideen, was tatsächlich passiert?

Ich habe die nette Hard-Fault-Handler eingerichtet, die Register-Info druckt, aber anscheinend tritt der Fehler sogar vor main() auf. Es scheint also nicht sinnvoll, in den Assembler-Code zu gehen, wenn die Dinge durcheinander geraten.

Wie wird das repariert?Danke für Ihre C++ - Expertise!

+0

Haben Sie genug Heap-Speicherplatz zugewiesen? Ist nomRight null? – Ross

+0

Ich kann tatsächlich die aufrufende Reihenfolge für nomRight und lightRight tauschen, aber der harte Fehler wird an der gleichen Stelle auftreten, diesmal beim Erstellen der nomRight-Instanz (die zweite der beiden erstellten). Das lässt mich denken, dass dies ein "Raum" -Abkommen ist und kein "schlechtes Objekt" -Ausgabe. Gibt es eine Möglichkeit zu überprüfen, ob nomRight == NULL ist? Kann ich das Objekt überprüfen und dann an das Terminal drucken? Ich werde es versuchen. –

+0

_ "anscheinend tritt der Fehler sogar vor main()" _ auf - aber Sie haben auch gesagt, dass Sie den Fehler sehen, nachdem ein großer großer Teil von 'main()' gut ausgeführt hat. Welches ist es? Randnotiz: '-C99'? "Ja wirklich?" – Notlikethat

Antwort

0

Try Heap und Stack Größe des Codes nach Mikrocontroller Sie von startup_stm32fxxx.s Datei ist

hier verwenden, um zu ändern das Beispiel

;******************** (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 

Der Wert des Stapels von dieser

Linie gesetzt
Stack_Size  EQU  0x200 ; <your stack size> 

und der Haufen

Heap_Size  EQU  0x400 ; <your heap size> 

In Keil uVision haben Sie auch zwei Registerkarten in der linken unteren Ecke, wo Sie zwischen "Text Editor" und "Config Wizard" wechseln können, um Ihre Code-Heap- und Stack-Größen zu ändern.

Verwandte Themen