2016-04-12 17 views
3

私は非常に奇妙な問題があります。これは知られている問題だと私には聞こえますが、私は実際の解決方法やそれを強く説明することはできません。
ホスト:: Win7のPC、RAMのたくさんCortex M4 C++初期化器のハードフォールト

は、ここに私の設定です。
対象:統合されたST-LINKとNucleo32ボード上の64 MHzの@ STM32F303REのCortex M4、2.1
ツールチェーン: 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++のインスタンス化に失敗しているとは限りません。解決策は見当たりませんが。私のプログラムの要点は次のとおりです。この第1セクションのコードは、セクションブロックがあなたの注意を奪うまで、うまく動作するように見えます。

 

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

これは、この行の下 ハード障害が新しいFuzzySet(次の呼び出しで発生した私は、端末で見る最後のシリアルメッセージ「lightRight」)です。

 

     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台の山車の集合体であるこれらのファジー集合、​​しかしどこかLE-野生のポインタのハエの束を作っていますか?

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

これは、他の文脈では、他の静的に宣言された関数によってアクセスされている静的変数とは何かのように聞こえます。

しかし、私は静的と宣言していません。

スタック交換リンクの誰かが、リンカの障害である可能性があると言います。同意しますか?これを修理するには?

実際に何が起こっているかに関するアイデアはありますか?

レジスタ情報を表示するniceハードフォールトハンドラを設定しましたが、明らかにmain()の前にエラーが発生しているようです。物事が混乱したときにアセンブリコードに行くことは役に立たないようです。

これを修復するにはどうすればよいですか?あなたのC++の専門知識に感謝します!

+0

十分なヒープスペースが割り当てられていますか? nomRightはnullですか? – Ross

+0

私は実際にnomRightとlightRightの呼び出し順序を入れ替えることができますが、ハード・フォールトはnomRightインスタンス(作成された2つのうちの2番目)を作成するときに同じ場所で発生します。これは私がこれが「宇宙」の問題であり、「悪いオブジェクト」の問題ではないと考えさせる。 nomRight == NULLかどうかをチェックする方法はありますか?オブジェクトをチェックしてからターミナルにプリントできますか?私はそれを撃つだろう。 –

+0

_ "明らかにmain()" _の前にエラーが発生していますが、main()の大きなチャンクがうまく実行された後もエラーが表示されています。どちらですか?サイドノート: '--C99'?本当に? – Notlikethat

答えて

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には、左下隅に「テキストエディタ」と「設定ウィザード」を切り替えることができる2つのタブがあり、コードヒープとスタックサイズを変更できます。