2012-04-21 07:32 AM
Hi all,
I'm building a custom bootloader and need to provide a way to write protect/unprotect the memory. In order to commit the change, a system reset is required, which I sought to be a software-triggered reset. First off, what are the effects of a software-triggered reset? Will the program again go though ResetHandler as it does with an external reset? I've tried the following ways to generate the system software reset: - NVIC_SystemReset from within my code (goes into HardFault handler). This is expected to be wrong in my opinion given that the execution in not privileged. - Supervisor call, and within the SVCHandler use NVIC_SystemReset: no effect on AIRCR i.e. bit 2 still cleared and the while(1) within NVIC_SystemReset looping forever. But at least no Hard Fault. - Escalate privileges at startup within ResetHandler by __set_CONTROL(0x00000001): no effect. Any hits/flaws that you see? Thanks guys!! Marco #reset #system-reset-privilege-software2012-04-22 12:47 PM
This has been working for me
SystemReset PROC
EXPORT SystemReset
ldr r1, =0xE000ED0C ; NVIC Application Interrupt and Controller
ldr r0, =0x05FA0004 ; Magic
str r0, [r1, #0] ; Reset
self b self
bx lr
ENDP
This will reset the CPU, and it will re-enter via the ResetHandler. Not sure about the privileges, if you don't have any useful code in the Hard Fault (ie while(1); ) the putting the reset code there should suffice regardless of the user privilege.
You could also use the watchdog(s) to reset. Or looped back GPIO in OD mode.
Something that will cause problems would be a RESET pin tied or driven high by external circuitry.
2012-04-22 08:56 PM
Saw a function in core_cm3.h. Didn't use it though.
/* This function initiate a system reset request to reset the MCU. */ static __INLINE void NVIC_SystemReset(void) { __DSB(); /* Ensure all outstanding memory accesses included buffered write are completed before reset */ SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | SCB_AIRCR_SYSRESETREQ_Msk); /* Keep priority group unchanged */ __DSB(); /* Ensure completion of memory access */ while(1); /* wait until reset */ }2012-04-24 01:27 AM
Solved setting
VECTRESET
pin instead of
SYSRESETREQ
. Don't know if it's the proper solution or not. In the code below I use both since after reset I need to check the cause of it and using only
VECTRESET
wouldn't allow me to (in turn, setting only
SYSRESETREQ
doesn't trigger the reset).
Here's where I got the hint from:
https://rowley.zendesk.com/entries/20554673-stm32f-and-startup-from-reset
By the way, I also tried letting expire the Independent Watchdog but with no effect.
I use STM32F103CBT6 and the NRST pin is driven to ground externally by a button and a 100nF capacitor.
delay(0xFFF);
__DSB();
SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) |
(SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
SCB_AIRCR_VECTRESET_Msk |
SCB_AIRCR_SYSRESETREQ_Msk);
__DSB();
while
(1);
Do you guys know any way to check at runtime in which mode the code is running i.e. Privileged or Unprivileged?
Thanks!