There are cases when I need to do a reset of the device by software. For example I have loaded the application image with the bootloader, and then I need to perform a reset of the microcontroller to do a restart. As a human user I can press the reset button on the board. But how to do this from the software and application running on the board, without user manual intervention? Or if I simply want to reset the system for whatever reason?
Using Watchdog Timeout
In the past I have used the following approach for other microcontroller (e.g. the Freescale S08 and S12 devices):
- Setting up a watchdog timer
- Then when I want to do a reset, I do *not* kick (serve) the watchdog timer any more
- As a result, the WDT (watchdog timer) or COP (Computer operating properly) will timeout, and will reset the part
That approach is working, but well is not the easiest way. Especially as on ARM Cortex-M there is a better way :-).
Using ARM System Reset
The ARM Cortex-M which includes the Freescale Kinetis series cores have a System Reset functionality available in the AICR (Application Interrupt and Reset Control Register):
So all I need to write a 0x05FA to VECTKEY with a 1 to SYSRESETREQ :-).
The easiest way is if I used the KinetisTools Processor Expert component from SourceForge (see “McuOnEclipse Releases on SourceForge“):
This componet offers a SoftwareReset() function which I can use in my application. It is defined like this in the component:
void KIN1_SoftwareReset(void) { /* Generic way to request a reset from software for ARM Cortex */ To write to this register, you must write 0x5FA to the VECTKEY field, otherwise the processor ignores the write. SYSRESETREQ will cause a system reset asynchronously, so need to wait afterwards. */ #if KIN1_IS_USING_KINETIS_SDK SCB_AIRCR = (0x5FA<<SCB_AIRCR_VECTKEY_Pos)|SCB_AIRCR_SYSRESETREQ_Msk; #else SCB_AIRCR = SCB_AIRCR_VECTKEY(0x5FA) | SCB_AIRCR_SYSRESETREQ_MASK; #endif for(;;) { /* wait until reset */ } }So all what you need is to have such a piece of code in your application to do a system reset.
That component features as well an optional command line interface. That way I can reset the target with a command from the shell 🙂
Summary
To reset an ARM Cortex M by software, I can use the AIRCR register. Either I can do this directly, or using my KinetisTools component for Processor Expert :-).
As an additional note: there is a sticky ‘System Reset Status’ register available (I think on most Kinetis devices) which reports the reason for the reset. A good idea is to read that register at startup time and e.g. print the reset reason to the console (Thanks Charles for that cool idea!).
Happy resetting 🙂
Links:
- Cortex-M3 Technical Reference Manual: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0337e/ch06s03s02.html
- McuOnEclipse Releases on SourceForge
Great bit of info. Thanks.
LikeLike
Great information Erich. Thank you.
I had a query. Is it applicable to ARM cortex M4 as well?
LikeLike
Hi Vishal,
yes, it applies to ARM Cortex M4 as well.
LikeLike
Thanks a lot, Erich.
Regards,
Naruto Uzumaki 🙂
LikeLike
Or, you could use CMSIS with NVIC_SystemReset(). It does the same, but it’s already there for you 😉
LikeLiked by 2 people
Yes, true. But only if using the CMSIS and if that is provided by the vendor, which is not always the case.
LikeLike
Pingback: McuOnEclipse Components: 05-July-2015 Release | MCU on Eclipse
I am extrapolating from this that KDS provides no command to reset the processor from either the menu system or the toolbar? I have spent most of my career using classical embedded tools and am still sometimes taken aback by the things Eclipse cannot do.
I have used one other Eclipse derivative (Code Composer Studio) and that feature was built in.
LikeLike
Hi Gary,
of course KDS can reset/restart the microcontroller under debug, so your extrapolation is not correct ;-).
This article is about performing a reset from the software/application running on the target, not about how to do a reset with a debugger.
I hope that makes sense?
Erich
LikeLike
May I ask, then, where it is? I have made several attempt to find it, but so far no luck.
LikeLike
It is the restart button:

LikeLike
Ok, I did find that, but the description text: (Restart a process or debug target without terminating and re- launching) was so abstruse, I didn’t recognize it.
Thanks, Erich!
LikeLike
This reset usualy works for us, but sometimes it doesn’t… I’ve noticed that the user guide says: SYSRESETREQ -> asserts a proc_reset_signal.
This is intended to force a large system reset of all major components **except for debug**.
What does it mean? Debug means that I am currently debugging using a JTAG, or does it mean that I am running a “debug” configuration compiled image?
Also, I’ve found that the AIRCR register has two more bits:
VECTRESET & VECTCLRACTIVE, which we should reset whenever we write to this register, “otherwise behavior is Unpredictable”. Can this be the case…?
Thanks!
Lior.
LikeLike
Hi Lior,
it means that it does not reset the debug logic on the chip (has nothing to do with hardware).
I have not seen any issues on my side with the proposed way.
I see this note:
Note
SYSRESETREQ is cleared by a system reset, which means that asserting VECTRESET at the same time may cause SYSRESETREQ to be cleared in the same cycle as it is written to. This may prevent the external system from seeing SYSRESETREQ. It is therefore recommended that VECTRESET and SYSRESETREQ be used exclusively and never both written to 1 at the same time.
LikeLike
Thanks, Erich!
So, in other words, is it recommended to clear both bits (VECTRESET & VECTCLRACTIVE) at the same time that I set SYSRESETREQ – in order to prevent it to interfere with the reset action?
LikeLike
Hi Lior,
Only set the SYSRESETREQ bit, like in
SCB_AIRCR = SCB_AIRCR_VECTKEY(0x5FA) | SCB_AIRCR_SYSRESETREQ_MASK;
LikeLike
Hey,
I’ve noticed that maybe there is another option for Cortex-M3, which is to use RSTC_CR.
Have anyone tried this option?
Thanks,
Lior.
LikeLike
Pingback: Debugging ARM Cortex-M0+ HardFaults | MCU on Eclipse
HI! I had a problem with de watchdog. I initialize the watchdog, I do not refresh in the loop and the core doesn t reset. All the registers are initialize ok beacause y see them in the debuger.
¿Does anyone know if there is another register to enable the clock or something similar?
LikeLike
Which device, and which debugger? The watchdog functions depend on the device implementation, and I have seen debuggers which disable the watchdog (so you can debug).
Do you have the same if you run the board without the debugger?
LikeLike
Hi, thanks for your great posts! I’m getting an error when I try to Generate Processor Expert Code:
“Description Resource Path Location Type
Generator: FAILURE: at line 72: “Shell”/Shell has not assigned the component (file: Drivers\sw\KinetisTools.drv) WT4 KIN1 Processor Expert Problem”
If I tick the checkbox to use a shell (and add the required components for that) then it builds just fine. The problem seems to only occur when I try to use the KinetisTools without a shell. Any suggestions?
LikeLike
Hi Nick
Just checking: Are you using the latest version (https://mcuoneclipse.com/2017/09/25/mcuoneclipse-components-25-sept-2017-release/)?
LikeLike
Yes, I just installed the mcuoneclipse components (latest version) when I tried this.
LikeLike
Hi Nick,
hmm, I’m not able to reproduce this. Would you mind to send me your project (I don’t need the source files to my email address listed on https://mcuoneclipse.com/about/ so I can try to reproduce this?
LikeLike
I just sent it over
LikeLike
Hi Nick,
got it, thank you, looking into it as soon as I can and will respond to you.
Thanks!
Erich
LikeLike
Hi Nick,
Ok, I see now the problem :-(. I have fixed it and sent you the updated component. It is available on SourceForge as a patch release too: https://sourceforge.net/projects/mcuoneclipse/files/PEx%20Components/
I appologize for the problem it caused,
Erich
LikeLike
Hi Erich,
The given information is useful foe me, i wanted to read the reset reason as well. i have tried to read the reset reason using the CPUDBGSCRATCH register, but in the this memory (0xe010200c) always i can see 0xFFFFFFFC values. can you please suggest how exactly i can read the reset reason.
Thanks in advance.
LikeLike
Hi Shiva,
which microcontroller are you using?
LikeLike
Hi Erich,
Thank you for your explanation.
I’m working with power modes and using FRDM-KL02z board, I tried to use this method to exit the stop mode, I wrote “KIN1_SoftwareReset();” after calling the enter stop mode function but it is not working. Do you have any idea why it is not working ?as I’m expecting to exit the stop mode into normal run mode.
Regards
Banu
LikeLike
Hi Banu,
I have not used it in such a sitution. But if you are in stop mode, then no instructions get executed. So you need first to exit stop mode and then do the reset?
LikeLike
Hi Erich,
Yes, I need to exit the stop mode into the normal run, this can happen by either using reset or interrupt(WFI). I’m not sure how to use the WFI so I’m thinking if there is software reset code that let the M0+ exit the stop mode?
Regards
Banu
LikeLike
Hi Banu,
WFI (Wait for Interrupt) is a simple as this:
__asm("wfi");
LikeLiked by 1 person
Hi Erich,
Thanks for quick reply.
Yes, I tried ” __asm(“wfi”);” but didn’t work, my code is simply as below, I tried to place the “__asm(“wfi”);” after and before calling the enter stop mode function, do you have any idea why?
int main(void)
{
PE_low_level_init();
unsigned int i,j;
PWM1_Enable();
for(i=0;i<5000;i++)
for(;;) {
{
enter_stop();
PWM1_Disable();
for(i=0;i<5000;i++)
PWM1_Enable();
for(i=0;i<50000;i++);
}
}
void enter_stop(void)
{
volatile unsigned int dummyread;
SMC_PMCTRL &= ~SMC_PMCTRL_STOPM_MASK; //mask=0x7u
SMC_PMCTRL |= SMC_PMCTRL_STOPM(0);
/*wait for write to complete to SMC before stopping core */
dummyread = SMC_PMCTRL;
deepsleep();
}
void deepsleep (void)
{
/* Set the SLEEPDEEP bit to enable deep sleep mode (STOP) */
SCB_SCR |= SCB_SCR_SLEEPDEEP_MASK; //0x4u
#ifdef CMSIS
__wfi();
#else
/* WFI instruction will start entry into STOP mode */
__asm("WFI");
#endif
}
LikeLike
your usage of WFI looks ok. All what you need then to continue after that instruction is to raise an interrupt (e.g. with an external pin interrupt).
LikeLike
I tired the interrupt but did not work. I enabled the interrupt after the WFI but nothing happen it enters the stop mode and stays there -_-
LikeLike
WFI does exactly what its name is: it waits and sits there until an interrupt occurs. You have to enable interrupts *before* executing wfi.
LikeLiked by 1 person
Hi Erich,
I added TimerInt components and put the interrupt period 2sec, then wrote in the events.c a wakeup_flag and modify the below code in main.c please check:
PWM1_Enable();
for(i=0;i<5000;i++)
for(;;) {
for(i=0;i<1000;i++)
enter_stop();
wake_up_int_Enable();
if (Wakeup_flag==0)
{
deepsleep();
PWM1_Disable();
for(i=0;i<5000;i++)
PWM1_Enable();
for(i=0;i<5000;i++)
}
Wakeup_flag==1;
}
I enabled the wake_up_int and then checked the wakeup_flag in events.c and then called the deepsleep function which is the same as in the above post but still has the same issue, the MCU enter the stop mode any stay there 🙁.
Regards
Banu
LikeLike
The interrupt to wake you up has to be turned on *before* you enter the stop mode.
LikeLiked by 1 person
And you should chanbe
Wakeup_flag==1;
toWakeup_flag=1;
LikeLike
Thank you for the quick reply.
I modified it as below:
/*****Main.c****/
unsigned char Wakeup_flag=0;
PWM1_Enable();
for(i=0;i<5000;i++)
for(;;) {
for(i=0;i<1000;i++)
wake_up_int_Enable();
if (Wakeup_flag==0)
{
enter_stop();
deepsleep();
PWM1_Disable();
for(i=0;i<5000;i++)
PWM1_Enable();
for(i=0;i<5000;i++)
}
Wakeup_flag=1;
}
/**********Events.c*****/
void wake_up_int_OnInterrupt(void)
{
/* Write your code here … */
Wakeup_flag=0;
LED1_On();
}
Still the same issue.
LikeLike
Pingback: FreeRTOS: how to End and Restart the Scheduler | MCU on Eclipse
@Erich,
Could you quickly explain in this comment or in a new series on LPC55S69 how one can reset the processor in both security states?
Thank you!
LikeLike
@Erich,
Could you quickly explain in this comment or in a new series on LPC55S69 how one can reset the processor in both security states?
Thank you!
Could you quickly explain in this comment or in a new series on LPC55S69 how one can reset the processor in both security states?
Thank you!
LikeLike
I have not explicitly tried, but I would have assumed it would work the same way? Are you saying it is not?
LikeLike
Thank you Erich again for the helpful tutoring. When using MCUXpresso, use NVIC_SystemReset (); as found in a file called “core_cm0plus.h”. Happy Resetting.
LikeLike
Hi Kevin,
thank you for that hint! Yes, indeed the CMSIS layer has added that NVIC_SystemReset() which can be used too.
Happy re-resetting 🙂
LikeLike