2015-06-12 3 views
0

Я работаю над встроенной платформой, которая не имеет функций отладки. Поэтому трудно сказать, что такое источник ошибок.Ошибка при попытке обновить элемент массива

Я определил в заголовочном файле:

typedef struct cm_packet { 
    CM_Header Header; //header of packet 3 bytes 
    uint8_t *Data; //packet data 64 bytes 
    CM_Footer Footer; //footer of packet 3 bytes 
} CM_Packet; 

typedef struct cm_inittypedef{ 
    uint8_t    DeviceId; 
    CM_Packet    Packet;   
} CM_InitTypeDef; 

extern CM_InitTypeDef cmHandler; 
void CM_Init(CM_InitTypeDef *handler);  
CM_AppendResult CM_AppendData(CM_InitTypeDef *handler, uint8_t identifier 
           , uint8_t *data, uint8_t length); 

И где-то в реализации у меня есть:

uint8_t bufferIndex = 0; 

void CM_Init(CM_InitTypeDef *cm_initer) { //init a handler 
    cmHandler.DeviceId = cm_initer->DeviceId; 

    CM_Packet cmPacket; 
    cmPacket.Header.DeviceId = cm_initer->DeviceId; 
    cmPacket.Header.PacketStart = CM_START; 
    cmPacket.Footer.PacketEnd = CM_END; 
    //initialize data array 
    uint8_t emptyBuffer[CM_MAX_DATA_SIZE] = {0x00}; 
    cmPacket.Data = emptyBuffer; 

    cm_initer->Packet = cmPacket; 
} 

CM_AppendResult CM_AppendData(CM_InitTypeDef *handler, uint8_t identifier 
           , uint8_t *data, uint8_t length){  
    //some check to see if new data does not make Data overflow    

    uint8_t i; 

    /*** ERROR HAPPENS HERE!!!! ***/ 
    handler->Packet.Data[bufferIndex++] = identifier; 

    //now add the data itself 
    for(i = 0; i < length; i++) { 
    handler->Packet.Data[bufferIndex++] = data[i]; 
    } 

    //reset indexer 
    if(bufferIndex > 64) { 
     PacketReady(); //mark packet as ready 
     bufferIndex = 0 
    }; 

    //return result 
} 

Идея заключается в том, чтобы обновить Packet.Data от некоторых других исходных кодов, которые имеют доступ к handler , Например, некоторые другие источники могут вызвать функцию Append для изменения Packet.Data. Но, как вы видите в коде, я прокомментировал место, в котором микроконтроллер переходит в режим жесткой неисправности. Я не уверен, что здесь происходит. Все, что я знаю, именно на этой линии микро переходит в режим жесткой неисправности и никогда не восстанавливается!

Это может быть состояние гонки, но прежде всего я хочу знать, что я написал правильно c !!! кода, то я пытаюсь исключить другие проблемы.

+0

Это первое поле в 'CM_Header' размером более 8 бит? BTW, если используемая среда IDE не предоставляет функции отладки, попробуйте запустить тот же код на вашем ПК и посмотреть, можете ли вы воспроизвести проблему там. –

+0

Какова ценность 'CM_MAX_DATA_SIZE'? Для переменных массивов полезно использовать байтовые переменные. – chqrlie

+0

@chqrlie its 64 –

ответ

3

В функции CM_Init, вы устанавливаете cmPacket.Data, чтобы указать на локальный массив:

uint8_t emptyBuffer[CM_MAX_DATA_SIZE] = {0x00}; 
cmPacket.Data = emptyBuffer; 

Доступ к этому адресу памяти выходит за рамки функциональных выходов неопределенное поведение.

+0

Спасибо ... это был преступник! –

+0

@SaeidYazdani: Добро пожаловать :) –

1

Как упоминалось @barak manos, буфер, поставленный в Data, выделяется в стеке.

Когда вы добираетесь до CM_AppendData, вы пишете память, которая больше не предназначена для буфера.

Возможно, вы захотите использовать malloc, чтобы буфер выделялся в куче, а не в стеке. Просто не забудьте позвонить free, чтобы вы не пропускали память.

Если вы не можете использовать динамическое распределение, можно выделить некоторую царапину для всех применений Data. Он просто должен быть статичным.

Надеюсь, что это поможет :)

+0

К сожалению, malloc недоступен на этой платформе –

+0

На самом деле, если вы знаете, что 'Data' будет 64 байта, вы можете сохранить его непосредственно в' cm_packet' как значение вместо указатель. – Jouan

Смежные вопросы