2016-07-11 15 views
1

でメモリにアクセスすることはできません。Cは、GDBをデバッグすることは私に次のエラーを伝えるときにアドレス

しかし、プログラムは問題なく終了し、私にOkの結果を与えますか?

私のメインのファイル:

#include "Local.h" 

int main(void) { 

    if(HandleReceivedMessages() == OP_COMPLETED){ 
     printf("Main Completed \n"); 
    } else { 
     printf("Main Failed \n"); 
    } 
    return 0; 
} 

Local.h

#ifndef LOCAL_H_ 
#define LOCAL_H_ 

#include "Common.h" 

T_OP_STATUS HandleReceivedMessages(void); 

#endif 

Local.c

#include "Handler.h" 
#include "Local.h" 

uint8_t message[] = {0x86, 0x9a, 0xa0, 0x00, 0x00, 0x01, 0x01, 0x07, 0x00, 0x10, 0x4a, 0x00, 0x00, 0x00, 0x00, 0xe1}; 

uint8_t length = 16; 

T_OP_STATUS HandleReceivedMessages(void) { 

    if(HandleResponseMessage(message, length) == STATUS_SUCCESS) { 
     printf("Completed from Local \n"); 
     return OP_COMPLETED; 
    } else { 
     printf("Failed from Local \n"); 
     return OP_FAILED; 
    } 

} 

Handler.h

#ifndef HANDLER_H_ 
#define HANDLER_H_ 

#include "Common.h" 

T_MESSAGE_STATUS HandleResponseMessage(uint8_t *requestData, uint8_t msgLength); 


#endif /* HANDLER_H_ */ 

Handler.c

#include "Handler.h" 
#include <string.h> 

static uint8_t rawRequestData[BUFFER_WIRED_SIZE]; 

static float TempFloat = 0; 


T_MESSAGE_STATUS HandleCmd(uint16_t cmdNumber, uint8_t rawDataLength, 
        uint8_t *rawDataPtr) { 

    switch (cmdNumber) { 
     case 1: 
      TempFloat = ConvertByteArrayToFloat(&rawDataPtr[3]); 
      printf("The value of the float is : %f \n", TempFloat); 
      return STATUS_SUCCESS; 
     default: 
      break; 
    } 

    return STATUS_NOT_IMPLEMENTED; 
} 


T_MESSAGE_STATUS HandleResponseMessage(uint8_t *message, 
           uint8_t msgLength) { 

    uint8_t cmdNumber, dataLength, startOfData; 


    // Check the delimiter. 
    if (message[0] & INDICATOR_UNIQUE_ADDRESS) { 

     cmdNumber = message[6]; 
     dataLength = message[7]; 
     startOfData = 8; 

    } else { 

     cmdNumber = message[2]; 
     dataLength = message[3]; 
     startOfData = 4; 
    } 

    // we copy only the real data from the command response 
    memcpy(&rawRequestData, message + startOfData, dataLength); 

    return HandleCmd(cmdNumber, dataLength, rawRequestData); 

} 

COMMON.H

#ifndef COMMON_H_ 
#define COMMON_H_ 

#include <stdint.h> 
#include <stdio.h> 

#define BUFFER_WIRED_SIZE    128 
#define INDICATOR_UNIQUE_ADDRESS  0x80 


typedef enum { 

    OP_FAILED, 
    OP_COMPLETED, 

}T_OP_STATUS; 

typedef enum 
{ 
    STATUS_SUCCESS, 
    STATUS_NOT_IMPLEMENTED, 

} T_MESSAGE_STATUS; 

float ConvertByteArrayToFloat(uint8_t *data); 


#endif /* COMMON_H_ */ 

Common.c

#include "Common.h" 

float ConvertByteArrayToFloat(uint8_t *data) { 

    union { 
     uint8_t tmpArray[4]; 
     float tmpFloat; 
    } value; 

    value.tmpArray[0] = data[3]; 
    value.tmpArray[1] = data[2]; 
    value.tmpArray[2] = data[1]; 
    value.tmpArray[3] = data[0]; 

    return value.tmpFloat; 
} 

これは(それがの形式をチェックするような多くのことを行い、分版ですメッセージ、CRCなど)が含まれますが、すべてのファイルから最初から最後まで続きます。

私は組み込みプラットフォームで作業しています。マイクロコントローラでデバッグしてConvertByteArrayToFloat関数を呼び出すと、自分のコードの他の部分にジャンプし、マイクロコントローラがクラッシュします。

マイクロコントローラなしでコンピュータのエラーを再現しようとしましたが、エラーが上部にありました。

+0

マイクロコントローラとは何ですか?ビッグエンディアンかリトルエンディアンか? 'ConvertByteArrayToFloat'がデコードするメッセージを生成するには、表示されていない' ConvertByteArrayToFloat'(例えば、 'ConvertFloatToByteArray')の逆の関数が必要です。間違ったエンディアンでハードワイヤリングされている可能性があり、フロートが返されたときにconvert関数が吹き飛ばされます。つまり、x86のためにハードワイヤードされていますが、そこでは動作しますが、コントローラはビ​​ッグエンディアンかもしれません。 –

+0

マイクロはリトルエンディアンですが、私のマイクロでは内部のブレークポイントに当たらないConvertByteArrayToFloatは、その文に到達すると、コードの他の無関係な部分にジャンプし、クラッシュしてHardFaultに入ります。 はい、ConvertFloatToByteArrayもありますが、私は値を読み取って書き込もうとしているので、現時点では使用されていません。 – IzonFreak

+0

以前のUBに起因するUBのような音。私は解き放たれた「+ 3」を見た[しかし、あなたはすでにそれをチェックしたと思った]。この後の問題の原因となるバッファをオーバーランする別の場所がある(つまり、何らかの机上のチェックをしている)のでしょうか?意図しない再帰によりスタックオーバーフロー? uCでは、[bkpt needs]が破損してしまう可能性があります。初期のinit中にconvert funcを呼び出して、少なくとも1回は動作することを証明してください。それから、コショウの人工呼出しをしながら(つまり、石炭鉱山のカナリアにする)。あなたはコードを踏むことができますか(対bkpt)? –

答えて

2

は、この:(rawDataPtruint8_t *引数がある)

TempFloat = ConvertByteArrayToFloat(&rawDataPtr[3]); 

は非常に疑わしいです。 rawDataPtrrawDataPtr + 3と同じ)の4番目のバイトへのポインターを変換関数に渡すと、変換関数はその位置から4バイトを読み込みます。

これは、メッセージの最初のバイトを消費した後、何らかの混乱のように見えます。

+0

そのrawDataPtrは、その場所(3)からメッセージに送信されるデータです。私のデータ配列(rawDataPrt)に4バイトの浮動小数点があります。これは、この特定のケースで抽出したい値です。 HandleResponseMessageに表示されている場合は、memcpyを使用してメッセージの特定の部分をコピーします。これは私のデータであり、次にHandleCmdにフィードします。 – IzonFreak

+0

@IzonFreakいいえ、私はそれを見ません。私はあなたの 'memcpy()'をソースの 'rawData'にどのように置いているのかを見ていますが、私が引用した行で別の* 4をスキップします。 – unwind

+0

@IzonFreak私はくつろぎに同意しなければならないのではないかと心配しています。したがって、絶対_raw_バッファ開始から、オフセット4または8の浮動小数点はありますか?つまり、スキップする必要があるヘッダーサイズはどれですか?ヘッダーが4の場合、コードは '&rawDataPtr [0]'でなければなりません。それが '&rawDataPtr [3]'でなければならない場合、 'HandleResponseMessage'の4/8のprestrip、' 0-3'の内容は?たぶん、簡単な方法は、インデックス0で試して、UBがなくなるかどうかを確認することです。または、後方に作業します。 'HandleCmd'または' HandleReponseMessage'にbkptを入れます。 –

関連する問題