2014-09-03 33 views
0

我試圖將char類型的緩衝區轉換成由我定義的結構,以便通過TLV分析緩衝區。但我一次又一次地陷入了嚴重的錯誤。arm cortex m0 nf51822 c編程硬件故障,真的很困惑

代碼是這些:有點長。

#define BigtoLittle32(A) ((((uint32_t)(A) & 0xff000000) >> 24) | \ 
            (((uint32_t)(A) & 0x00ff0000) >> 8) | \ 
            (((uint32_t)(A) & 0x0000ff00) << 8) | \ 
            (((uint32_t)(A) & 0x000000ff) << 24)) 

enum { 
    DISH = 0 
} CB_DISH_TLV_TYPES; 

typedef struct cb_tlv_node_s 
{ 
    uint32_t type; 
    uint32_t length; 
    char value[0]; 
} cb_tlv_node_t; 


typedef struct cb_ble_buffer_s { 
    uint16_t total_length; 
    uint16_t current_length; 
    int8_t current_data_id; 
    int8_t expect_package_id; 
    char buffer[500]; 
} cb_ble_buffer_t; 

static cb_ble_buffer_t     current_buffer; 

cb_tlv_node_t * 
cb_tlv_read(char *buffer) 
{ 
    uint32_t a,b,c,d; 
    cb_tlv_node_t * tlv_p; 
    tlv_p = (cb_tlv_node_t *)buffer; 
/* tlv_p->length = BigtoLittle32(tlv_p->length);*/ //this code also cause hard fault 
/* tlv_p->type = BigtoLittle32(tlv_p->type);*/ //didn't test this one ,but high risk causing hard fault 

    return tlv_p; 
} 

//ble packages are reorgnized and call this function. it excutes in the ble recieve interupt 
int 
cb_dish_data_processer(char * data, int length) 
{ 
    assert(data != NULL); 
    assert(length > 0); 


    cb_tlv_node_t *tlv_p = cb_tlv_read(data); 

    //test 
    int a = sizeof(CB_DISH_TLV_TYPES); 

    //if ((char)tlv_p->type != DISH) { //this code is fine and steady 
    if (tlv_p->type != DISH) {   //this leads to hard fault 
     return CB_PC_CODE_UNRECOGNIZE; 
    } 

    cb_dish_tlv_read(tlv_p->value, tlv_p->length); 
    return CB_PC_CODE_PROCESSED; 
} 

拳頭我相信指針不會丟失,所以不應該有任何形式的,如果使用非法地址; 第二我假設我的過程太長,無法進入中斷,所以我將代碼移出側並在主循環中激活,但仍然無用;

所以我被困在這裏,我找不到任何導致這種情況的原因。 如果您需要更多信息,請留言,我會在網上等待。 ps:硬件主板是Nordic nf51822,內存8kB,256kB閃存ROM

順便說一句:在這種主板中禁止使用calloc和其他alloc函數是真的嗎? ,因爲當我嘗試動態分配一個新的空間時,電路板出問題並自行重置。

非常感謝

+1

無論是動態內存分配函數可用或不是,依賴於你的編譯工具。 8kB的內存量非常小,並且可能沒有爲分配功能保留內存池。檢查你的編譯器/鏈接器設置。 – user694733 2014-09-03 06:36:42

+0

@ user694733 keil c 4.0是我使用的編譯器,我不知道用於編譯的準確參數,我在Windows上使用Keil uVersion IDE。並使用北歐模板項目來開發該板。希望這個信息有用 – 2014-09-03 06:42:32

+2

看起來有點可疑的一件事是,你將'char *'緩衝區轉換爲(cb_tlv_node_t *)並嘗試使用它。 ARM要求32位整數在訪問它們時正確對齊到4字節邊界。 'char * buffer'指向的緩衝區很可能與1字節的邊界對齊。 – user694733 2014-09-03 06:55:03

回答

0

一件事看起來很可疑的是,你轉換的char *緩衝區(cb_tlv_node_t *),並嘗試使用它。 ARM要求32位整數在訪問它們時正確對齊到4字節邊界。 char *緩衝區指向的緩衝區很可能與1字節的邊界對齊。通過user694733

,所以我改變了這種

typedef struct cb_ble_buffer_s { 
    uint16_t total_length; 
    uint16_t current_length; 
    int8_t current_data_id; 
    int8_t expect_package_id; 
    char buffer[500]; 
} cb_ble_buffer_t; 

這個

typedef struct cb_ble_buffer_s { 
    uint16_t total_length; 
    uint16_t current_length; 
    int16_t current_data_id; 
    int16_t expect_package_id; 
    char buffer[500]; 
} cb_ble_buffer_t; 

,它只是正常工作和穩定 非常感謝@ user694733