我正在开发一个没有调试功能的嵌入式平台。所以很难说出错误来源是什么。
我在头文件中定义了:
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 :(得分:3)
在函数cmPacket.Data
中,您将uint8_t emptyBuffer[CM_MAX_DATA_SIZE] = {0x00};
cmPacket.Data = emptyBuffer;
设置为指向本地数组:
<?php
在函数范围之外访问此内存地址会产生未定义的行为。
答案 1 :(得分:1)
正如提到的@barak manos,提供给Data
的缓冲区已分配到堆栈中。
当你到达CM_AppendData
时,你正在编写不再专用于缓冲区的内存。
您可能希望使用malloc
,以便在堆上而不是在堆栈上分配缓冲区。只记得打电话给free
,这样你就不会泄漏记忆。
如果您无法使用动态分配,则可以为所有Data
用途专用一些临时存储器。它只需要是静态的。
希望有所帮助:)