I am
currently developing the SPI communication between CPU1 and an ADC converter.
When calling a method (was called multiple
times in a do while, in my scenareo 2 times), I always
have the problem, that in the second call of the methode in
the return data on the stack is interpreted as return
addresses and i land somewhere in the memory after this
return. As result of this, it runs in an ESTOP0 with illegal operation
interrupt.
I broke the problem down as far as possible,
because it is to much code to show here. But I still have an problem on the stack. I suspect that the same problem is underlying this but I don't know
why this is happening.
#define SYSTEM_STATUS_REGISTER_ADDRESS 0x0
#define NO_COMMAND 0x0
#define READ_COMMAND 0x10
typedef unsigned char UInt8;
typedef unsigned int UInt16;
void createUInt16Stack()
{
uint16_t test = 65000;
}
void createUInt32Stack()
{
uint32_t test = 165000;
}
enum Command
{
/// a write command shall be performed, i.e. send data to device.
/// (everything without a response from device)
COMMAND_WRITE,
/// a read command shall be executed, i.e. receive data from device.
COMMAND_READ,
/// the spi response shall be compared with a buffer
COMMAND_COMPARE,
};
struct Buffer
{
UInt16 *data;
UInt16 lengthBytes;
};
struct Request
{
Command command;
UInt16 bytesSent;
UInt16 bytesReceived;
UInt16 bytesToSend;
Buffer header;
Buffer buffer;
};
Buffer getADCHeader(UInt8 command, UInt8 address)
{
static UInt16 header[1];
Buffer buffer;
header[0] = (command << 8) & 0xFF00;
header[0] |= (address) & 0xFF;
buffer.data = header;
buffer.lengthBytes = 2;
return buffer;
}
Request getReadRegisterRequest(UInt8 address)
{
Request requestRegister;
UInt16 readNullBuffer[1];
readNullBuffer[0] = NO_COMMAND;
requestRegister.header = getADCHeader(READ_COMMAND, address);
requestRegister.command = COMMAND_READ;
requestRegister.buffer.data = readNullBuffer;
requestRegister.buffer.lengthBytes = 1;
requestRegister.bytesToSend = 0;
requestRegister.bytesSent = 0;
requestRegister.bytesReceived = 0;
return requestRegister;
}
void main(void)
{
Request request = getReadRegisterRequest(SYSTEM_STATUS_REGISTER_ADDRESS);
//createUInt16Stack(); // works correct
createUInt32Stack(); // override parts of statusRegisterRequest variable
Buffer data;
while (true)
{
data = request.buffer;
};
}
在示例中、我创建了类型请求的变量(与主应用程序中的变量相同)。 这是使用我所需的数据进行初始化的。 然后、我将调用以下方法之一、该方法仅在堆栈上创建新变量。
- void createUInt16Stack()
- void createUInt32Stack()
在 uint16情况下、一切都正常、但在 uint32情况下可以解决问题。
uint16情况:
在下图中、您可以在初始化 request 变量后看到栈。 标记的蓝色是请求变量。 红色标记了保存 request.buffer 数据的地址(0x0000)。
在我调用 metode createUInt16Stack()后,这个新创建的变量是请求最后一个数据后面的一个地址(红色字体0xFDE8)。 一切都很好。
uint32情况:
在下图中、您可以在初始化 request 变量后看到栈。 这里的颜色意味着相同的东西。
在我调用 metode createUInt32Stack()后,这个新创建的变量与请求的最后一个数据位于同一地址,后面一个地址。 发生什么情况:新变量值现在是我的请求值(0x8488)的一部分、因为它在同一地址写入。
在我的主应用程序中、我有同样的问题、只是地址在进一步移动、而且它有更多的想法要做。 我怀疑同样的问题也是这种情况的根源、但我不知道为什么会发生这种情况。