Skip to main content
BBİNG.11
Associate
February 20, 2021
Question

STM32 Bootloader Vector table relocation problem which is linked with CubeMX version

  • February 20, 2021
  • 12 replies
  • 5586 views

Hello All,

I need to start the flash program from 0x08020000 origin. I have updated the linker file with that value as you can see at below.

/* Memories definition */
MEMORY
{
 RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K
 FLASH (rx) : ORIGIN = 0x8020000, LENGTH = 128K //previous one was 256K
}

Indeed, I have updated the vector table register which is VTOR from system_stm32f4xx.c. You can see the SystemInit function at below.

/*!< Uncomment the following line if you need to relocate your vector Table in
 Internal SRAM. */
/* #define VECT_TAB_SRAM */
#define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field. //0x00
 This value must be a multiple of 0x200. */
/******************************************************************************/
 
void SystemInit(void)
{
 /* FPU settings ------------------------------------------------------------*/
 #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
 SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
 #endif
 /* Reset the RCC clock configuration to the default reset state ------------*/
 /* Set HSION bit */
 RCC->CR |= (uint32_t)0x00000001;
 
 /* Reset CFGR register */
 RCC->CFGR = 0x00000000;
 
 /* Reset HSEON, CSSON and PLLON bits */
 RCC->CR &= (uint32_t)0xFEF6FFFF;
 
 /* Reset PLLCFGR register */
 RCC->PLLCFGR = 0x24003010;
 
 /* Reset HSEBYP bit */
 RCC->CR &= (uint32_t)0xFFFBFFFF;
 
 /* Disable all interrupts */
 RCC->CIR = 0x00000000;
 
#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
 SystemInit_ExtMemCtl(); 
#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */
 
 /* Configure the Vector Table location add offset address ------------------*/
#ifdef VECT_TAB_SRAM
 SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
#else
 SCB->VTOR = 0x08020000UL | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
#endif
}

When I configure and compile this project with STM32CubeMX version 5.0.0, everything works fine. However, when I configure and compile this project with STM32CubeMX version 6.1.1, I receive independent watchdog timer reset. What would be the source of problem? It costs my 2-3 days approximately. How can i solve the problem? Thanks in advance.

This topic has been closed for replies.

12 replies

BBİNG.11
BBİNG.11Author
Associate
February 20, 2021

So, the MCU is STM32F401RCT6.

Tesla DeLorean
Guru
February 20, 2021

>>What would be the source of problem?

Sounds like the watchdog timer not being kicked.

Does the loader application at 0x08000000 start the watchdog?

Does your system Hard Fault, or otherwise enter an infinite while loop?

Are you sure its not in the Default Handler because the loader started an interrupt you're not servicing?

Instrument your system, especially the Hard Fault and Error Handlers so you know what's happening in your own system.

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
BBİNG.11
BBİNG.11Author
Associate
February 20, 2021

As I mentioned, the system is working accurately with CubeMX version 5.0.0, but it doesn't work above 5.0.0. Some questions have answers with this information.

I have also debugged the system, the system enters hard fault and VTOR register returns the FLASH_BASE value which is 0x08000000. __HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST) flag is triggered as well.

Pavel A.
February 20, 2021

So you compare the sources produced by different Cube version and... ?

--pa

MM..1
Super User
February 21, 2021

Maybe you dont properly understand init, you dont edit code, instead this you need set define value

#define VECT_TAB_OFFSET 0x20000 /*!< Vector Table base offset field. //0x00

too you realy use 128k as bootloader code , so big?

Tesla DeLorean
Guru
February 21, 2021

Personally I just set the SCB->VTOR to the vector table symbol and dispense with all the smoke and mirrors ORing values together that aren't synchronized to what the linker actually built.

But yes the size of the thing does suggest there is a kitchen sink full of issues, especially with the contract/handoff with the application

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
BBİNG.11
BBİNG.11Author
Associate
February 21, 2021

Dear All,

I have solved the problem. I have compared all the c and header files between previous version and updated version of stmcubeMX.

I detected that there is a difference between main.c files as you can see at below:

void Error_Handler(void)
{
 /* USER CODE BEGIN Error_Handler_Debug */
 /* User can add his own implementation to report the HAL error return state */
 __disable_irq();
 while (1)
 {
 }
 /* USER CODE END Error_Handler_Debug */
}

The updated one contains these lines. When the progam enters error_handler, irq is disabled and entered to infinite loop.

Previous one doesn't contain these lines. When I disable these lines, the program works accurately.

Do you have any idea about what's going on ?

Thanks in advance.

BBİNG.11
BBİNG.11Author
Associate
February 21, 2021

So, the system enters to Error_Handler();

void SystemClock_Config(void)
{
 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
 {
 Error_Handler();
 }
}

There is a problem about RCC_OscConfig as far as I understand. What may be the problem ?

BBİNG.11
BBİNG.11Author
Associate
February 21, 2021

I have researched on the internet, but I can not find anything about the issue. Could you please help me about the problem? What may be root cause of the problem?

Here is the RCC configuration:

void SystemClock_Config(void)
{
 RCC_OscInitTypeDef RCC_OscInitStruct = {0};
 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
 RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
 
 /** Configure the main internal regulator output voltage
 */
 __HAL_RCC_PWR_CLK_ENABLE();
 __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
 /** Initializes the RCC Oscillators according to the specified parameters
 * in the RCC_OscInitTypeDef structure.
 */
 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSI;
 RCC_OscInitStruct.HSIState = RCC_HSI_ON;
 RCC_OscInitStruct.HSICalibrationValue = 8;
 RCC_OscInitStruct.LSIState = RCC_LSI_ON;
 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
 RCC_OscInitStruct.PLL.PLLM = 8;
 RCC_OscInitStruct.PLL.PLLN = 84;
 RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
 RCC_OscInitStruct.PLL.PLLQ = 4;
 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
 {
 Error_Handler();
 }
 /** Initializes the CPU, AHB and APB buses clocks
 */
 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
 |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
 
 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
 {
 Error_Handler();
 }
 PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
 PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
 if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
 {
 Error_Handler();
 }
}

Thanks in advance.

BBİNG.11
BBİNG.11Author
Associate
February 22, 2021

I have detected the error source. But, I don't understand why I receive such an error. Do you have any idea?

/*-------------------------------- PLL Configuration -----------------------*/
if((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_OFF)
 {
 return HAL_ERROR;
 }
 else
 {
 /* Do not return HAL_ERROR if request repeats the current configuration */
 pll_config = RCC->PLLCFGR;
 if((READ_BIT(pll_config, RCC_PLLCFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) ||
 (READ_BIT(pll_config, RCC_PLLCFGR_PLLM) != RCC_OscInitStruct->PLL.PLLM) ||
 (READ_BIT(pll_config, RCC_PLLCFGR_PLLN) != RCC_OscInitStruct->PLL.PLLN) ||
 (READ_BIT(pll_config, RCC_PLLCFGR_PLLP) != RCC_OscInitStruct->PLL.PLLP) ||
 (READ_BIT(pll_config, RCC_PLLCFGR_PLLQ) != RCC_OscInitStruct->PLL.PLLQ))
 {
 return HAL_ERROR; // <- HAL_ERROR is returned.
 }
 

in stm32f4xx_hal.rcc.c, HAL_ERROR is returned. There is a problem about PLL configuration as far as I understand. These registers don't get along with compared values. Could you please help me?

Thanks in advance.

Tesla DeLorean
Guru
February 22, 2021

Probably because your loader has already started and is running from the PLL, but with different parameters.

You can't change the PLL settings on-the-fly, you need to switch to a different source first.

Better to set the appropriate clocks in the loader, and then not do-over in the application.

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..