This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS320F28388D: Stack overwrites my data that will be needed later

Part Number: TMS320F28388D


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;
    };
}

In the example I create a variable of the type Request (same as in my main application). This is initialized with my desired data. Then I'll call one of the following methods, which only creates a new variable on stack.

  • void createUInt16Stack()
  • void createUInt32Stack()

In the UInt16 case, everything is fine, but in the UInt32 case occures the problem.

 


UInt16 case:

 

In the following image, you see the stack after the initialisation of the request variable. The blue marked is the request variable. The red circeled the address where the data of request.buffer are saved (0x0000).

After i call the methode, createUInt16Stack(), this new created variable is one address behind (red font 0xFDE8) the last data of the request. So everything is fine.


UInt32 case:

 

In the following image, you see the stack after the initialisation of the request variable. The colors here mean the same thing.

After i call the methode, createUInt32Stack(), this new created variable is at the same address as the last data of the request and one behind. What happens: the new variables value is now part of my request values (0x8488), because it writes at the same address.

In my main application I have the same problem, only that the addresses are shifting even further and it has much more thinks to do. I suspect that the same problem is underlying this but I don't know why this is happening.

  • Hi Christopher,

    I am sorry, I had some trouble understanding the memory view. Please correct me if I got it wrong. The data in blue is the entire request variable and one you have circled is a different variable which is not part of Request struct. Is this variable (the one circled) in scope? Note that if you create a local variable in a function, it get allocated to stack, but once that function is returned, that will gone. That means, that address is available for new local variables.

    It would be good if you could share the Variables view in CCS.

    Regards,

    Veena

  • Thanks for your reply.

    The variable i circled is the address, on which the data of the buffer are created.That means i have in my request a buffer and in that buffer is a pointer to the data. In my request, at address 0x00000040C, is my address to the data (0412). That is the position in stack i circeled.

    Yes of course, i give you the variables view, right away

  • The moment request is initialised. All values how them should be.

    After the new variable on stack.

  • Hi Christopher,

    So my question is where is the variable at 0x416 allocated? I do not see that in the main. Was it allocated inside getReadRegisterRequest as a local variable?

    If you declare a local variable inside a function, that allocation would be cleared once the function returns.

    Lets say, the SP (Stack Pointer) was at 0x1000 when you call Function1. Function1 allocates some local variables and SP gets incremented to 0x1010. Once the Function1 returns, the SP is reset back to 0x1000. The address 0x1000-0x1010 will now be open for allocating new local variables. When you call Function2, local variable in it will get allocated to the address 0x1000 onwards.

    It is highly recommended not to have function return the address of local variables. The scope of the local variables is within that function.

    Regards,

    Veena

  • Thank you for your help Veena. That solved my problem in my test project. I will try to integrate this in my main application.