Soft reset by jumping to main()

Go To Last Post
4 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So here is an interesting problem. I have an application using and XMEGA series chip and I need to be able to do a reset in the event of failure. Normally a perfect case for the WDT, right? Well there is a hiccup in my case: the real time counter. I need it to keep running at all times, and I need to retain the value across resets. There are also a few other values that I would like to save. To complicate matters further, I am using a boot loader, which the reset vector points to, so "jmp 0000" doesn't work (at least not for debugging since the boot loader isn't present yet). Long story short, I need to do a very soft reset.

The solution I came up with was to use a timer on the highest interrupt level (the XMEGA series has 3 levels) that would clear out several likely error sources (TWI, ADC, etc.), reset a few specific variables, shut down attached hardware, then jump. Basically a soft WDT, including a reset function that clears the timers counter.

With all of that out of the way, here's my actual question. The solution I came up with for the jump was to create a function pointer to main and jump to that. That way it would re-init my hardware without losing everything then re-start my state machine loop. What are the pitfalls of this? What problems could be caused by jumping just to main()? I still have the actual WDT on it's longest period in case of catastrophic failure, and I write the RTC values to the eeprom just in case, but this seemed like an easy solution for my soft reset. Am I wrong?

Thanks.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

1) No matter what you do, you aren't goning to be able to prevent losing "ticks" in the case of any/all events. You have power loss, brown out, external reset to start. Your "event of failure" could include your timekeeping mechanism.

2) The recovery becomes so elaborate that the effort may well dwarf the app development itself.

3) If you want a RTC, then use an RTC. (IMO) Or have a way to re-sync/re-set the RTC in the case of restart.

4) Use WDT to do a clean restart in the event of "failure".

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If it is only a few locations that you want to preserve, just remove them from the initialisation section.

avr-gcc has a specific "no_init" section, but there should be no problem adjusting the "crts0.s" or "startup.asm" for any other compiler.

Then you can let the watchdog do its thing with the general proviso that you will miss a few ticks in the process.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

well, you should jump to a place in main and not main.

in main the first thing you do is initialize. after that the app starts. Having said that you want to skip the initialisation part, so jump to the application part.
but I agree with bob if your timekeeping is so critical go for an external RTC. then you can always do a full restart of the chip. because you don;t know what was the reason for the reset. it might as well have been the rtc code itself.....