ARM: STM32Cube Generated Code Clashes with Keil RTX4/5
Information in this knowledgebase article applies to:
I have a Keil RTX based application using STM32Cube generated code and it does not work correctly. After some time it starts to become unstable or even ends in a hardfault. So what is the problem using a Keil RTX together with STM32Cube?
The code generated by STM32Cube resets the interrupt priorities by calling the HAL_Init() function in its initialization code that runs in main(). But Keil RTX had already prepared the priorities for SVC, SysTick and PendSV as required before main(). Because HAL_Init() changed the interrupt priorities, they no longer meet the Keil RTX usage requirements, and the Keil RTX will not work correctly and could possibly hardfault.
Look in the STM32Cube generated code for the following code lines, usually found in a function HAL_MspInit():
/* SVCall_IRQn interrupt configuration */ HAL_NVIC_SetPriority(SVCall_IRQn, 0, 0); /* PendSV_IRQn interrupt configuration */ HAL_NVIC_SetPriority(PendSV_IRQn, 0, 0); /* SysTick_IRQn interrupt configuration */ HAL_NVIC_SetPriority(SysTick_IRQn, 15, 0);
Disable this code. The Keil RTX already configures the priorities for these interrupts, and that must not be changed for correct RTOS operation.
You could also use STM32Cube to replicate the Keil RTX settings. But as this is a dynamic configuration, based on PRIGROUP settings, and if something changes in this area in the future, this approach may no longer work.
Currently, there seems to be no option in STM32Cube to disable the generation of this interrupt priority initialization code. You may want to contact ST to change this.
In Keil RTX 5.3.0 the initialization of the RTX interrupt priorities moved into the osKernelStart() function. In that case, the STM32Cube generated code does not need to be modified when osKernelStart() is called after HAL_Init().
Last Reviewed: Friday, November 13, 2020
of your data.