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.

TMS320F28386D: erad_ex3_stack_overflow_detect

Expert 2460 points

Part Number: TMS320F28386D

When use the example code, I comments the stack overflow detection related functions, just keep the recursiveFunction.

I have one question, the test result shows that the program still works.

functionCallCount still increases

It does not branch into illeagal operation function or stuck at somewhere.

//#############################################################################
//
// FILE:   erad_ex3_stack_overflow_detect.c
//
// TITLE:  ERAD HWBP Stack Overflow Detection.
//
//! \addtogroup driver_example_list
//! <h1>ERAD HWBP Stack Overflow Detection</h1>
//!
//!  This example uses BUSCOMP1 to monitor the stack. The Bus comparator
//!  is set to monitor the data write access bus and generate an RTOS interrupt
//!  CPU when a write is detected to end of the STACK within a threshold.
//!
//!  \b Watch \b Variables \n
//!  - functionCallCount - the number of times the recursive function
//!    overflowing the STACK is called.
//!  - x indicates that the ISR has been entered
//!
//! \b External \b Connections \n
//!  None
//
//#############################################################################

//
//Included Files
//
#include "driverlib.h"
#include "device.h"


//
// Global Variables
//

//
// The stack end address
//
extern uint32_t __TI_STACK_END;

//
// A threshold value. An interrupt is generated when there is an access to
// StackEnd - threshold
//
uint32_t threshold = 10;
//#define threshold      10

volatile uint32_t functionCallCount = 0;
uint32_t x = 0;

//
// Function Prototypes
//
interrupt void RTOSISR(void);
void recursiveFunction(uint32_t delay);

//
// Main
//
void main(void)
{
    //
    // Initializes device clock and peripherals
    //
    Device_init();

    //
    // Configures the GPIO pin as a push-pull output
    //
    Device_initGPIO();

    //
    // Initializes PIE and clears PIE registers. Disables CPU interrupts.
    //
    Interrupt_initModule();

    //
    // Initializes the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    //
    Interrupt_initVectorTable();
#if 0
    //
    // ISRs for each RTOS interrupt
    //
    Interrupt_register(INT_RTOS, &RTOSISR);
    Interrupt_enableInCPU(INTERRUPT_CPU_RTOSINT);

    //
    // Enable RTOS Interrupt
    //
    Interrupt_enable(INT_RTOS);

    //
    // Initializes the ERAD module with the owner set as APPLICATION
    //
    ERAD_initModule(ERAD_OWNER_APPLICATION);

    //
    // Parameters for generating interrupt on a write access to the
    // threshold address
    //
    ERAD_AddressHit_Params addr_params;
    addr_params.address = (uint32_t)&__TI_STACK_END - threshold;
    addr_params.mask = 0x0;
    addr_params.bus_sel = ERAD_BUSCOMP_BUS_DWAB;

    //
    // Sets a watchpoint at the end address of the STACK
    //
    ERAD_enableInterruptOnAddressHit(addr_params, ERAD_HWBP1_BASE);
#endif
    //
    // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
    //
    EINT;
    ERTM;

    recursiveFunction(1);

    //
    // IDLE loop. Just sit and loop forever (optional)
    //
    while(1)
    {

    }
}

//
// recursive function to fill the stack
//
void recursiveFunction(uint32_t delay)
{
    functionCallCount++;

    //
    // Recursive function
    //
    recursiveFunction(delay + 1UL);
}
#if 0
//
// ISR to be executed on RTOS generation
// Program will halt at this ESTOP0
//
interrupt void
RTOSISR(void)
{
    //
    // Indicate that the ISR was executed
    //
    x++;
    ESTOP0;
}
#endif
//
// End of File
//

  • Is it not entering the RTOSISR?

    Regards,

    Veena

  • No, I use the #if0 #endif  comment the code.

  • So, ERAD cannot prevent any memory access. It is only capable of detecting such access access and generate a halt or an interrupt. In the example, ERAD is configured to detect a write access to the end of stack and generate an ISR

    Regards,

    Veena

  • Yes. I understand the fucntion of ERAD.

    Question is call the recursiveFunction in the mainloop, why the program can still work?

    It shall make the stackoverflow problem.

    I suppose it shall enter into illeagal operation function or stuck at somewhere.

  • Illegal operation interrupt occurs when CPU tries executing an illegal instruction. In a stack overflow scenario, the CPU tries accessing the RAM beyond the stack boundary. This doesn't cause any CPU fault, as long as there is a valid RAM memory available at that address. If that memory is used for some other data, that gets corrupted and your application might misbehave.

    Regards,

    Veena

  • Yes, the test result matchs with your comment.

    But I cannot understand, why call the recursiveFunction in the mainloop, the program can still work.

    When observe  the SP register, it increases beyong the stack boundary, then continue increase, then will pointer back to the start RAM address.

    Repeat again but never gets corrupted.

    I suppoese it will always increase until there is no RAM can be use, then gets corrupted.

    But the test result shows no corrupt, it will repeat. So this is the behavior.

  • Hi,

    As mentioned in my previous replay CPU is not aware of the stack boundary and doesn't generate any CPU faults when it crosses that boundary. If there is a valid RAM region after that address, the writes will go through. I am assuming that memory region is not in use and you did not face any other issue due to data corruption. If CPU is trying to write to an invalid address, when SP crosses the actual RAM boundary, writes will be ignored, without any errors

    Regards,

    Veena

  • Yes, I understand your comments. I got it.

    Which I cannot understand is the SP's behavior when  call the recursiveFunction in the mainloop.

    it increases beyong the stack boundary, then continue increase, then will pointer back to the start RAM address. Like a cycle.

  • SP is like any other register. It is a 16 bit long register. Once it reaches the value 0xFFFF, it will next move to address 0.

    Regards,

    Veena