cancel
Showing results for 
Search instead for 
Did you mean: 

Core reset without peripheral reset

slal
Associate III
Posted on September 13, 2013 at 15:37

Hi forum!

I am trying to launch a soft reset of the STM32F417 core without losing peripheral state or resetting the peripheral registers. I intend to jump from one application (in flash) to another (in SRAM), for which I first remap the syscfg to place SRAM at address 0, followed by a soft reset. By using the NVIC_SystemReset( ) code from the ST stdperiph library I am able to reset the MCU, but also seem to lose the state of peripherals like USARTs etc. Is there a method to reset just the core and not the peripherals? Or is my observation flawed?

Thanks for your comments!

#firmware-update #soft-reset
8 REPLIES 8
Posted on September 13, 2013 at 15:53

Is there a method to reset just the core and not the peripherals?

No

Why not just transfer control to your RAM code with the peripherals in the state you want them?
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
slal
Associate III
Posted on September 13, 2013 at 16:08

How would that be done? The stage I'm at is that I've copied an entire new application binary into internal SRAM, and done a system remap to it. And that is where I'm stalled. One method I thought was to reserve some SRAM section to store peripheral state variables and then re-initialise to that state in the new application.

slal
Associate III
Posted on September 13, 2013 at 16:20

Are you referring to moving the interrupt vector base to the new project's location at 0x2000000 followed by jumping to that location?

Posted on September 13, 2013 at 16:36

If you had a vector table at the front, you wouldn't jump to 0x20000000, as there is no executable code there. You'd want to jump to the address of the ResetHandler code, or whatever entry point you've defined. You'd also want to set the Vector Table (SCB->VTOR) to match the basis of your code.

If you've built your code to reside at a base of 0x20000000, I'm not sure of the value of mapping RAM to zero. Also you'd want to make sure that any RAM the boot loader was using is placed high up in memory so as not to conflict or be corrupted by the code you're trying to copy there.

What's your experience level with ARM processors, and assembly code?

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
slal
Associate III
Posted on September 13, 2013 at 16:54

Thanks for the response again Clive1.

I follow your points there. I have been working with STM32 ARM cores for over a year now, but mostly using the recommended stdperiph library. At the moment I haven't looked at assembly coding in depth on ARM.

A previous product I worked on had enough external RAM for me to play around with while doing things like firmware updates. However, here I am trying to accomplish firmware update with only internal SRAM. I have read through the IAP discussions, and also tried using _ram functions. I realise I need to retain peripheral state as is between two different applications, the first in flash and the second in SRAM.
Posted on September 13, 2013 at 17:13

I'd generally recommend having a boot loader at the base of memory (0x08000000, 16KB for the STM32 F2/F4), and then never erase that. Then place the app code above that, and have the boot loader validate the app code before jumping to it. This protects you if the power fails during an update, and makes things far more robust.

You can copy and execute arbitrary code in RAM, this can be code that is part of the boot loader, or application. It could be address agnostic, or a self contained applet. It also doesn't need to be placed at 0x20000000. Other free RAM areas may be used, the only limit being that the VTOR address must be on a 512-byte boundary, and then only needed if you are using interrupts.

One of the primary issues with transferring control to RAM code, and erasing the FLASH, is if you have assorted interrupts running which will now fail, or if you attempt to return to a subroutine that has been erased/replaced. Or if the code you copied tries to call subroutines/library function which still reside in FLASH.

So basically, you want to copy your code to RAM, and jump to it never expecting to return, and in a state that both sides agree upon. You can define those condition, and should document them so someone looking at the two projects understands the contract between the pieces of code.
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
slal
Associate III
Posted on September 13, 2013 at 17:29

I follow that Clive1. The issue is, even during firmware update, I want to have full communication with the outside world. Actually, the new firmware is being passed to me over USART in chunks of random size. The RAM project aims to maintain all the communication exchange intact, while mass erasing the flash and then reprogramming it on the go.

Regarding your suggestion, I understand that it would be more robust to have a bootloader. However, I would still have to run from RAM while programming new firmware into flash. The reason I want an entire second application in RAM is to be able to continue communication with other devices as normal - which means moving the vector table and vectors/ISRs to RAM too - because there are two communication channels that need to be active during firmware update.
slal
Associate III
Posted on September 16, 2013 at 15:41

Meanwhile, I've managed to get the second application in RAM working. It turns out I was incorrectly using the NVIC_SetVectorTable( ) by passing it the SRAM base address instead an of offset value. Apart from that, setting the MSP to SRAM base address and jumping to SRAM_BASE_ADDR + 4 launches the RAM application with all peripheral registers intact. I also do a memory remap, although I'm not sure that is needed..

Any comments on this method?

Thanks!