Stack Violation

fbpp wrote on Monday, November 28, 2011:

I am using ISE-13.3 with microblaze and FreeRTOS-7.02.
I load my app from XMD console, and type run, then the XMD console prints:
XMD% Warning: Stack Violation. Check the stack size of your program
Then I removed all the xTaskCreate() function call, but the XMD still prints the same warning.
If I remove the vTaskStartScheduler() call, the warning just dispeared.
I don’t understand why that warning comes without any task running?

davedoors wrote on Monday, November 28, 2011:

The kernel creates at least one, and possibly two tasks, when you call vTaskStartScheduler(). So tasks are being created, even if you don’t create them in your code.

How does it know the stack has been violated? What check is it performing to determine that? If it is just checking that the stack pointer is in the stack segment as configured by your linker script then the warning message can probably be ignored. I know this is how the IAR compiler works, so it is likely to be the same in your ISE. When a task is running, the stack pointer will (correctly) point to the stack allocated to that task, which will come from a heap somewhere, and be outside of the memory region the tool expects it to point into.

fbpp wrote on Monday, November 28, 2011:

This is how I get the Stack Violation:
1. run cmd.exe
2. run C:\Xilinx\13.3\ISE_DS\EDK\bin\nt64\xmd.exe inside of cmd.exe

XMD% connect mb mdm
Warning: Stack Violation. Check the stack size of your program

JTAG chain configuration

Device   ID Code        IR Length    Part Name
1       34008093           6        XC6SLX45
2       6424c093          10        XC6VLX195T
3       6424c093          10        XC6VLX195T

MicroBlaze Processor Configuration :

MMU Type………………………No_MMU
No of PC Breakpoints……………2
No of Read Addr/Data Watchpoints…1
No of Write Addr/Data Watchpoints…1
Instruction Cache Support……….on
Instruction Cache Base Address……0x8a000000
Instruction Cache High Address……0x8a1fffff
Data Cache Support………………on
Data Cache Base Address…………0x8a000000
Data Cache High Address…………0x8a1fffff
Exceptions  Support…………….on
FPU  Support……………………off
Hard Divider Support……………on
Hard Multiplier Support…………on - (Mul32)
Barrel Shifter Support………….on
MSR clr/set Instruction Support….on
Compare Instruction Support………on
Data Cache Write-back Support……off
Fault Tolerance Support…………off
Stack Protection Support…………on

Connected to “mb” target. id = 0
Starting GDB server for “mb” target (id = 0) at TCP port no 1235
XMD% dow app.elf
Downloading Program - app.elf
        section, .vectors.reset: 0x00000000-0x00000007
        section, .vectors.sw_exception: 0x00000008-0x0000000f
        section, .vectors.interrupt: 0x00000010-0x00000017
        section, .vectors.hw_exception: 0x00000020-0x00000027
        section, .text: 0x8a000000-0x8a034bdb
        section, .init: 0x8a034bdc-0x8a034c13
        section, .fini: 0x8a034c14-0x8a034c33
        section, .ctors: 0x8a034c34-0x8a034c3b
        section, .dtors: 0x8a034c3c-0x8a034c43
        section, .rodata: 0x8a034c44-0x8a046e47
        section, .data: 0x8a046e48-0x8a04afa3
        section, .eh_frame: 0x8a04afa4-0x8a04afa7
        section, .jcr: 0x8a04afa8-0x8a04afab
        section, .bss: 0x8a04afb0-0x8a08e45b
        section, .heap: 0x00000050-0x0000284f
        section, .stack: 0x00002850-0x0000504f
Setting PC with Program Start Address 0x00000000
System Reset …. DONE

XMD% run
Processor started. Type “stop” to stop processor

XMD% Warning: Stack Violation. Check the stack size of your program

I have had a very hard time to debug the program in Xilinx XSDK, it even couldn’t display local variable sometime, and it has problem to step through for loop. So I am wondering if it is REAL stack issue.

rtel wrote on Monday, November 28, 2011:

As DaveDoors said, it might just be complaining that the stack pointer is outside of its .stack section.  Looking at the print out above, your .stack section is between 0x2850 and 0x504f.  That is nearly 11K of stack that will be used by main().  The tasks themselves will use a stack from the FreeRTOS heap.  When the warning is output, look at the stack pointer value to see where it is.  If a task is running it will point somewhere in the FreeRTOS heap.  If a task is not executing, it should be in this 11k section somewhere.


uecasm wrote on Monday, April 16, 2012:

I was having the same issue, and further noticed that if I enabled exceptions via Xil_ExceptionsEnable() then the processor halted on a stack violation when vTaskStartScheduler is called.

The “quick” workaround would be to simply disable the stack protection exception in the IP core configuration for the CPU, and rely on FreeRTOS’s stack protection mechanism instead.

However it’d be nice if FreeRTOS could be modified to support the CPU-based stack protection instead, as it provides instant feedback instead of detecting it only after-the-fact or on task switch (with the possibility of missing it entirely depending on the nature of the error).

I had a quick look at the code and what would be required to do it; the basics are pretty simple: portRESTORE_CONTEXT (and anything else which switches R1 to a different stack) needs to set the SLR and SHR registers (which only exist conditionally) to the extent of the stack being restored prior to restoring R1 to that stack.  Unfortunately I couldn’t find any easy way of determining the extent of the stack from there.  The logical (at least to me) way to do it would be to include those as context registers as well, and initialise them from pxPortInitialiseStack, but unfortunately that isn’t passed the stack extents.  The next most logical is to pull them out of the TCB, but that’s private to tasks.c, and in any case only includes one or other of the ends (plus the current top), which isn’t sufficient to calculate the extent.  (Which in turn means that FreeRTOS’ own stack checking can’t check for stack underflow.)

uecasm wrote on Tuesday, April 17, 2012:

Ok, I think I figured out a way to do it by using portUSING_MPU_WRAPPERS=1 and using xMPU_SETTINGS to contain the stack info.  (Which is not entirely unreasonable, if you consider stack protection to be a limited MPU application.)

It’s a little bit messy though since it also forced me to define stubs for all the MPU_* functions, which at the moment all just call back to the normal implementation, and hack my LD script for the new sections it created.  (Though I suppose that since the Microblaze can have an MMU enabled, someone might eventually want to do a full implementation of that.)

rtel wrote on Tuesday, April 17, 2012:

A port of FreeRTOS that implements the MPU stubs is only available for the Cortex-M3, which is why the subs just point back to the original functions for the Microblaze.  If you want the MPU functionality to protect the stack on a Microblaze you will have to implement the MPU changes yourself in the port layer.


uecasm wrote on Tuesday, April 17, 2012:

I think you misunderstood.  The stubs didn’t even exist before for the Microblaze - I had to add them in myself.  But I do have something which works now (it supports the stack protection exception being enabled; does not include wider MMU/MPU support).

If you’re interested in patches, just let me know where to send them. :slight_smile:

rtel wrote on Wednesday, April 18, 2012:

Yes, I would definitely be interested.  Here is a good place to upload them:

The traceTASK_SWITHED_IN and traceTASK_SWITCHED_OUT trace macros have been used in the past for augmenting ports, for doing things like adding FPU supports etc.  (the latest MicroBlaze port supports the FPU anyway, but not the MPU).


uecasm wrote on Friday, May 18, 2012:

My apologies for the delay; I got caught up in a different project for a while, and also needed to update my code to FreeRTOS 7.1.0 before generating patches. :slight_smile:

I tried to register at the site you linked; it claimed that it sent out an activation email but I never received it.  (And yes, I checked my spam folders, and tried getting it to send a second one.)