vListInsert jumps to Default_Handler

I’ve added FreeRTOS to an example of HTTP server from Keil MDK, it was originally made with RTX . I’m using an Infineon XMC4700 Relax Kit board. The project has the IPV4/6 network and mBedTLS stacks from ARM. The code only is:

int main(void)
vTaskStartScheduler(); // Start the RTOS

I’m having problems with the execution of the threads, due randomly goes to the Default_Handler after executing the vListInsert.
I’ve tried almost all combinations of thread priorities and stack sizes, some times takes more time and others less but almost always the way is the same:

Also, when the configASSERTis enabled always stops at task.c where:

configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );

where ucCurrentPriority is 0 and ucMaxSysCallPriority is 16, due the ucCurrentPriority value is loaded always with 0 from pcInterruptPriorityRegisters. The address assigned at port.c (0xE000E3F0) seems that is empty.

I’ve tried to change the configMAX_SYSCALL_INTERRUPT_PRIORITY from 16 up and down but with no improvements. Also I’ve changed the three default threads priorities: netEth0_Thread 32, netTLS_Thread 24, netCore_Thread 24.
Also I’ve changed the stacks sizes but seems don’t affect and always stops at the Default_Handler.

No idea what to go from here.

Moving thread to the kernel forum category as it is not Infineon specific.

The screenshot shows a bus fault.

The assert failing is critical and the first thing to fix as its telling you there is definitely a problem.

How many priority bits does your chip have? Please also attach your FreeRTOSConfig.h file to your reply.

The XMC4700 has 64 priority levels, so 6 bits.
I couldn’t upload a file, so this is the config file:

/* --------------------------------------------------------------------------
 * Copyright (c) 2013-2021 Arm Limited. All rights reserved.
 * SPDX-License-Identifier: Apache-2.0
 * Licensed under the Apache License, Version 2.0 (the License); you may
 * not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * --------------------------------------------------------------------------
 * $Revision:   V10.3.0
 * Project:     CMSIS-FreeRTOS
 * Title:       FreeRTOS configuration definitions
 * --------------------------------------------------------------------------*/


 * Application specific definitions.
 * These definitions should be adjusted for your particular hardware and
 * application requirements.
 * See http://www.freertos.org/a00110.html

#if (defined(__ARMCC_VERSION) || defined(__GNUC__) || defined(__ICCARM__))
#include <stdint.h>

#include "RTE_Components.h"
#include CMSIS_device_header

//-------- <<< Use Configuration Wizard in Context Menu >>> --------------------

//  <o>Minimal stack size [words] <0-65535>
//  <i> Stack for idle task and default task stack in words.
//  <i> Default: 128
#define configMINIMAL_STACK_SIZE                ((uint16_t)(128))

//  <o>Total heap size [bytes] <0-0xFFFFFFFF>
//  <i> Heap memory size in bytes.
//  <i> Default: 8192
#define configTOTAL_HEAP_SIZE                   ((size_t)8192)

//  <o>Kernel tick frequency [Hz] <0-0xFFFFFFFF>
//  <i> Kernel tick rate in Hz.
//  <i> Default: 1000
#define configTICK_RATE_HZ                      ((TickType_t)1000)

//  <o>Timer task stack depth [words] <0-65535>
//  <i> Stack for timer task in words.
//  <i> Default: 80
#define configTIMER_TASK_STACK_DEPTH            80

//  <o>Timer task priority <0-56>
//  <i> Timer task priority.
//  <i> Default: 40 (High)
#define configTIMER_TASK_PRIORITY               40

//  <o>Timer queue length <0-1024>
//  <i> Timer command queue length.
//  <i> Default: 5
#define configTIMER_QUEUE_LENGTH                5

//  <o>Preemption interrupt priority
//  <i> Maximum priority of interrupts that are safe to call FreeRTOS API.
//  <i> Default: 16

//  <q>Use time slicing
//  <i> Enable setting to use timeslicing.
//  <i> Default: 1
#define configUSE_TIME_SLICING                  1

//  <q>Idle should yield
//  <i> Control Yield behaviour of the idle task.
//  <i> Default: 1
#define configIDLE_SHOULD_YIELD                 1

//  <o>Check for stack overflow
//    <0=>Disable <1=>Method one <2=>Method two
//  <i> Enable or disable stack overflow checking.
//  <i> Callback function vApplicationStackOverflowHook implementation is required when stack checking is enabled.
//  <i> Default: 0
#define configCHECK_FOR_STACK_OVERFLOW          2

//  <q>Use idle hook
//  <i> Enable callback function call on each idle task iteration.
//  <i> Callback function vApplicationIdleHook implementation is required when idle hook is enabled.
//  <i> Default: 0
#define configUSE_IDLE_HOOK                     0

//  <q>Use tick hook
//  <i> Enable callback function call during each tick interrupt.
//  <i> Callback function vApplicationTickHook implementation is required when tick hook is enabled.
//  <i> Default: 0
#define configUSE_TICK_HOOK                     0

//  <q>Use deamon task startup hook
//  <i> Enable callback function call when timer service starts.
//  <i> Callback function vApplicationDaemonTaskStartupHook implementation is required when deamon task startup hook is enabled.
//  <i> Default: 0
#define configUSE_DAEMON_TASK_STARTUP_HOOK      0

//  <q>Use malloc failed hook
//  <i> Enable callback function call when out of dynamic memory.
//  <i> Callback function vApplicationMallocFailedHook implementation is required when malloc failed hook is enabled.
//  <i> Default: 0
#define configUSE_MALLOC_FAILED_HOOK            0

//  <o>Queue registry size
//  <i> Define maximum number of queue objects registered for debug purposes.
//  <i> The queue registry is used by kernel aware debuggers to locate queue and semaphore structures and display associated text names.
//  <i> Default: 0
#define configQUEUE_REGISTRY_SIZE               0

// <h>Event Recorder configuration
//  <i> Initialize and setup Event Recorder level filtering.
//  <i> Settings have no effect when Event Recorder is not present.

//  <q>Initialize Event Recorder
//  <i> Initialize Event Recorder before FreeRTOS kernel start.
//  <i> Default: 1
#define configEVR_INITIALIZE                    1

//  <e>Setup recording level filter
//  <i> Enable configuration of FreeRTOS events recording level
//  <i> Default: 1
#define configEVR_SETUP_LEVEL                   1

//  <o>Tasks functions
//  <i> Define event recording level bitmask for events generated from Tasks functions.
//  <i> Default: 0x05
//    <0x00=>Off <0x01=>Errors <0x05=>Errors + Operation <0x0F=>All
#define configEVR_LEVEL_TASKS                   0x05

//  <o>Queue functions
//  <i> Define event recording level bitmask for events generated from Queue functions.
//  <i> Default: 0x05
//    <0x00=>Off <0x01=>Errors <0x05=>Errors + Operation <0x0F=>All
#define configEVR_LEVEL_QUEUE                   0x05

//  <o>Timer functions
//  <i> Define event recording level bitmask for events generated from Timer functions.
//  <i> Default: 0x05
//    <0x00=>Off <0x01=>Errors <0x05=>Errors + Operation <0x0F=>All
#define configEVR_LEVEL_TIMERS                  0x05

//  <o>Event Groups functions
//  <i> Define event recording level bitmask for events generated from Event Groups functions.
//  <i> Default: 0x05
//    <0x00=>Off <0x01=>Errors <0x05=>Errors + Operation <0x0F=>All
#define configEVR_LEVEL_EVENTGROUPS             0x05

//  <o>Heap functions
//  <i> Define event recording level bitmask for events generated from Heap functions.
//  <i> Default: 0x05
//    <0x00=>Off <0x01=>Errors <0x05=>Errors + Operation <0x0F=>All
#define configEVR_LEVEL_HEAP                    0x05

//  <o>Stream Buffer functions
//  <i> Define event recording level bitmask for events generated from Stream Buffer functions.
//  <i> Default: 0x05
//    <0x00=>Off <0x01=>Errors <0x05=>Errors + Operation <0x0F=>All
#define configEVR_LEVEL_STREAMBUFFER            0x05
//  </e>
// </h>

// <h> Port Specific Features
// <i> Enable and configure port specific features.
// <i> Check FreeRTOS documentation for definitions that apply for the used port.

//  <q>Use Floating Point Unit
//  <i> Using Floating Point Unit (FPU) affects context handling.
//  <i> Enable FPU when application uses floating point operations.
//  <i> Default: 1
#define configENABLE_FPU                      1

//  <q>Use Memory Protection Unit
//  <i> Using Memory Protection Unit (MPU) requires detailed memory map definition.
//  <i> This setting is only releavant for MPU enabled ports.
//  <i> Default: 0
#define configENABLE_MPU                      0

//  <q> Use TrustZone Secure Side Only
//  <i> This settings prevents FreeRTOS contex switch to Non-Secure side.
//  <i> Enable this setting when FreeRTOS runs on the Secure side only.
#define configRUN_FREERTOS_SECURE_ONLY        0

//  <q>Use TrustZone Security Extension
//  <i> Using TrustZone affects context handling.
//  <i> Enable TrustZone when FreeRTOS runs on the Non-Secure side and calls functions from the Secure side.
//  <i> Default: 1
#define configENABLE_TRUSTZONE                1

//  <o>Minimal secure stack size [words] <0-65535>
//  <i> Stack for idle task Secure side context in words.
//  <i> This setting is only relevant when TrustZone extension is enabled.
//  <i> Default: 128
#define configMINIMAL_SECURE_STACK_SIZE       ((uint32_t)128)
// </h>

//------------- <<< end of configuration section >>> ---------------------------

/* Defines needed by FreeRTOS to implement CMSIS RTOS2 API. Do not change! */
#define configCPU_CLOCK_HZ                      (SystemCoreClock)
#define configSUPPORT_STATIC_ALLOCATION         1
#define configSUPPORT_DYNAMIC_ALLOCATION        1
#define configUSE_PREEMPTION                    1
#define configUSE_TIMERS                        1
#define configUSE_MUTEXES                       1
#define configUSE_RECURSIVE_MUTEXES             1
#define configUSE_COUNTING_SEMAPHORES           1
#define configUSE_TASK_NOTIFICATIONS            1
#define configUSE_TRACE_FACILITY                1
#define configUSE_16_BIT_TICKS                  0
#define configMAX_PRIORITIES                    56
#define configKERNEL_INTERRUPT_PRIORITY         255

/* Defines that include FreeRTOS functions which implement CMSIS RTOS2 API. Do not change! */
#define INCLUDE_xEventGroupSetBitsFromISR       1
#define INCLUDE_xSemaphoreGetMutexHolder        1
#define INCLUDE_vTaskDelay                      1
#define INCLUDE_xTaskDelayUntil                 1
#define INCLUDE_vTaskDelete                     1
#define INCLUDE_xTaskGetCurrentTaskHandle       1
#define INCLUDE_xTaskGetSchedulerState          1
#define INCLUDE_uxTaskGetStackHighWaterMark     1
#define INCLUDE_uxTaskPriorityGet               1
#define INCLUDE_vTaskPrioritySet                1
#define INCLUDE_eTaskGetState                   1
#define INCLUDE_vTaskSuspend                    1
#define INCLUDE_xTimerPendFunctionCall          1

/* Map the FreeRTOS port interrupt handlers to their CMSIS standard names. */
#define xPortPendSVHandler                      PendSV_Handler
#define vPortSVCHandler                         SVC_Handler

/* Ensure Cortex-M port compatibility. */
#define SysTick_Handler                         xPortSysTickHandler

#if (defined(__ARMCC_VERSION) || defined(__GNUC__) || defined(__ICCARM__))
/* Include debug event definitions */
#include "freertos_evr.h"

#endif /* FREERTOS_CONFIG_H */

It doesn’t look like you are defining configMAX_SYSCALL_INTERRUPT_PRIORITY correctly. You have to shift the value into the bits actually implemented in the Cortex-M core, which is the top six bits in your case. This is one of the tricky things with Cortex-M, and is explained here: RTOS for ARM Cortex-M - I think I gave that link earlier. Rather than this:


you need to do something like:

#define configPRIO_BITS       		6        /* 63 priority levels */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 	( 63 << (8 - configPRIO_BITS) )

You can use the examples for XMC devices in the FreeRTOS download as a reference. Starting here: https://github.com/FreeRTOS/FreeRTOS/blob/V10.4.1/FreeRTOS/Demo/CORTEX_M4F_Infineon_XMC4500_GCC_Atollic/src/FreeRTOSConfig.h#L97 within the config file.

Additional comments on your config file that are unrelated to your question:

  • The file includes options for things like TrustZone, which are only for ARMv8-M chips. So not applicable to the XMC4700.

  • There are an alarming number of task priorities defined. 56 in total. This will be very inefficient as it is more than can be defined when using the port optimised task selection method. Port optimised task selection using a couple of assembly instructions to pick the priority of the next task to run. To do that it uses a bitmap in a 32-bit value, hence can’t do more priorities than 0 to 31. If you don’t use that method then you will be using a generic C algorithm, and in this case, over a wide distribution of possible priorities.

I’ve taken the default freertos config file supplied by ARM without any modifications.
Using the example from Github , now the value configMAX_SYSCALL_INTERRUPT_PRIORITY is 20 and configKERNEL_INTERRUPT_PRIORITY is 252.
Can not change configMAX_PRIORITIES due in freertos_os2.h there is this code:

#if (configMAX_PRIORITIES != 56)
    CMSIS-RTOS2 defines 56 different priorities (see osPriority_t) and portable CMSIS-RTOS2
    implementation should implement the same number of priorities.
    Set #define configMAX_PRIORITIES 56 to fix this error.
  #error "Definition configMAX_PRIORITIES must equal 56 to implement Thread Management API."

It now stops at the same assert line in port.c, the difference is that ucMaxSysCallPriority is 20 instead of 16.

I will continue without the assert to find if there is improvement, maybe lowering configKERNEL_INTERRUPT_PRIORITY is the key.
I’ve read about the priority bits but was not clear about how the shits affected the predefined priorities, thanks for your help.

configKERNEL_INTERRUPT_PRIORITY should be 255.

You say you got that configuration from Arm - can you give more detail? Was it shipped in a CMSIS pack, or with an IDE example, or somewhere else?

If the number must be 56 (why 56? seems a bit random) then don’t use all 56 priorities. For example, if you only need 5 priorities, then use priorities 0 to 4, not 0, 10, 20, 30 and 40.

What is the value of ucCurrentPriority? Can you determine which interrupt are you in? Seems like you are calling a FreeRTOS API from an ISR priority of which is too high. See my this response which explains which ISRs can call FreeRTOS APIs: Understanding priority levels of ISR and FreeRTOS APIs - #16 by aggarg


I think from the screen shot it is interrupt 5, which is a bus fault.

The screenshot is for when the fault happens. I am talking about the assert.

The assert stops at port.c, in the function vPortValidateInterruptPriority().
The ucCurrentPriority is 0 and ucMaxSysCallPriority is 20.
The stack then is this:

With the assert disabled, it stills jumps to Default_Handler, the stack and interrupts are like this:

Could be one of the two enabled interrupts with priority 0 (System Service Call SVCALL, Ethernet ETH0_0) that causes it?

I’ve the same project but with the RTX5 instead of FreeRTOS and it doesn’t seems to fail.
A difference is that SVCALL has a priority of 62 instead of 0 with FReeRTOS, ETH0_0 still at priority 0.

Probably. Can you try decreasing the priority (numerically increase) of ETH_0 interrupt?

I could change the line of Net_Config_ETH_0.h were the priority is assigned. By default is osPriorityAboveNormal, that is 32 in priority:

//        Interface Thread Priority
#define ETH0_THREAD_PRIORITY    osPriorityAboveNormal

If I want to decrease the priority I should then use a lower number, if I look to the cmsis_os2.h priorities enum:

/// Priority values.
typedef enum {
  osPriorityNone          =  0,         ///< No priority (not initialized).
  osPriorityIdle          =  1,         ///< Reserved for Idle thread.
  osPriorityLow           =  8,         ///< Priority: low
  osPriorityLow1          =  8+1,       ///< Priority: low + 1
  osPriorityLow2          =  8+2,       ///< Priority: low + 2
  osPriorityLow3          =  8+3,       ///< Priority: low + 3
  osPriorityLow4          =  8+4,       ///< Priority: low + 4
  osPriorityLow5          =  8+5,       ///< Priority: low + 5
  osPriorityLow6          =  8+6,       ///< Priority: low + 6
  osPriorityLow7          =  8+7,       ///< Priority: low + 7
  osPriorityBelowNormal   = 16,         ///< Priority: below normal
  osPriorityBelowNormal1  = 16+1,       ///< Priority: below normal + 1
  osPriorityBelowNormal2  = 16+2,       ///< Priority: below normal + 2
  osPriorityBelowNormal3  = 16+3,       ///< Priority: below normal + 3
  osPriorityBelowNormal4  = 16+4,       ///< Priority: below normal + 4
  osPriorityBelowNormal5  = 16+5,       ///< Priority: below normal + 5
  osPriorityBelowNormal6  = 16+6,       ///< Priority: below normal + 6
  osPriorityBelowNormal7  = 16+7,       ///< Priority: below normal + 7
  osPriorityNormal        = 24,         ///< Priority: normal
  osPriorityNormal1       = 24+1,       ///< Priority: normal + 1
  osPriorityNormal2       = 24+2,       ///< Priority: normal + 2
  osPriorityNormal3       = 24+3,       ///< Priority: normal + 3
  osPriorityNormal4       = 24+4,       ///< Priority: normal + 4
  osPriorityNormal5       = 24+5,       ///< Priority: normal + 5
  osPriorityNormal6       = 24+6,       ///< Priority: normal + 6
  osPriorityNormal7       = 24+7,       ///< Priority: normal + 7
  osPriorityAboveNormal   = 32,         ///< Priority: above normal
  osPriorityAboveNormal1  = 32+1,       ///< Priority: above normal + 1
  osPriorityAboveNormal2  = 32+2,       ///< Priority: above normal + 2
  osPriorityAboveNormal3  = 32+3,       ///< Priority: above normal + 3
  osPriorityAboveNormal4  = 32+4,       ///< Priority: above normal + 4
  osPriorityAboveNormal5  = 32+5,       ///< Priority: above normal + 5
  osPriorityAboveNormal6  = 32+6,       ///< Priority: above normal + 6
  osPriorityAboveNormal7  = 32+7,       ///< Priority: above normal + 7
  osPriorityHigh          = 40,         ///< Priority: high
  osPriorityHigh1         = 40+1,       ///< Priority: high + 1
  osPriorityHigh2         = 40+2,       ///< Priority: high + 2
  osPriorityHigh3         = 40+3,       ///< Priority: high + 3
  osPriorityHigh4         = 40+4,       ///< Priority: high + 4
  osPriorityHigh5         = 40+5,       ///< Priority: high + 5
  osPriorityHigh6         = 40+6,       ///< Priority: high + 6
  osPriorityHigh7         = 40+7,       ///< Priority: high + 7
  osPriorityRealtime      = 48,         ///< Priority: realtime
  osPriorityRealtime1     = 48+1,       ///< Priority: realtime + 1
  osPriorityRealtime2     = 48+2,       ///< Priority: realtime + 2
  osPriorityRealtime3     = 48+3,       ///< Priority: realtime + 3
  osPriorityRealtime4     = 48+4,       ///< Priority: realtime + 4
  osPriorityRealtime5     = 48+5,       ///< Priority: realtime + 5
  osPriorityRealtime6     = 48+6,       ///< Priority: realtime + 6
  osPriorityRealtime7     = 48+7,       ///< Priority: realtime + 7
  osPriorityISR           = 56,         ///< Reserved for ISR deferred thread.
  osPriorityError         = -1,         ///< System cannot determine priority or illegal priority.
  osPriorityReserved      = 0x7FFFFFFF  ///< Prevents enum down-size compiler optimization.
} osPriority_t;

In any case, that changes the priority of the thread and don’t’ seems to change the ETH_0 interrupt priority, still at 0. I’ve tested it with thread priority 16 (osPriorityBelowNormal) and still jumps to Default_Hadler.
I could not see where to change the priority of the ETH_0 interrupt, the network stack is a library so I could only change the configuration headers.
The difference with the code that seems to work is in the ‘Interrupt System Service’ Call SVCALL. In FreeRTOS has priority 0 and in RTX has priority 63.
Is there some way to change this priority in FreeRTOS?

You can use the SHPR2 register to change the priority of SVC: Documentation – Arm Developer

Looking at the image that you shared though, the problematic ISR seems to be ETH0. The following configuration will not change the ISR priority as it is for the task priority:

#define ETH0_THREAD_PRIORITY    osPriorityAboveNormal

I think you should still be able to change the interrupt priority. Do you see a call to NVIC_SetPriority anywhere in your code?

I only find NVIC_SetPriority in the file cmsis_os2.c:

  Setup SVC to reset value.
__STATIC_INLINE void SVC_Setup (void) {
#if (__ARM_ARCH_7A__ == 0U)
  /* Service Call interrupt might be configured before kernel start     */
  /* and when its priority is lower or equal to BASEPRI, svc intruction */
  /* causes a Hard Fault.                                               */
  NVIC_SetPriority (SVCall_IRQn, 0U);

I’ve tried to change the priority of SVCall_IRQn to 63 (as seen in the project with RTX) before starting the kernel, but it sets again to 0.
I’ve successfully changed the priority of ETH0_0_IRQn to 63 and I’m testing it now.

How is that happening? We do not do that in the kernel code. Can you place a breakpoint on the above line and see where is it getting called from. Let me know what you see after lowering the priority of ETH0 interrupt.


I’m starting the kernel by using osKernelStart(). This function in cmsis_os2.c looks like this:

  Start the RTOS Kernel scheduler.
osStatus_t osKernelStart (void) {
  osStatus_t stat;
  BaseType_t state;

  if (IRQ_Context() != 0U) {
    stat = osErrorISR;
  else {
    state = xTaskGetSchedulerState();

    /* Start scheduler if initialized and not started before */
    if ((state == taskSCHEDULER_NOT_STARTED) && (KernelState == osKernelReady)) {
      /* Ensure SVC priority is at the reset value */
      /* Change state to ensure correct API flow */
      KernelState = osKernelRunning;
      /* Start the kernel scheduler */
      stat = osOK;
    } else {
      stat = osError;

  /* Return execution status */
  return (stat);

And SVC_Setup() is where SVCall_IRQn is set to 0 :

  Setup SVC to reset value.
__STATIC_INLINE void SVC_Setup (void) {
#if (__ARM_ARCH_7A__ == 0U)
  /* Service Call interrupt might be configured before kernel start     */
  /* and when its priority is lower or equal to BASEPRI, svc intruction */
  /* causes a Hard Fault.                                               */
  NVIC_SetPriority (SVCall_IRQn, 0U);

If I instead of calling osKernelStart() I call directly vTaskStartScheduler() then the SVCall_IRQn priority remains at 0. If I try to set to 63 before starting the kernel, then the program jumps to Default_Handler right when calling to prvPortStartFirstTask() in port.c.

So setting NVIC_SetPriority(ETH0_0_IRQn, 63) before starting the kernel seems by now the only thing that makes the code to not stop at configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ) and not jump randonmly to Default_Handler.

That seems the right solution as the problematic ISR was ETH0 from your screenshot.

I am a bit unclear about this. Which FreeRTOS port are you using?

I’m using the included in Keil, identified in port.c as FreeRTOS Kernel V10.4.6