70196


STM32F207ZG Nucleoの評価用ボードを使用して  
PCとマイコン間で通信するサンプルプログラムを作成しています。

[![画像の説明をここに入力](https://i.stack.imgur.com/nGAAD.jpg)](https://i.stack.imgur.com/nGAAD.jpg)

画像内、42行目の様にPcDataという基底クラスのポインタへ  
PcDataLampという派生クラスをnewして代入しようとしています。  
この、newしたタイミングで画像右下のトレースの様に、  
mallocでHardFaultとなってしまいます。

マイコンプログラムを作成するのが初めてで、初歩的なことも分かっていないのですが  
こういったエラーの場合に原因を探る方法として、どこから確認していけばよいでしょうか。

補足ですが、new演算子を使用している部分は、本番実装時には  
スマートポインタへ置き換える予定です。

pc_data.cpp

[code]

    PcData* PcData::getPcData(uint8_t* source, uint32_t len){
        const char * CLASS_NAME = "[PcData]";
    
        // データ受信ログ
        char mes[] = "Received data from PC.";
        char dat[100] = {0};
        for(int i = 0; i < (int)len; i++){
            sprintf(&dat[strlen(dat)], "%02X,", source[i]);
        }
        dat[strlen(dat) - 1] = 0;   // 末尾の「,」を除去
        char log[255] = {0};
        sprintf(log, "%s <%s>\n\r", mes, dat);
        Logger::getInstance()->logging(CLASS_NAME, "(GetPcData)", log);
    
        // データ長(2, 3Byte目)と実際受信した長さの検証
        int16_t size = ((source[FMT_LEN1] << 8) | source[FMT_LEN2]);
        if(size != (int32_t)len){
            // 受信データ長不一致のエラーログを出力
            sprintf(log, "Data length unmatch. [Receive -> %d] [2,3bytes -> %d]\n\r", (int)len, (int)size);
            Logger::getInstance()->logging(CLASS_NAME, "(GetPcData)", log);
            return nullptr;
        }
    
        PcData* df = nullptr;
        switch(source[FMT_DEST]){
        case DEST_LAMP:
            df = new PcDataLamp(source, len);
            break;
        }
    
        df->m_TotalLen = size;
        return df;
    }
    
[/code]

pc_data_lamp.cpp

[code]

    PcDataLamp::PcDataLamp(uint8_t *source, uint32_t len): PcData(Destinations::Lamp) {
        // 通信プロトコル設定
        uint8_t protocol = source[FMT_PRTCL];
        m_Protocol = static_cast<LampProtocol>(protocol);
    
        // コマンド設定
        uint16_t command = ((source[FMT_CMD_1] << 8) | source[FMT_CMD_2]);
        m_Command = static_cast<LampCommand>(command);
    
        // データ設定
        const int32_t offset = FMT_DATA;
        int32_t dataLen = len - offset;                 // source長からコマンドまでの長さを引いたサイズを求める
        memcpy(&m_Data[0], &source[offset], dataLen);
        m_DataLen = dataLen;
    }
    
    PcDataLamp::~PcDataLamp() {
        // TODO Auto-generated destructor stub
    }
    
[/code]


CC BY-SA 4.0
2020-09-07T01:02:50.333
70190
2020-09-07T07:26:11.097
2020-09-07T04:01:48.747
38100
38100
question
c++ c eclipse
STM32 インスタンス生成時にmallocでHardFault発生


そのボードについては全く知りませんが、組み込み系の仕事している身としては

> どこから確認すればよいか

家電用のマイコンソフト、特に小規模なものでは動的にメモリを確保することがありえなくて、よって `malloc()`
には対応していなかったりします。まずはその Nucleo 評価ボードの処理系で `malloc()`
が使えるかどうかの確認から。仕様書とかメーカーホームページ内解説書とか公式文書にあればよし、無ければ `malloc()`
の逆アセンブルとか。非対応な場合のよくある実装は即実行時エラーになるダミールーチンだったりします。

# 動的メモリ確保ができる＝未使用な RAM を開けておかねばならない＝単なる電気の無駄遣いをしているわけで、それなら別の目的に使ったほうが有意義。

どうしても実行中に `new` しなきゃならないですか？ `new` せずに `static` な変数にしてしまえばよくないですか？ そうすれば
`delete` とかも考えなくていいしバグを出しにくくなります。小規模組み込み系の常識は PC ソフトのそれとは異なります。


CC BY-SA 4.0
2020-09-07T07:26:11.097
70196
2020-09-07T07:26:11.097
8589
70190
answer