Cortex-M processors before jumping from IAP to application
This article is from Here
KBA Article ID: KA001423
Applies To: Cortex-M3, Cortex-M3 DesignStart Eval, Cortex-M3 DesignStart Eval Academic, Cortex-M3 DesignStart Pro, Cortex-M3 DesignStart Pro Academic, Cortex-M3 Safety Package, Cortex-M3 Safety Package, Cortex-M3 STL Package, Cortex-M3 with ETM, Cortex-M3 with ETM, Cortex-M4, Cortex-M4 + ETM-M4 Hybrid, Cortex-M4 Safety Package, Cortex-M4 Safety Package, Cortex-M4 STL Pkg, Cortex-M4 with FPU, Cortex-M4 with FPU/ETM, Cortex-M7, Cortex-M7 Safety Package, Cortex-M7 Safety Package, Cortex-M7 with FPU, Cortex-M7 with FPU/ETM
Confidentiality: Customer non-confidential
How do I configure Cortex-M processors before jumping from IAP to application in terms of exception handling?
Before jumping to user code, the In-system Application Programming (IAP) might involve exception handling. You must clean the working environment to a condition similar to the reset status.
To clean the working environment, perform the following steps:
Disable the interrupt response.
Disable all the enabled interrupts in the Nested Vectored Interrupt Controller (NVIC).
Disable all the enabled peripherals which might generate interrupt requests.
You must also clear:
All the pending interrupt flags in those peripherals.
All the pending interrupt requests in NVIC.
Disable SysTick and clear its exception pending bit.
Load the vector table address of user application code into Vector Table Offset Register (VTOR).
Use the Main Stack Pointer (MSP) as the current stack pointer (SP) and load its value from the vector table used by the application.
Note: In some cases when the process stack pointer (PSP) is used, simply loading the MSP with the user main stack pointer stored in the vector table does not work. If the system is working with unprivileged accesses, you must change the project configuration to use privileged accesses.
Enable the interrupt response.
After performing these steps, you are free to jump to user code for exception handling.
The following pseudocode is given for your reference:
//1. Disable interrupt response. __disable_irq(); //2. Disable all enabled interrupts in NVIC. memset((uint32_t *)NVIC->ICER, 0xFF, sizeof(NVIC->ICER)); /* 3. Disable all enabled peripherals which might generate interrupt requests. * Clear all pending interrupt flags in those peripherals. * This part is device-dependent, and you can write it by referring to device datasheet. */ /* Clear all pending interrupt requests in NVIC. */ memset((uint32_t *)NVIC->ICPR, 0xFF, sizeof(NVIC->ICPR)); // 4. Disable SysTick and clear its exception pending bit. SysTick->CTRL = 0; SCB->ICSR |= SCB_ICSR_PENDSTCLR_Msk; // 5. Load the vector table address of user application code in to VTOR. SCB->VTOR = USER_APPLICATION_VECTOR_TABLE_ADDRESS; // 6. Use the MSP as the current SP. // Set the MSP with the value from the vector table used by the application. __set_MSP( ((unsigned int *)(SCB->VTOR)) ); // In thread mode, enable privileged access and use the MSP as the current SP. __set_CONTROL( 0 ); // 7. Enable interrupts. __enable_irq(); // 8. The reset handler address could be found with following expression // ((unsigned int *)(SCB->VTOR))