Skip to main content
After Forever
Senior III
October 1, 2018
Question

STM32CubeMX LL Code Generating Bug when the Flash Interrupt is Enabled

  • October 1, 2018
  • 8 replies
  • 1996 views

I use STM32L0 series microcontroller with LL and CMSIS libraries, no HAL is selected in the advanced settings tab, only LL.

And still, when I enable the "Flash and EEPROM global interrupt" in the Configuration -> NVIC, STM32CubeMX starts using the HAL library and generating code for it. As I understand, LL (at least for STM32L0) misses a module for working with Flash, but still, I think this is a bug.

This topic has been closed for replies.

8 replies

Khouloud GARSI
Technical Moderator
October 1, 2018

Hi @After Forever​ ,

Thanks for your feedback!

It is reported internally for further check.

Khouloud.

Cyril FENARD
ST Employee
October 4, 2018

Hi @After Forever​ ,

 May you check your application's map file and verify there is something like the following:

.text.HAL_FLASH_IRQHandler
 
 0x08000688 0x110 Drivers/STM32L0xx_HAL_Driver/stm32l0xx_hal_flash.o
 
 0x08000688 HAL_FLASH_IRQHandler

  There is no LL code for FLASH, but please you may have look at stm32l0xx_hal_flash_ex.c, stm32l0xx_hal_flash_ramfunc.c, stm32l0xx_hal_flash.c files to write your application.

 You can also have a look in examples of CubeFW folders, i.e. STM32Cube_FW_L0_V1.11.0RC3\Projects\[NUCLEO-EVAL]\Examples\FLASH\...

 Hoping it helps.

 Regards.

 Cyril

After Forever
Senior III
October 4, 2018

Hi @Cyril FENARD​ 

More information: I have checked "Copy only the necessary library files" radio-button and "Generate peripheral initialization as a pair of '*c/*.h' files" checkbox.

After enabling the "Flash and EEPROM global interrupt" in the NVIC configuration window and re-generating the code I noticed that STM32CubeMX generated this function in stm32l0xx_it.c:

void FLASH_IRQHandler(void)
{
 /* USER CODE BEGIN FLASH_IRQn 0 */
 
 /* USER CODE END FLASH_IRQn 0 */
 HAL_FLASH_IRQHandler();
 /* USER CODE BEGIN FLASH_IRQn 1 */
 
 /* USER CODE END FLASH_IRQn 1 */
}

...and the stm32l0xx_hal_* files in the Drivers/STM32L0xx_HAL_Driver/Src directory. I don't have any HAL library selected, only LL. So this was an error, and I didin't even try to compile the code in this state (so can't look at the map file), because the existence of HAL makes my binary bigger than the Flash size of my microcontroller.

So I un-checked the "Flash and EEPROM global interrupt" in the NVIC configuration window, re-generating the code, this removed every mention of HAL from the code. Then I added a custom FLASH_IRQHandler function in one of the user code section in stm32l0xx_it.c, also another user function to enable the interrupt:

void FLASH_IRQHandler(void)
{
 if ((FLASH->SR & FLASH_SR_EOP)) {
 FLASH->SR = FLASH_SR_EOP;
 flash_eop_callback();
 } else if ((FLASH->SR & FLASH_SR_FWWERR)) {
 FLASH->SR = FLASH_SR_FWWERR;
 flash_error_callback(FLASH_SR_FWWERR);
 } else if ((FLASH->SR & FLASH_SR_NOTZEROERR)) {
 FLASH->SR = FLASH_SR_NOTZEROERR;
 flash_error_callback(FLASH_SR_NOTZEROERR);
 } else if ((FLASH->SR & FLASH_SR_SIZERR)) {
 FLASH->SR = FLASH_SR_SIZERR;
 flash_error_callback(FLASH_SR_SIZERR);
 } else if ((FLASH->SR & FLASH_SR_WRPERR)) {
 FLASH->SR = FLASH_SR_WRPERR;
 flash_error_callback(FLASH_SR_WRPERR);
 } else if ((FLASH->SR & FLASH_SR_RDERR)) {
 FLASH->SR = FLASH_SR_RDERR;
 flash_error_callback(FLASH_SR_RDERR);
 } else if ((FLASH->SR & FLASH_SR_OPTVERR)) {
 FLASH->SR = FLASH_SR_OPTVERR;
 flash_error_callback(FLASH_SR_OPTVERR);
 } else if ((FLASH->SR & FLASH_SR_PGAERR)) {
 FLASH->SR = FLASH_SR_PGAERR;
 flash_error_callback(FLASH_SR_PGAERR);
 } else {
 flash_error_callback(FLASH_UNKNOWN_ERROR);
 }
}
 
void flash_init(void)
{
 NVIC_SetPriority(FLASH_IRQn, 1);
 NVIC_EnableIRQ(FLASH_IRQn);
}

Cyril FENARD
ST Employee
October 5, 2018

 Hi @After Forever​ ,

May you try to compile the project from CubeMX, all HAL/LL objects will be generated, and then inspect result of your link. It should fit your flash memory, embedding only the code that is needed for the application. 

 Hoping it helps.

 Regards.

 Cyril

After Forever
Senior III
October 5, 2018

Hello @Cyril FENARD​ 

I did what you asked, and as was expected, the map file has several HAL functions and objects in it (like HAL_InitTick, HAL_Init, HAL_IncTick, HAL_NVIC_SetPriority, HAL_FLASH_IRQHandler, etc...):

 .text.HAL_InitTick
 0x000000000800c4b0 0x28 /home/sweden/projects/stm32l0-test/build/stm32l0xx_hal.c.o
 0x000000000800c4b0 HAL_InitTick
 .text.HAL_Init
 0x000000000800c4d8 0x20 /home/sweden/projects/stm32l0-test/build/stm32l0xx_hal.c.o
 0x000000000800c4d8 HAL_Init
 .text.HAL_IncTick
 0x000000000800c4f8 0x10 /home/sweden/projects/stm32l0-test/build/stm32l0xx_hal.c.o
 0x000000000800c4f8 HAL_IncTick
 .text.c
 0x000000000800c508 0x74 /home/sweden/projects/stm32l0-test/build/stm32l0xx_hal_cortex.c.o
 0x000000000800c508 HAL_NVIC_SetPriority
 .text.HAL_NVIC_EnableIRQ
 0x000000000800c57c 0x24 /home/sweden/projects/stm32l0-test/build/stm32l0xx_hal_cortex.c.o
 0x000000000800c57c HAL_NVIC_EnableIRQ
 .text.HAL_SYSTICK_Config
 0x000000000800c5a0 0x34 /home/sweden/projects/stm32l0-test/build/stm32l0xx_hal_cortex.c.o
 0x000000000800c5a0 HAL_SYSTICK_Config
 .text.HAL_SYSTICK_Callback
 0x000000000800c5d4 0x2 /home/sweden/projects/stm32l0-test/build/stm32l0xx_hal_cortex.c.o
 0x000000000800c5d4 HAL_SYSTICK_Callback
 .text.HAL_SYSTICK_IRQHandler
 0x000000000800c5d6 0x8 /home/sweden/projects/stm32l0-test/build/stm32l0xx_hal_cortex.c.o
 0x000000000800c5d6 HAL_SYSTICK_IRQHandler
 *fill* 0x000000000800c5de 0x2 
 .text.FLASH_SetErrorCode
 0x000000000800c5e0 0xa8 /home/sweden/projects/stm32l0-test/build/stm32l0xx_hal_flash.c.o
 .text.HAL_FLASH_EndOfOperationCallback
 0x000000000800c688 0x2 /home/sweden/projects/stm32l0-test/build/stm32l0xx_hal_flash.c.o
 0x000000000800c688 HAL_FLASH_EndOfOperationCallback
 .text.HAL_FLASH_OperationErrorCallback
 0x000000000800c68a 0x2 /home/sweden/projects/stm32l0-test/build/stm32l0xx_hal_flash.c.o
 0x000000000800c68a HAL_FLASH_OperationErrorCallback
 .text.HAL_FLASH_IRQHandler
 0x000000000800c68c 0xe0 /home/sweden/projects/stm32l0-test/build/stm32l0xx_hal_flash.c.o
 0x000000000800c68c HAL_FLASH_IRQHandler
 .text.FLASH_PageErase
 0x000000000800c76c 0x2c /home/sweden/projects/stm32l0-test/build/stm32l0xx_hal_flash_ex.c.o
 0x000000000800c76c FLASH_PageErase
 .text.LL_EXTI_Init
 0x000000000800c798 0xf4 /home/sweden/projects/stm32l0-test/build/stm32l0xx_ll_exti.c.o
 0x000000000800c798 LL_EXTI_Init
 .text.LL_GPIO_Init
 0x000000000800c88c 0x150 /home/sweden/projects/stm32l0-test/build/stm32l0xx_ll_gpio.c.o
 0x000000000800c88c LL_GPIO_Init
 .text.LL_I2C_Init
 0x000000000800c9dc 0x118 /home/sweden/projects/stm32l0-test/build/stm32l0xx_ll_i2c.c.o
 0x000000000800c9dc LL_I2C_Init
 .text.RCC_GetHCLKClockFreq
 0x000000000800caf4 0x18 /home/sweden/projects/stm32l0-test/build/stm32l0xx_ll_rcc.c.o
 0x000000000800caf4 RCC_GetHCLKClockFreq
 .text.RCC_GetPCLK1ClockFreq
 0x000000000800cb0c 0x18 /home/sweden/projects/stm32l0-test/build/stm32l0xx_ll_rcc.c.o
 0x000000000800cb0c RCC_GetPCLK1ClockFreq
 .text.RCC_GetPCLK2ClockFreq
 0x000000000800cb24 0x18 /home/sweden/projects/stm32l0-test/build/stm32l0xx_ll_rcc.c.o
 0x000000000800cb24 RCC_GetPCLK2ClockFreq
 .text.RCC_PLL_GetFreqDomain_SYS
 0x000000000800cb3c 0x3c /home/sweden/projects/stm32l0-test/build/stm32l0xx_ll_rcc.c.o
 0x000000000800cb3c RCC_PLL_GetFreqDomain_SYS
 .text.RCC_GetSystemClockFreq
 0x000000000800cb78 0x48 /home/sweden/projects/stm32l0-test/build/stm32l0xx_ll_rcc.c.o
 0x000000000800cb78 RCC_GetSystemClockFreq
 .text.LL_RCC_GetSystemClocksFreq
 0x000000000800cbc0 0x20 /home/sweden/projects/stm32l0-test/build/stm32l0xx_ll_rcc.c.o
 0x000000000800cbc0 LL_RCC_GetSystemClocksFreq
 .text.LL_RCC_GetUSARTClockFreq
 0x000000000800cbe0 0xb8 /home/sweden/projects/stm32l0-test/build/stm32l0xx_ll_rcc.c.o
 0x000000000800cbe0 LL_RCC_GetUSARTClockFreq
 .text.LL_RTC_EnterInitMode
 0x000000000800cc98 0x70 /home/sweden/projects/stm32l0-test/build/stm32l0xx_ll_rtc.c.o
 0x000000000800cc98 LL_RTC_EnterInitMode

But my issue is that I don't want to use HAL, I selected only LL so I expect only LL and CMSIS functions in my linked binary. Don't you think this is a bug? Thank you!

0690X000006C8f3QAC.png

Cyril FENARD
ST Employee
October 8, 2018

Hi @After Forever​ ,

 Your feedback is in line with the implementation of the CubeMX tool.

 Minimum code elementary initialization uses HAL implementation. This is not a problem and you can still use LL implementation for IPs, depending on your choice.

 Regards.

 Cyril

After Forever
Senior III
October 8, 2018

@Cyril FENARD​ 

> Your feedback is in line with the implementation of the CubeMX tool.

Thank you for your time. Please let me (as my last resort about this issue) express my opinion that in cases when HAL is not being used that "implementation" is not logical, and here is why:

  1. Although ST mentions the "Possible concurrent usage of HAL and LL" with some limitations, LL is marketed as a lightweight alternative to HAL, not a supplement. I didn't select the HAL library anywhere (as shown in the screenshot posted previously), and yet it's being used
  2. Confusion, as LL is lightweight and for example it doesn't come with its own systick handler implementing a global millisecond counter, so it was implemented in the user code. Now, after enabling the flash interrupt, CubeMX inserted HAL with its own systick handler which conflicts with mine.
  3. Unnecessary, why do we need HAL's FLASH_IRQHandler with its callbacks (that would be useful only when the firmware in fact uses the HAL functions) for a simple interrupt handler where HAL is not required anywhere else in the firmware? Just generate an empty FLASH_IRQHandler interrupt handler function with user code sections, and 2 lines of code somewhere to set the priority and enable the interrupt. And that's everything required.

Thank you again.

Cyril FENARD
ST Employee
October 9, 2018

Hi @After Forever​ ,

I understand your last point, I will ask for improvements in future versions. 

Regards.

Cyril