Tasks not running after starting vTaskStartScheduler (Cortex-R5)

monwhooper wrote on Tuesday, August 06, 2019:

Hello,

I am trying to start a task and have it execute after calling vTaskStartScheduler, but the task does not start. The applications runs up until the point I call the task scheduler, and I only create one task before calling it. I will create other tasks after starting the scheduler.

I saw this paragraph in the FreeRTOS FAQ (FreeRTOS - Open Source RTOS Kernel for small embedded systems)

If the project you have created is compiling, and at least executing up to the point that the scheduler is started, but only a single task is executing or no tasks are executing at all after the call to vTaskStartScheduler(), then it is likely that the interrupt vector table is incorrect.

I am using FreeRTOS 10, which is built into the BSP for a Xilinx UltraScale+ MPSoC board. How can I verify that the interrupt vector table is correct, and, if it is correct, what can I look to next?

I tried raising the minimum stack size for tasks, as well, and I am using static allocation.

My FreeRTOSConfig.h file looks like this:

#ifndef _FREERTOSCONFIG_H
#define _FREERTOSCONFIG_H

#include "xparameters.h" 

#define configMAX_API_CALL_INTERRUPT_PRIORITY (18)

#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
#define configUSE_TICKLESS_IDLE	0
#define configTICK_RATE_HZ (100)

#define configUSE_PREEMPTION 1

#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configMAX_PRIORITIES (8)
#define configMINIMAL_STACK_SIZE (250)
#define configTOTAL_HEAP_SIZE (90 * 1024)
#define configMAX_TASK_NAME_LEN 10
#define configUSE_TRACE_FACILITY 1
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
#define configUSE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 10
#define configCHECK_FOR_STACK_OVERFLOW 2
#define configUSE_RECURSIVE_MUTEXES 1
#define configUSE_MALLOC_FAILED_HOOK 1
#define configUSE_APPLICATION_TASK_TAG 0
#define configUSE_COUNTING_SEMAPHORES 1
#define configUSE_QUEUE_SETS 1
#define configSUPPORT_STATIC_ALLOCATION 1

/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES 2

/* Software timer definitions. */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES - 1)
#define configTIMER_QUEUE_LENGTH 10
#define configTIMER_TASK_STACK_DEPTH ((configMINIMAL_STACK_SIZE) * 2)


/* If configUSE_TASK_FPU_SUPPORT is set to 1 (or undefined) then each task will
be created without an FPU context, and a task must call vTaskUsesFPU() before
making use of any FPU registers.  If configUSE_TASK_FPU_SUPPORT is set to 2 then
tasks are created with an FPU context by default, and calling vTaskUsesFPU() has
no effect. */
#define configUSE_TASK_FPU_SUPPORT 2

/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet             1
#define INCLUDE_uxTaskPriorityGet            1
#define INCLUDE_vTaskDelete                  1
#define INCLUDE_vTaskCleanUpResources        1
#define INCLUDE_vTaskSuspend                 1
#define INCLUDE_vTaskDelayUntil              1
#define INCLUDE_vTaskDelay                   1
#define INCLUDE_eTaskGetState                1

#define configUSE_STATS_FORMATTING_FUNCTIONS 1

#define configGENERATE_RUN_TIME_STATS 0
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()
#define portGET_RUN_TIME_COUNTER_VALUE()

#define configCOMMAND_INT_MAX_OUTPUT_SIZE 2096

/* Normal assert() semantics without relying on the provision of an assert.h
header file. */

#define configASSERT( x ) if( ( x ) == 0 ) vApplicationAssert( __FILE__, __LINE__ )
#define configTASK_RETURN_ADDRESS    NULL


/****** Hardware specific settings. *******************************************/
void FreeRTOS_SetupTickInterrupt( void );
#define configSETUP_TICK_INTERRUPT() FreeRTOS_SetupTickInterrupt()

void FreeRTOS_ClearTickInterrupt( void );
#define configCLEAR_TICK_INTERRUPT()	FreeRTOS_ClearTickInterrupt()

#define configINTERRUPT_CONTROLLER_BASE_ADDRESS XPAR_SCUGIC_0_DIST_BASEADDR
#define configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET 0x1000
#define configUNIQUE_INTERRUPT_PRIORITIES 32


#define INCLUDE_xSemaphoreGetMutexHolder 1
#define configUSE_DAEMON_TASK_STARTUP_HOOK 0
#define configUSE_NEWLIB_REENTRANT 0
#define configUSE_TIME_SLICING 1
#define configUSE_TASK_NOTIFICATIONS 1
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 0
#define INCLUDE_xTimerPendFunctionCall       1
#define INCLUDE_pcTaskGetTaskName            1
#define configTIMER_ID XPAR_XTTCPS_0_DEVICE_ID
#define configTIMER_BASEADDR XPAR_XTTCPS_0_BASEADDR
#define configTIMER_INTERRUPT_ID XPAR_XTTCPS_0_INTR
#define configINTERRUPT_CONTROLLER_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID

void vApplicationAssert( const char *pcFile, uint32_t ulLine );
#define recmuCONTROLLING_TASK_PRIORITY ( configMAX_PRIORITIES - 2 )

#ifdef FREERTOS_ENABLE_TRACE
#include "FreeRTOSSTMTrace.h"
#endif /* FREERTOS_ENABLE_TRACE */
#endif

In my application’s linker script, I have the following:

SECTIONS
{
.vectors : {
   KEEP (*(.vectors))
   *(.boot)
} > psu_r5_ddr_0_MEM_0

And .vectors is defined in port_asm_vectors.S as:

.section .vectors,"a"
_vector_table:
	ldr	pc,=_boot
	ldr	pc,=Undefined
	ldr   pc, _swi
	ldr	pc,=PrefetchAbortHandler
	ldr	pc,=DataAbortHandler
	NOP	/* Placeholder for address exception vector*/
	ldr   pc, _irq
	ldr	pc,=FIQHandler

_irq:   .word FreeRTOS_IRQ_Handler
_swi:   .word FreeRTOS_SWI_Handler

Any advice or ideas to try?

rtel wrote on Friday, September 13, 2019:

Sorry this post sat in moderation for a long time - no posts are supposed to go into moderation.

If the project is created by the Xilinx tools then I would epxect you would not have to edit the linker or vector files directly yourself.

Is the first task starting? Set a break point in the first task (which may be the timer task if that has the highest priority, implemented in Source/timers.c) or step through the vPortRestoreTaskContext() in \FreeRTOS\Source\portable\GCC\ARM_CA9\portASM.S to see if you enter the first task. If so next check to see if the tick interrupt is executing - you can do that by setting a break point in xTaskIncrementTick() in tasks.c - then report back what you find.