cancel
Showing results for 
Search instead for 
Did you mean: 

stm32f103 Interrupt issue after jump from bootloader to application.

kipyo cho
Associate II
Posted on June 14, 2017 at 16:08

I am using the STM32F103 microcontroller.

I am using the IAR workbench and using cubeMX to make the boot loader.

My problem is that after the jump from the boot loader to the application, all the interrupts in the application do not work.

I would be grateful to let them know what I'm missing.

The ICF file in the boot loader is written as follows.

/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile='$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml' */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x08000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x08000000;
define symbol __ICFEDIT_region_ROM_end__ = 0x08004FFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__ = 0x2000FFFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x800;
define symbol __ICFEDIT_size_heap__ = 0x800;
/**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G;
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
initialize by copy { readwrite };
do not initialize { section .noinit };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in ROM_region { readonly };
place in RAM_region { readwrite,
 block CSTACK, block HEAP };
�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

The main.c file in the boot loader is written as follows.

void disable_Sys_Conf(void)
{
HAL_UART_DeInit(&huart2);
HAL_UART_DeInit(&huart1);
HAL_UART_MspDeInit(&huart2);
HAL_UART_MspDeInit(&huart1);
 HAL_RCC_DeInit();
 HAL_DeInit();
__disable_irq();
__disable_interrupt();
SysTick->LOAD = 0;
SysTick->VAL = 0;
SysTick->CTRL = 0;
}
#define ApplicationAddress 0x08005000
typedef void (*pFunction)(void);
pFunction Jump_To_Application;
uint32_t JumpAddress;
void main_code_jump(void)
{
/* Test if user code is programmed starting from address 'ApplicationAddress' */
if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000)
{
/* Jump to user application */
JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4);
printf('\rJumpAddress %x\r\n',JumpAddress);
Jump_To_Application = (pFunction) JumpAddress;
printf('\rJump_To_Application %x\r\n', Jump_To_Application);
/* Initialize user application's Stack Pointer */
__set_MSP(*(__IO uint32_t*) ApplicationAddress);
Jump_To_Application();
}
}
static void Uart_Int_Init(void)
{
__HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE);
__HAL_UART_ENABLE_IT(&huart2, UART_IT_RXNE);
}
int main(void)
{
 /* USER CODE BEGIN 1 */
 /* USER CODE END 1 */
 /* MCU Configuration----------------------------------------------------------*/
 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
 HAL_Init();
 /* Configure the system clock */
 SystemClock_Config();
 /* Initialize all configured peripherals */
 MX_GPIO_Init();
 MX_USART1_UART_Init();
 MX_USART2_UART_Init();
 /* USER CODE BEGIN 2 */
Uart_Int_Init();
disable_Sys_Conf();
main_code_jump();
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
 
 /* USER CODE END WHILE */
 /* USER CODE BEGIN 3 */
 }
 /* USER CODE END 3 */
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

The ICF file of the application that runs after the jump is written as follows.

/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile='$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml' */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x08005000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x08005000;
define symbol __ICFEDIT_region_ROM_end__ = 0x0807FFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__ = 0x2000FFFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x800;
define symbol __ICFEDIT_size_heap__ = 0x800;
/**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G;
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
initialize by copy { readwrite };
do not initialize { section .noinit };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in ROM_region { readonly };
place in RAM_region { readwrite,
 block CSTACK, block HEAP };�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

The main.c file of the application that runs after the jump is written as follows.

static void Uart_Int_Init(void)
{
__HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE);
__HAL_UART_ENABLE_IT(&huart2, UART_IT_RXNE);
}
int main(void)
{
 /* USER CODE BEGIN 1 */ 
__enable_interrupt();
__enable_irq();
 /* USER CODE END 1 */
 /* MCU Configuration----------------------------------------------------------*/
 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
 HAL_Init();
 /* Configure the system clock */
 SystemClock_Config();
 /* Initialize all configured peripherals */
 MX_GPIO_Init();
 MX_DMA_Init();
 MX_ADC1_Init();
 MX_USART1_UART_Init();
 MX_USART2_UART_Init();
 /* USER CODE BEGIN 2 */
Uart_Int_Init();
prompt_print();
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
uint32_t kpcho = 0;
while (1)
{
 /* USER CODE END WHILE */
 /* USER CODE BEGIN 3 */
com_shell();
}
 /* USER CODE END 3 */
}
�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

I think the jump from the boot loader to the application is a success.

However, I found that HAL_delay (1000), UART TX / RX interrupts do not work.

I hope you can help me if you have done this or if you know what my problem is.

#interrupt-issue #stm32f103 #jump-to-application
5 REPLIES 5
Posted on June 14, 2017 at 19:51

You need to adjust the address of the vector table.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Posted on June 15, 2017 at 08:57

Thank you for your valuable feedback.

I still have questions.

Does the boot loader need to adjust the address of the vector table? Or should it be done in an application?

I would like to have an example that works normally.

Posted on June 15, 2017 at 09:15

Yes. Even if the user program does not use any interrupts you still might want to catch the exceptions.

https://www.keil.com/pack/doc/cmsis/Core/html/group__Core__Register__gr.html ♯ gaeb8e5f7564a8ea23678fe3c987b04013

();

SCB->VTOR = (uint32_t)&vectorTable;

https://www.keil.com/pack/doc/cmsis/Core/html/group__intrinsic__CPU__gr.html ♯ gacb2a8ca6eae1ba4b31161578b720c199

();

https://www.keil.com/pack/doc/cmsis/Core/html/group__Core__Register__gr.html ♯ ga0f98dfbd252b89d12564472dbeba9c27

();

Typically, you first boot into the loader. This will have it's vector table at 0. 

You then jump to user code, which will have it's vector table somewhere else.

The use program does not need to know that it has a remapped vector table. But you're free to choose to move it whenever you like.

Posted on June 16, 2017 at 03:10

Thank you very much.

The issue was solved with Clive one and Jeroen3's precious opinion.

I adjusted the vector table in the application area.

int main(void)
{
 /* USER CODE BEGIN 1 */
 SCB->VTOR = 0x08005004; 
__enable_interrupt();
__enable_irq();
 /* USER CODE END 1 */
 /* MCU Configuration----------------------------------------------------------*/
 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
 HAL_Init();

I am so happy to be running as I want.

Thank you again.

Posted on June 16, 2017 at 09:08

You omitted the __DSB(). It is there for a reason!

It completes when all explicit memory accesses before the DSB instruction complete.

This is to prevent you from enabling the global interrupt bit while the bus is still writing to the SCB.

More info:

https://community.arm.com/processors/b/blog/posts/memory-access-ordering-part-3---memory-access-ordering-in-the-arm-architecture