_abort_stack_end

I often meet a problem of “_abort_stack_end”.
Do you know what causes this problem and how to overcome it?

I am grateful for any help!

I’m afraid you are going to have to provide a lot more information before anybody can begin to offer suggestions. For example, which FreeRTOS and compiler port are you using as _abort_stack_end sounds like a linker variable (i.e. not necessarily anything to do with FreeRTOS). Under what circumstances does this happen (when you first turn it on, after a few months, after a particular event, etc.).

@rtel : I apologize for an unclear question.

I am running FreeRTOS on two Cortex A9 cores of Zynq 7000.
When I start software in a debug mode, I see one core doesn’t work as expected. I wonder why _abort_stack_end() happens as the following screenshot.

Thanks. If I understand correctly then, you get a Data Abort exception when running in debug mode.

Have you tried debugging the data abort to find where in the code it is caused?
Does this also happen in Release mode?
Does it work ok when you run the code ‘standalone’ rather than through the debugger (because the startup requirements on the Zynq are different when running in the debugger Vs standalone).
Does this happen immediately, or occasionally?
Have you seen the instructions regarding careful use of standard library functions that might unknowingly use floating point instructions?

@rtel: Thanks for your hints!

Yes, I have.
The program fails to create a task, then jumps to _abort_stack_end and Data Abort Exception.
The following screenshot shows information of pxIndex when a task cannot be created.

This screenshot shows information of pxIndex when a task is successfully created.

It happens similarly in Release Mode.

I don’t get what “standalone” means. Can you clarify it?

Both cores run FreeRTOS. This problem happens immediately on Core 0 when the software creates a task. However, Core 1 doesn’t experience this issue.

Floating point is not used.

Can you elaborate on ‘fails to create a task’? The image shows 0xa5a5a5a5 being dereferenced (which is the value used to fill the stack), which will be the cause of the data abort, but something went wrong before then. Does ‘failed to create a task’ mean it could not allocate the memory for the task? If so, how did it then get into vListInsertEnd() within vTaskCreate() without having first allocated the required memory?

Thanks for your guidance!

—> a task cannot be created.

	BaseType_t xTaskCreate(	TaskFunction_t pxTaskCode,
						const char * const pcName,		/*lint !e971 Unqualified char types are allowed for strings and single characters only. */
						const configSTACK_DEPTH_TYPE usStackDepth,
						void * const pvParameters,
						UBaseType_t uxPriority,
						TaskHandle_t * const pxCreatedTask )
{
     ...

    prvAddNewTaskToReadyList( pxNewTCB );

    ...
}

static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB )
{
      ...
   
      prvAddTaskToReadyList( pxNewTCB );

     ...
}

 #define prvAddTaskToReadyList( pxTCB )																\
traceMOVED_TASK_TO_READY_STATE( pxTCB );														\
taskRECORD_READY_PRIORITY( ( pxTCB )->uxPriority );												\
vListInsertEnd( &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xStateListItem ) ); \
tracePOST_MOVED_TASK_TO_READY_STATE( pxTCB )


   void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem )
  {
       ...

  }

Exception: Cannot read target memory. Memory read error at 0xA5A5A5A5. PL AXI slave ports access is not allowed. This address has not been added to the memory map

This is value of pxList that is passed to the function vListInsertEnd()

I wonder why 0xa5a5a5a5 is dereferenced.

As per my last post - something went wrong before then. We need to find out why the task cannot be created. It looks like the task create function runs, errs, doesn’t notice it has erred, then tried to continue anyway with bad values that then lead to the abort - so the question is where did the bad value come from?

Sorry for the delay in replying!

When the program creates its first task.

static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB )
{
	/* Ensure interrupts don't access the task lists while the lists are being
	updated. */
	taskENTER_CRITICAL();
	{
		uxCurrentNumberOfTasks++;
		if( pxCurrentTCB == NULL )
		{
			/* There are no other tasks, or all the other tasks are in
			the suspended state - make this the current task. */
			pxCurrentTCB = pxNewTCB;

			if( uxCurrentNumberOfTasks == ( UBaseType_t ) 1 )
			{
				/* This is the first task to be created so do the preliminary
				initialisation required.  We will not recover if this call
				fails, but we will report the failure. */
				prvInitialiseTaskLists();
			}
			else
			{
				mtCOVERAGE_TEST_MARKER();
			}
		}
		else
		{
			/* If the scheduler is not already running, make this task the
			current task if it is the highest priority task to be created
			so far. */
			if( xSchedulerRunning == pdFALSE )
			{
				if( pxCurrentTCB->uxPriority <= pxNewTCB->uxPriority )
				{
					pxCurrentTCB = pxNewTCB;
				}
				else
				{
					mtCOVERAGE_TEST_MARKER();
				}
			}
			else
			{
				mtCOVERAGE_TEST_MARKER();
			}
		}

		uxTaskNumber++;

		#if ( configUSE_TRACE_FACILITY == 1 )
		{
			/* Add a counter into the TCB for tracing only. */
			pxNewTCB->uxTCBNumber = uxTaskNumber;
		}
		#endif /* configUSE_TRACE_FACILITY */
		traceTASK_CREATE( pxNewTCB );

		prvAddTaskToReadyList( pxNewTCB );

		portSETUP_TCB( pxNewTCB );
	}
	taskEXIT_CRITICAL();

	if( xSchedulerRunning != pdFALSE )
	{
		/* If the created task is of a higher priority than the current task
		then it should run now. */
		if( pxCurrentTCB->uxPriority < pxNewTCB->uxPriority )
		{
			taskYIELD_IF_USING_PREEMPTION();
		}
		else
		{
			mtCOVERAGE_TEST_MARKER();
		}
	}
	else
	{
		mtCOVERAGE_TEST_MARKER();
	}
}

uxCurrentNumberOfTasks has value of 0xa5a5a5a5.

However, it should be 0 because the first task is being created and its initial value is 0.
PRIVILEGED_DATA static volatile UBaseType_t uxCurrentNumberOfTasks = ( UBaseType_t ) 0U;

Values of pxCurrentTCB

Similarly, pxCurrentTCB should be NULL.

PRIVILEGED_DATA TCB_t * volatile pxCurrentTCB = NULL;





/*
 * Place the task represented by pxTCB into the appropriate ready list for
 * the task.  It is inserted at the end of the list.
 */
#define prvAddTaskToReadyList( pxTCB )																\
	traceMOVED_TASK_TO_READY_STATE( pxTCB );														\
	taskRECORD_READY_PRIORITY( ( pxTCB )->uxPriority );												\
	vListInsertEnd( &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xStateListItem ) ); \
	tracePOST_MOVED_TASK_TO_READY_STATE( pxTCB )

pxReadyTasksLists has values

I haven’t found the reason why the bad value appears yet.

Hi XuanTran,

I’m afraid there is not a big value in posting screen shots of FreeRTOS code. Can you show us the code YOU wrote, in particular the sequence up to your first invocation of xTaskCreate()? Can you show us the contents of your interrupt vector table and your linker command file? It almost looks as if your startup stack gets corrupted.

The source code is as follows.

   //disable caching on shared memory
    Xil_SetTlbAttributes( 0x00000000  ,0x14DE2);
    Xil_SetTlbAttributes(OCM_SHMEM_LO_ADDR,0x14DE2);

    shared_data_ptr->shm_valid=0;

    // SHM core2core constructs.
    // XScuGic IntcInstance;   // scope: portZynq7000.c:xInterruptController
    extern XScuGic xInterruptController;
    static int InterruptCounter = 0;


    //Setup semaphore on shared memory and initialize it
    StaticSemaphore_t * xSemaphoreBuffer = (StaticSemaphore_t *)SHMEM_SEMPHR_ADDR;
    xSemaphore = xSemaphoreCreateBinaryStatic(xSemaphoreBuffer);
    xSemaphoreGive(xSemaphore);

    //Setup function call queue
    StaticQueue_t * rpcCallQueue = (StaticQueue_t *)SHMEM_FNCTN_QUEUE_ADDR;
    uint8_t * queueStorageArea = (uint8_t *)SHMEM_FNCTN_QUEUE_STORAGE_ADDR;
    xFnctnQueue = xQueueGenericCreateStatic(FNCTN_QUEUE_LENGTH,FNCTN_STRUCT_SIZE,queueStorageArea,rpcCallQueue,0);

    //Setup function return queue
    StaticQueue_t * rpcReturnQueue = (StaticQueue_t *)SHMEM_RETURN_QUEUE_ADDR;
    uint8_t * retQueueStorageArea = (uint8_t *)SHMEM_RETURN_QUEUE_STORAGE_ADDR;
    xReturnQueue = xQueueGenericCreateStatic(RETURN_QUEUE_LENGTH,RETURN_VALUE_SIZE,retQueueStorageArea,rpcReturnQueue,0);

    // init the UARTs before waking up CPU1
    u32 * uartAvailable = &shared_data_ptr->uart_available;
    (*uartAvailable) = 0;
    dmb();
	if ( lld_uart_init() == 0 ) {
		(*uartAvailable) = 2;      // send ownership to core 0
	};

    sleep(1);

    xil_printf("CPU0: writing startaddress for cpu1 and reset.\n\r");

    {
    	/*
    	 *  Reset and start CPU1
    	 *  - Application for cpu1 exists at APP_CPU1_ADDR per cpu1 linkerscript
    	 *
    	 */
		#include "xil_misc_psreset_api.h"
		#include "xil_io.h"

    	#define A9_CPU_RST_CTRL		(XSLCR_BASEADDR + 0x244)
		#define A9_RST1_MASK 		0x00000002
		#define A9_CLKSTOP1_MASK	0x00000020
		#define CPU1_CATCH			0x00000024

		#define XSLCR_LOCK_ADDR		(XSLCR_BASEADDR + 0x4)
		#define XSLCR_LOCK_CODE		0x0000767B

    	u32 RegVal;

    	/*
    	 * Setup cpu1 catch address with starting address of app_cpu1. The FSBL initialized the vector table at 0x00000000
    	 * using a boot.S that checks for cpu number and jumps to the address stored at the
    	 * end of the vector table in cpu0_catch and cpu1_catch entries.
    	 * Note: Cache has been disabled at the beginning of main(). Otherwise
		 * a cache flush would have to be issued after this write
    	 */
    	Xil_Out32(CPU1_CATCH, APP_CPU1_ADDR);

    	/* Unlock the slcr register access lock */
    	Xil_Out32(XSLCR_UNLOCK_ADDR, XSLCR_UNLOCK_CODE);

    	//    the user must stop the associated clock, de-assert the reset, and then restart the clock. During a
    	//    system or POR reset, hardware automatically takes care of this. Therefore, a CPU cannot run the code
    	//    that applies the software reset to itself. This reset needs to be applied by the other CPU or through
    	//    JTAG or PL. Assuming the user wants to reset CPU1, the user must to set the following fields in the
    	//    slcr.A9_CPU_RST_CTRL (address 0xF8000244) register in the order listed:
    	//    1. A9_RST1 = 1 to assert reset to CPU0
    	//    2. A9_CLKSTOP1 = 1 to stop clock to CPU0
    	//    3. A9_RST1 = 0 to release reset to CPU0
    	//    4. A9_CLKSTOP1 = 0 to restart clock to CPU0

    	/* Assert and deassert cpu1 reset and clkstop using above sequence*/
    	RegVal = 	Xil_In32(A9_CPU_RST_CTRL);
    	RegVal |= A9_RST1_MASK;
    	Xil_Out32(A9_CPU_RST_CTRL, RegVal);
    	RegVal |= A9_CLKSTOP1_MASK;
    	Xil_Out32(A9_CPU_RST_CTRL, RegVal);
    	RegVal &= ~A9_RST1_MASK;
		Xil_Out32(A9_CPU_RST_CTRL, RegVal);
    	RegVal &= ~A9_CLKSTOP1_MASK;
		Xil_Out32(A9_CPU_RST_CTRL, RegVal);

    	/* lock the slcr register access */
    	Xil_Out32(XSLCR_LOCK_ADDR, XSLCR_LOCK_CODE);
    }


    while(! (shared_data_ptr->uart_available == 1)){
    	// wait for core 1 to hand back UART handle (simple "alive" detection)
    }

    u32 reg_val;
    //ensure OCM is mapped low
    reg_val = Xil_In32(XPS_SYS_CTRL_BASEADDR + 0x910);
    if((reg_val & 0x000F) != 0) {
        Xil_Out32((XPS_SYS_CTRL_BASEADDR + 0x8),0xDF0D );
        Xil_Out32((XPS_SYS_CTRL_BASEADDR + 0x910),(reg_val & 0xFFF0));
        Xil_Out32((XPS_SYS_CTRL_BASEADDR + 0x4),0x767B );
    }


    TaskHandle_t xadcTask;

	/* Start the two tasks */
	xTaskCreate( ccLld_powerController, ( const char * ) "PWRCTL",
			configMINIMAL_STACK_SIZE, NULL,
			POWER_CONTROLLER_TASK_PRIORITY, &pctrlTask );
	xTaskCreate( ccLld_i2cHandler, ( const char * ) "I2C",
			configMINIMAL_STACK_SIZE, NULL,
			I2C_HANDLER_TASK_PRIORITY, &i2cHandlerTaskHandle);
	xTaskCreate( ccLld_pmbusHandler, ( const char *) "PMBUS",
			configMINIMAL_STACK_SIZE, NULL,
			PMBUS_HANDLER_TASK_PRIORITY , &pmbusHandlerTaskHandle);
	xTaskCreate( ccLld_xadcLoop, ( const char * ) "XADC",
			configMINIMAL_STACK_SIZE, NULL,
			XADC_TASK_PRIORITY, &xadcTask );
	xTaskCreate(ccLld_qziHandler, (const char *) "QZI",
			configMINIMAL_STACK_SIZE, NULL,
			QZI_HANDLER_TASK_PRIORITY, &qziHandlerTaskHandle);

	/* Start the tasks and timer running. */
	vTaskStartScheduler();

	/* If all is well, the scheduler will now be running, and the following line
	will never be reached.  If the following line does execute, then there was
	insufficient FreeRTOS heap memory available for the idle and/or timer tasks
	to be created.  See the memory management section on the FreeRTOS web site
	for more details. */
	for( ;; );

lscript.ld

_STACK_SIZE = DEFINED(_STACK_SIZE) ? _STACK_SIZE : 0x40000;
_HEAP_SIZE = DEFINED(_HEAP_SIZE) ? _HEAP_SIZE : 0x20000;

_ABORT_STACK_SIZE = DEFINED(_ABORT_STACK_SIZE) ? _ABORT_STACK_SIZE : 1024;
_SUPERVISOR_STACK_SIZE = DEFINED(_SUPERVISOR_STACK_SIZE) ? _SUPERVISOR_STACK_SIZE : 2048;
_IRQ_STACK_SIZE = DEFINED(_IRQ_STACK_SIZE) ? _IRQ_STACK_SIZE : 1024;
_FIQ_STACK_SIZE = DEFINED(_FIQ_STACK_SIZE) ? _FIQ_STACK_SIZE : 1024;
_UNDEF_STACK_SIZE = DEFINED(_UNDEF_STACK_SIZE) ? _UNDEF_STACK_SIZE : 1024;

/* Define Memories in the system */

MEMORY
{
   ps7_ddr_0_S_AXI_BASEADDR : ORIGIN = 0x01000000, LENGTH = 0x01000000
   ps7_qspi_linear_0_S_AXI_BASEADDR : ORIGIN = 0xFC000000, LENGTH = 0x1000000
   ps7_ram_0_S_AXI_BASEADDR : ORIGIN = 0x0, LENGTH = 0x30000
   ps7_ram_1_S_AXI_BASEADDR : ORIGIN = 0xFFFF0000, LENGTH = 0xFE00
}

/* Specify the default entry point to the program */

ENTRY(_vector_table)

/* Define the sections, and where they are mapped in memory */

SECTIONS
{
.text : {
   KEEP (*(.vectors))
   *(.boot)
   *(.text)
   *(.text.*)
   *(.gnu.linkonce.t.*)
   *(.plt)
   *(.gnu_warning)
   *(.gcc_execpt_table)
   *(.glue_7)
   *(.glue_7t)
   *(.vfp11_veneer)
   *(.ARM.extab)
   *(.gnu.linkonce.armextab.*)
} > ps7_ddr_0_S_AXI_BASEADDR

.init : {
   KEEP (*(.init))
} > ps7_ddr_0_S_AXI_BASEADDR

.fini : {
   KEEP (*(.fini))
} > ps7_ddr_0_S_AXI_BASEADDR

.rodata : {
   __rodata_start = .;
   *(.rodata)
   *(.rodata.*)
   *(.gnu.linkonce.r.*)
   __rodata_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR

.rodata1 : {
   __rodata1_start = .;
   *(.rodata1)
   *(.rodata1.*)
   __rodata1_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR

.sdata2 : {
   __sdata2_start = .;
   *(.sdata2)
   *(.sdata2.*)
   *(.gnu.linkonce.s2.*)
   __sdata2_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR

.sbss2 : {
   __sbss2_start = .;
   *(.sbss2)
   *(.sbss2.*)
   *(.gnu.linkonce.sb2.*)
   __sbss2_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR

.data : {
   __data_start = .;
   *(.data)
   *(.data.*)
   *(.gnu.linkonce.d.*)
   *(.jcr)
   *(.got)
   *(.got.plt)
   __data_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR

.data1 : {
   __data1_start = .;
   *(.data1)
   *(.data1.*)
   __data1_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR

.got : {
   *(.got)
} > ps7_ddr_0_S_AXI_BASEADDR

.ctors : {
   __CTOR_LIST__ = .;
   ___CTORS_LIST___ = .;
   KEEP (*crtbegin.o(.ctors))
   KEEP (*(EXCLUDE_FILE(*crtend.o) .ctors))
   KEEP (*(SORT(.ctors.*)))
   KEEP (*(.ctors))
   __CTOR_END__ = .;
   ___CTORS_END___ = .;
} > ps7_ddr_0_S_AXI_BASEADDR

.dtors : {
   __DTOR_LIST__ = .;
   ___DTORS_LIST___ = .;
   KEEP (*crtbegin.o(.dtors))
   KEEP (*(EXCLUDE_FILE(*crtend.o) .dtors))
   KEEP (*(SORT(.dtors.*)))
   KEEP (*(.dtors))
   __DTOR_END__ = .;
   ___DTORS_END___ = .;
} > ps7_ddr_0_S_AXI_BASEADDR

.fixup : {
   __fixup_start = .;
   *(.fixup)
   __fixup_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR

.eh_frame : {
   *(.eh_frame)
} > ps7_ddr_0_S_AXI_BASEADDR

.eh_framehdr : {
   __eh_framehdr_start = .;
   *(.eh_framehdr)
   __eh_framehdr_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR

.gcc_except_table : {
   *(.gcc_except_table)
} > ps7_ddr_0_S_AXI_BASEADDR

.mmu_tbl (ALIGN(16384)) : {
   __mmu_tbl_start = .;
   *(.mmu_tbl)
   __mmu_tbl_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR

.ARM.exidx : {
   __exidx_start = .;
   *(.ARM.exidx*)
   *(.gnu.linkonce.armexidix.*.*)
   __exidx_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR

.preinit_array : {
   __preinit_array_start = .;
   KEEP (*(SORT(.preinit_array.*)))
   KEEP (*(.preinit_array))
   __preinit_array_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR

.init_array : {
   __init_array_start = .;
   KEEP (*(SORT(.init_array.*)))
   KEEP (*(.init_array))
   __init_array_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR

.fini_array : {
   __fini_array_start = .;
   KEEP (*(SORT(.fini_array.*)))
   KEEP (*(.fini_array))
   __fini_array_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR

.ARM.attributes : {
   __ARM.attributes_start = .;
   *(.ARM.attributes)
   __ARM.attributes_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR

.sdata : {
   __sdata_start = .;
   *(.sdata)
   *(.sdata.*)
   *(.gnu.linkonce.s.*)
   __sdata_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR

.sbss (NOLOAD) : {
   __sbss_start = .;
   *(.sbss)
   *(.sbss.*)
   *(.gnu.linkonce.sb.*)
   __sbss_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR

.tdata : {
   __tdata_start = .;
   *(.tdata)
   *(.tdata.*)
   *(.gnu.linkonce.td.*)
   __tdata_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR

.tbss : {
   __tbss_start = .;
   *(.tbss)
   *(.tbss.*)
   *(.gnu.linkonce.tb.*)
   __tbss_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR

.bss (NOLOAD) : {
   __bss_start = .;
   *(.bss)
   *(.bss.*)
   *(.gnu.linkonce.b.*)
   *(COMMON)
   __bss_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR

_SDA_BASE_ = __sdata_start + ((__sbss_end - __sdata_start) / 2 );

_SDA2_BASE_ = __sdata2_start + ((__sbss2_end - __sdata2_start) / 2 );

/* Generate Stack and Heap definitions */

.heap (NOLOAD) : {
   . = ALIGN(16);
   _heap = .;
   HeapBase = .;
   _heap_start = .;
   . += _HEAP_SIZE;
   _heap_end = .;
   HeapLimit = .;
} > ps7_ddr_0_S_AXI_BASEADDR

.stack (NOLOAD) : {
   . = ALIGN(16);
   _stack_end = .;
   . += _STACK_SIZE;
   . = ALIGN(16);
   _stack = .;
   __stack = _stack;
   . = ALIGN(16);
   _irq_stack_end = .;
   . += _IRQ_STACK_SIZE;
   . = ALIGN(16);
   __irq_stack = .;
   _supervisor_stack_end = .;
   . += _SUPERVISOR_STACK_SIZE;
   . = ALIGN(16);
   __supervisor_stack = .;
   _abort_stack_end = .;
   . += _ABORT_STACK_SIZE;
   . = ALIGN(16);
   __abort_stack = .;
   _fiq_stack_end = .;
   . += _FIQ_STACK_SIZE;
   . = ALIGN(16);
   __fiq_stack = .;
   _undef_stack_end = .;
   . += _UNDEF_STACK_SIZE;
   . = ALIGN(16);
   __undef_stack = .;
} > ps7_ddr_0_S_AXI_BASEADDR

_end = .;
}

Did you make sure that your task priorities fall into the valid range defined by your configMAX_PRIORITIES constant?

Also, what are the CONTENTS of your interrupt vector table, in particular, where does your initial SP (offset 0) point to, and is there enough untouched RAM before it to cleanly run all of your xTaskCreate() calls?

You should also make it a habit to monitor the return values of ALL FreeRTOS calls, ie don’t just expect your xTaskCreate() calls to succeed. Also, in what context are the first lines of code (ie from ```
//disable caching on shared memory


called?

Also are you sure about using configMINIMAL_STACK_SIZE (what’s the value ?) for all your tasks ? That’s often not sufficient b/c it’s just the bare minimum.
I’d recommend to define configASSERT and also enable stack overflow checking for development/debugging in case you didn’t already.

Thanks so much for your swift reply!

    #define configMAX_PRIORITIES (8)
    /* Priorities at which the tasks are created. */
    #define POWER_CONTROLLER_TASK_PRIORITY    6 // This is the highest priority task
    #define	I2C_HANDLER_TASK_PRIORITY        ( PMBUS_HANDLER_TASK_PRIORITY + 1 )
    #define	PMBUS_HANDLER_TASK_PRIORITY      ( XADC_TASK_PRIORITY + 1 )
    #define XADC_TASK_PRIORITY               ( QZI_HANDLER_TASK_PRIORITY + 1 )
    #define QZI_HANDLER_TASK_PRIORITY        ( tskIDLE_PRIORITY + 1 )

Do you know where I can find information of interrupt vector table?

Thanks for your tips! Honestly, I didn’t write this code. I am curious about the issue and eager to learn new things.

   int main( void )
  {
	uint32_t status = XST_FAILURE;

    // Initialization of pheripherals
    ccLld_LedIoInit();
	ccLld_GpioInit();
	ccLld_drPllIoInit();
	ccLld_CBPosIoInit();
	ccLld_XcvuConfIoInit();
	ccLld_LldAnlgIoInit();
	ccLld_MJtagIoInit();
	ccLld_sysCtrlIoInit();
	ccLld_uWireIoInit();
	ccLld_xadc_init();
	ccLld_i2cInit();
	logInforInit();
    shared_data_ptr->swVersion = SDK_REV_CODE;
	ccLld_qziBoardInfor ();

	pmbusInit (&pmbusInstance);
	status = pmbusConfigureAllDevices (&pmbusInstance, pmbusDeviceTable, NUM_DCDC);
	if (XST_FAILURE == status)
	{
		xil_printf("Configure DCDCs via PMMUS failed.\r\n");
	}


    //disable caching on shared memory
    Xil_SetTlbAttributes( 0x00000000  ,0x14DE2);
    Xil_SetTlbAttributes(OCM_SHMEM_LO_ADDR,0x14DE2);
   ...
   ...
 }

Search for
.vectors

in your code base. Normally it’s in your startup file. Then look for the identifier stored there in offset 0, and find that one in your code base. That is the initial stack pointer loaded into your MCU at reset time. There must be enough RAM UP TO that address to run your startup code (and later on all of your maximum nested interrupts) correctly. Remember that the stack moves from higher to lower addresses (on most including your platforms).

Put a break point on the first line of main() and inspect the value of uxCurrentNumberOfTasks there. It should be 0 - if not your C startup code is not clearing the .bss section as it is supposed to.

Next inspect uxCriticalNesting - it should be 0xff. If it is not then the C startup code is not initialising the .data section correctly.

@hs2
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 8192)

use_freertos_asserts is set.
check_for_stack_overflow is set to 2.

@RAc : Is that .vector section that you mentioned?

.section .vectors
_vector_table:
	B	_boot
	B	Undefined
	B	SVCHandler
	B	PrefetchAbortHandler
	B	DataAbortHandler
	NOP	/* Placeholder for address exception vector*/
	B	IRQHandler
	B	FIQHandler

@rtel

The code that you pointed to is for MicroBlazeV9.
I am using CortexA9.

Do you know what causes the problems of .bss and .data sections?

Hmmm, where is the initial stack pointer?

Can you dump the memory beginning from start address 0 (that should be the location of the vector table)?

Edit: Oh I see, the A9 has a different layout… I’m not familiar with the core, and it seems not to be too easy to determine where in the boot sequence the initial stack pointer comes from. I still believe there is something wrong with your startup stack, maybe someone with more knowledge about that core can jump in?..

Is that what you meant?

/*****************************************************************************/
    /**
    * @file asm_vectors.s
    *
    * This file contains the initial vector table for the Cortex A9 processor
******************************************************************************/

#include "xil_errata.h"
#include "xparameters.h"

.org 0
.text
.arm

.global _boot
.global _freertos_vector_table
.global _vector_table

.globl _cpu0_catch
.globl _cpu1_catch
.globl OKToRun
.globl EndlessLoop0

.global FIQInterrupt
.global DataAbortInterrupt
.global PrefetchAbortInterrupt
.global vPortInstallFreeRTOSVectorTable

.extern FreeRTOS_IRQ_Handler
.extern FreeRTOS_SWI_Handler

.section .vectors
_vector_table:
_freertos_vector_table:
	B	  _boot
	B	  FreeRTOS_Undefined
	ldr   pc, _swi
	B	  FreeRTOS_PrefetchAbortHandler
	B	  FreeRTOS_DataAbortHandler
	NOP	  /* Placeholder for address exception vector*/
	LDR   PC, _irq
	B	  FreeRTOS_FIQHandler

_irq:   .word FreeRTOS_IRQ_Handler
_swi:   .word FreeRTOS_SWI_Handler

#if XPAR_CPU_ID==0
_cpu0_catch:
.word	OKToRun			/* fixed addr for caught cpu- */
_cpu1_catch:
.word	EndlessLoop0	/* fixed addr for caught cpu- */

#elif XPAR_CPU_ID==1
_cpu0_catch:
.word	EndlessLoop0
_cpu1_catch:
.word	OKToRun
#endif

.align 4
FreeRTOS_FIQHandler:			/* FIQ vector handler */
	stmdb	sp!,{r0-r3,r12,lr}	/* state save from compiled code */
FIQLoop:
	blx	FIQInterrupt			/* FIQ vector */
	ldmia	sp!,{r0-r3,r12,lr}	/* state restore from compiled code */
	subs	pc, lr, #4			/* adjust return */

.align 4
FreeRTOS_Undefined:				/* Undefined handler */
	b		.

.align 4
FreeRTOS_DataAbortHandler:		/* Data Abort handler */
#ifdef CONFIG_ARM_ERRATA_775420
	dsb
#endif
	stmdb	sp!,{r0-r3,r12,lr}	/* state save from compiled code */
	blx	DataAbortInterrupt		/*DataAbortInterrupt :call C function here */
	ldmia	sp!,{r0-r3,r12,lr}	/* state restore from compiled code */
	subs	pc, lr, #4			/* adjust return */

.align 4
FreeRTOS_PrefetchAbortHandler:	/* Prefetch Abort handler */
#ifdef CONFIG_ARM_ERRATA_775420
	dsb
#endif
	stmdb	sp!,{r0-r3,r12,lr}	/* state save from compiled code */
	blx	PrefetchAbortInterrupt	/* PrefetchAbortInterrupt: call C function here */
	ldmia	sp!,{r0-r3,r12,lr}	/* state restore from compiled code */
	subs	pc, lr, #4			/* adjust return */

.align 4
.type vPortInstallFreeRTOSVectorTable, %function
vPortInstallFreeRTOSVectorTable:

	/* Set VBAR to the vector table that contains the FreeRTOS handlers. */
	ldr	r0, =_freertos_vector_table
	mcr	p15, 0, r0, c12, c0, 0
	dsb
	isb
	bx lr


.end

Disassembly content:

00000000:   b       +300    ; addr=0x00000134
00000004:   b       +156    ; addr=0x000000a8
00000008:   b       +180    ; addr=0x000000c4
0000000c:   b       +244    ; addr=0x00000108
00000010:   b       +208    ; addr=0x000000e8
00000014:   nop
00000018:   b       +8      ; addr=0x00000028
0000001c:   b       +68     ; addr=0x00000068
00000020:   andeq   r0, r0, r12, ror #2
00000024:   andeq   r0, r0, r12, asr r1
00000028:   push    {r0,r1,r2,r3,r12,lr}
0000002c:   vpush   {d0-d7}
00000030:   vpush   {d16-d31}
00000034:   vmrs    r1, fpscr
00000038:   push    {r1}
0000003c:   vmrs    r1, fpexc
00000040:   push    {r1}
00000044:   bl      +27236  ; addr=0x00006ab0
00000048:   pop     {r1}
0000004c:   vmsr    fpexc, r1
00000050:   pop     {r1}
00000054:   vmsr    fpscr, r1
00000058:   vpop    {d16-d31}
0000005c:   vpop    {d0-d7}
00000060:   pop     {r0,r1,r2,r3,r12,lr}
00000064:   subs    pc, lr, #4
00000068:   push    {r0,r1,r2,r3,r12,lr}
0000006c:   vpush   {d0-d7}
00000070:   vpush   {d16-d31}
00000074:   vmrs    r1, fpscr
00000078:   push    {r1}
0000007c:   vmrs    r1, fpexc
00000080:   push    {r1}
00000084:   bl      +27152  ; addr=0x00006a9c
00000088:   pop     {r1}
0000008c:   vmsr    fpexc, r1
00000090:   pop     {r1}
00000094:   vmsr    fpscr, r1
00000098:   vpop    {d16-d31}
0000009c:   vpop    {d0-d7}
000000a0:   pop     {r0,r1,r2,r3,r12,lr}
000000a4:   subs    pc, lr, #4
000000a8:   push    {r0,r1,r2,r3,r12,lr}
000000ac:   ldr     r0, [pc, #+116]
000000b0:   sub     r1, lr, #4
000000b4:   str     r1, [r0]
......... ...

No. What happens in _boot? It looks as if the A9 requires the programmer to set up the stack pointer in the _boot routine.