2018-10-29 06:14 PM
STM32F091CBT6 BootLoader application problem
In the bootloader, there is no ploblem and jump to application code exactly.
If I jump to application firmware in main() routine, timer interrupt works well,
but if I jump to application firmware in sub-routine of timer interrupt or SysTick_Handler() routine, it seems that all interrupts aren't working.
How can I fix it ? Can anybody advice me ??
I use STM32F091CBT6 IC and compiled using IAR Embedded Workbench for ARM (Ver. 8.20.2)
My code is as below,
/*** Sub-routine call in SysTick_Handler() ***/
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
/* USER CODE END SysTick_IRQn 0 */
HAL_IncTick();
HAL_SYSTICK_IRQHandler();
/* USER CODE BEGIN SysTick_IRQn 1 */
Tick_counter++;
if(Tick_counter > 500)
{
Tick_counter = 0;
WDT_LED1_TOG;
}
System_Check_Process();
/* USER CODE END SysTick_IRQn 1 */
}
/*** Jump to application code of BootLoader ***/
#define ApplicationAddress 0x08004000
typedef void (*pFunction)(void);
pFunction Jump_To_Application;
uint32_t JumpAddress;
System_Check_Process(void)
{
HAL_DeInit();
JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4);
Jump_To_Application = (pFunction)JumpAddress;
/* Initialize user application's Stack Pointer */
__set_MSP(*(__IO uint32_t*) ApplicationAddress);
Jump_To_Application();
}
2018-10-29 07:03 PM
You need to relocate the vector table into RAM, and then map the zero memory to that RAM.
See the CM0 based IAP examples.
2018-10-29 07:05 PM
The app side code
STM32Cube_FW_F0_V1.9.0\Projects\STM32091C_EVAL\Applications\IAP\IAP_Binary_Template\Src\main.c
int main(void)
{
uint32_t i = 0;
/* STM32F0xx HAL library initialization:
- Configure the Flash prefetch
- Systick timer is configured by default as source of time base, but user
can eventually implement his proper time base source (a general purpose
timer for example or other time source), keeping in mind that Time base
duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and
handled in milliseconds basis.
- Low Level Initialization
*/
HAL_Init();
/* Configure the system clock to 48 MHz */
SystemClock_Config();
/* Relocate by software the vector table to the internal SRAM at 0x20000000 ***/
/* Copy the vector table from the Flash (mapped at the base of the application
load address 0x08004000) to the base address of the SRAM at 0x20000000. */
for(i = 0; i < 48; i++)
{
VectorTable[i] = *(__IO uint32_t*)(APPLICATION_ADDRESS + (i<<2));
}
/* Enable the SYSCFG peripheral clock*/
__HAL_RCC_SYSCFG_CLK_ENABLE();
/* Remap SRAM at 0x00000000 */
__HAL_SYSCFG_REMAPMEMORY_SRAM();
...
2018-10-29 07:22 PM
Thank you very much for the quick your advice !!
I already used remap, as below,
/*** Definition ***/
/* Private variables ---------------------------------------------------------*/
#define APPLICATION_ADDRESS (uint32_t)0x08004000
//#if (defined ( __CC_ARM ))
//__IO uint32_t VectorTable[48] __attribute__((at(0x20000000)));
//#elif (defined (__ICCARM__))
#pragma location = 0x20000000
__no_init __IO uint32_t VectorTable[48];
//#elif defined ( __GNUC__ )
//__IO uint32_t VectorTable[48] __attribute__((section(".RAMVectorTable")));
//#endif
/*** And in the main() function, ***/
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* Relocate by software the vector table to the internal SRAM at 0x20000000 ***/
for(i = 0; i < 48; i++)
{
VectorTable[i] = *(__IO uint32_t*)(APPLICATION_ADDRESS + (i<<2));
}
__HAL_RCC_SYSCFG_CLK_ENABLE();
__HAL_SYSCFG_REMAPMEMORY_SRAM();
Only if I jump to application firmware in sub-routine of timer interrupt or SysTick_Handler() routine, it seems that all interrupts aren't working after jumping to main application.
Thank you !!
2018-10-30 06:26 AM
You can't call in from interrupt context in this manner. You'd need to modify the stack so the transfer occurs as it unwinds when it leaves the interrupt handler.
2018-10-30 05:16 PM
Thank you so much !!
I am checking for the method of stack operation.
2018-10-30 06:56 PM
My preferred method is to reset, and have the Reset_Handler catch a flag and then vector to the app. Or just branch from a foreground task.
My worry with the IRQ Handler, if it is not the lowest priority, is that you might be multiple interrupts deep, and how that might impact states within the NVIC as the core unwinds. If you preemptively jump somewhere else and never come back, it will likely block other interrupts.
2018-10-31 12:16 AM
I appreciate for your kindness !!!!!
I have no much time to process the bootloader project, and so I’ll use “Jump_To_Application();�? in the main() routine only at first.
After the end of the bootloader project, I’ll recheck you’re the advice.
Thank you !!. Thank you !!.