Migration from v10.5.1 to v11.0.1 fails with new FreeRTOSConfig.h file


I tried to migrate from v10.5.1 to v11.0.1, but it doesn’t work if I use the config file template. It works if I use the config file from v10.5.1. The reason why I want to use the template file is because the different settings are well documented and I think it’s better to have a file with all available settings even if they’re defined to the defaults made in FreeRTOS.h.

The blog post about v11 states that it’s a drop-in for v10.6.x, so I checked the release notes for what must be done to migrate from v10.5.x to v10.6.x, but I couldn’t find anything obvious explaining what goes wrong.

I’m using a Cortex-M3 device and the application is quite simple: two tasks are created, both using the same function with a different parameter. Depending on the parameter a string is output on UART by printf() - I did this just for learning FreeRTOS. This works if I use the v10.5.1 config file. If I use the v11.0.1 config file each task is executed only once.

I tried to get the differences between the two config files, most of them are related to MPU and/or multicore devices, so I think they don’t apply. Definitions not shown below are identical in both configs and the shown definitions are only available in one of them or have a slight deviation:

#define configUSE_TIME_SLICING                     0
#define configUSE_TICKLESS_IDLE                    0
#define configTICK_TYPE_WIDTH_IN_BITS              TICK_TYPE_WIDTH_32_BITS
#define configUSE_MINI_LIST_ITEM                   1
#define configSTACK_DEPTH_TYPE                     size_t
#define configMESSAGE_BUFFER_LENGTH_TYPE           size_t
#define configHEAP_CLEAR_MEMORY_ON_FREE            0
#define configSTATS_BUFFER_MAX_LENGTH              0xFFFF
#define configTIMER_QUEUE_LENGTH        10
#define configAPPLICATION_ALLOCATED_HEAP             0
#define configENABLE_HEAP_PROTECTOR                  0
#define configUSE_SB_COMPLETED_CALLBACK       0
#define configUSE_CO_ROUTINES              0
#define configMAX_CO_ROUTINE_PRIORITIES    0
#define configTOTAL_MPU_REGIONS                                   8
#define configTEX_S_C_B_FLASH                                     0x07UL
#define configTEX_S_C_B_SRAM                                      0x07UL
#define configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY               1
#define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS                0
#define configUSE_MPU_WRAPPERS_V1                                 0
#define configPROTECTED_KERNEL_OBJECT_POOL_SIZE                   10
#define configSYSTEM_CALL_STACK_SIZE                              128
#define configENABLE_ACCESS_CONTROL_LIST                          1
#define configRUN_MULTIPLE_PRIORITIES             0
#define configUSE_CORE_AFFINITY                   0
#define configUSE_TASK_PREEMPTION_DISABLE         0
#define configUSE_PASSIVE_IDLE_HOOK               0
#define secureconfigMAX_SECURE_CONTEXTS        5
#define configENABLE_TRUSTZONE            0
#define configRUN_FREERTOS_SECURE_ONLY    0
#define configENABLE_MPU                  0
#define configENABLE_FPU                  0
#define configENABLE_MVE                  0
#define configUSE_TASK_NOTIFICATIONS           1
#define configUSE_QUEUE_SETS                   0
#define INCLUDE_xResumeFromISR                 1
#define INCLUDE_xEventGroupSetBitFromISR       1
#define INCLUDE_xTaskGetHandle                 0
#define INCLUDE_xTaskResumeFromISR             1

While writing the above I recognized that when using the new config file, something prevents the SysTick handler from being executed. I’ll investigate this further. Any hints which setting of the new config file might cause this behaviour are welcome :slight_smile:


The default for configUSE_TIME_SLICING is 1 and template configuration has this value set to 0. I do not recall why I set the default to 0 in this case and it may be a bad choice.

Time slicing will rotate through ready tasks of the same priority when preemption is also turned on. Without time slicing, only one task will run until it is blocked and then the next task in the ready list will run.

Also interesting is you identify configUSE_TICKLESS_IDLE as a difference between the files. The selection in the template is 0. The default is also 0 and the selection above is 0. Does the working configuration enable tickless idle?

Is it possible to stop the CPU and check what task is running after it has executed both tasks once? Can you verify that the tick timer is running? Perhaps put a breakpoint in the tick interrupt.

Good Luck, I am curious about your results.

Another important config to look at is configMAX_SYSCALL_INTERRUPT_PRIORITY. What is the difference here?

Hello Joseph & Gaurav,

Ah, okay. This seems to be one of the rare settings where the description in the template doesn’t mention the default :slight_smile: I set it to one, but it hasn’t had any effect. Anyway, if I understand your description correctly it means that there are only rare cases where it should be set to 0?

For the configKERNEL_INTERRUPT_PRIORITY setting, I assume it’s used not only on Cortex-M, right? If yes, the description is confusing because it states that it defaults to the “highest priority (0)”, but every Cortex-M example sets this value to the lowest priority :thinking: So, just for clarification: is the description wrong or are there other MCU types where it really needs to be the highest priority and only Cortex-M uses it on lowest priority? :crazy_face:

My fault, sorry: it’s on the default value on both configs. Reason why it’s in the above list is because it’s in the template, but not in the old configuration - I just missed to remove it from the list after checking if the values differ.

Using the old config stops at a breakpoint in the SysTick handler, but not with the new config as I wrote above. Starting the scheduler calls vPortSetupTimerInterrupt() as intended. With the new config, the breakpoint never hits => Solution to the issue at the end!

After both tasks runned once, it’s in the prvIdleTask() function, calling only prvCheckTasksWaitingTermination() where uxDeletedTasksWaitingCleanUp variable is zero all the time.

The description states that the former is just another name for the latter, so I decided to do exactly that :slight_smile: It’s to avoid the need of changing both (and maybe forgetting one of them) when using different ports. It’s in the list because it was not in the old configuration.

Solution: investigating the SysTick behaviour and checking the content of the SysTick control register revealed that with the old configuration bit 2 (SysTick clock: 0 = external, 1 = CPU clock) was set. With the new configuration this bit was cleared because I also used configSYSTICK_CLOCK_HZ with the same value as for configCPU_CLOCK_HZ => I thought this would only change the calculation for the reload value - but I didn’t think about that it will also affect the timer configuration which is now under full control of the OS. After disabling configSYSTICK_CLOCK_HZ the SysTick handler is called as intended.

That’s one of the best ways for a beginner like me to learn the subtleties of FreeRTOS :smiley: So, many thanks to Joseph for pointing me into the right direction :+1: Now I can try to migrate my video terminal parser project to FreeRTOS.


1 Like

That line should be removed. Would you like to raise a PR for that?

Thank you for sharing your soluion!

Unfortunately I’m not using GitHub :frowning: I don’t know how it works and how much effort it is to get it up and running under Windows.


No worries. We will do it. Thank you for pointing it out.

Glad that I can help improving it :slight_smile: But I think I’d need to get familiar with GitHub in the future. I found some other spots which were confusing or might be optimized.


This PR addresses the issue - Update comment in template FreeRTOSConfig.h by aggarg · Pull Request #1007 · FreeRTOS/FreeRTOS-Kernel · GitHub.