Can anyone tell me if it's possible to do a hard-reset out to the bootloader from inside a program? I've tried 3 ideas:
using an I/O pin to pulse the Reset line.
triggering the watchdog timer.
trying to set the program counter = 0x000 .
The first works successfully, the 2nd just restarts the sketch as I expected, and the 3rd appears to do likewise. Written as follows:
digitalWrite(7, LOW); // pin 7 configured as output, hardwired to Reset pin.
// watchdogConfig(WATCHDOG_1S); // code pulled from optiboot.c
// asm volatile("jmp 0x000\n\t"); // tried different forms of this line.
discussed often, does not reset everything. IIRC timers might continue and interrupts may not have been reset. You should be able to find threads on the forum discussing the details. (or dive into the 328 manual.)
Ummm, I want to do a hard reset out into the boot loader. From what I could tell, the watchdog reset appears to just restart the sketch, not the boot loader. IE, no 3 Led bootup blinks like I get with method 1. I've been looking at the 328 d/s, but I'm confused - obviously.
A watchdog reset resets the AVR and all its internal registers
(well all of them except the MCUSR).
Keep in mind that none of the other hardware that may be attached to the AVR or the board
is reset.
If there is a bootloader, it will start running, and depending on if the bootloader
looks at the MCUSR register to see what type of reset occured,
it may not do the same thing depending on what caused the reset:
power on
brown out
external (reset pin)
watch dog
Have you created a custom bootloader?
If not, the default bootloader that comes with the boards,
restarts the application code which is the sketch.
Many of the bootloaders, including the optiboot bootloader do look at the MCUSR
as a way to get the sketch up and running quicker under certain reset conditions.
The optiboot bootloader will immediately jump to the sketch
if the reset was not due to the reset signal line/pin.
So for example, when using the optiboot bootloader:
A power-on, brownout, or watchdog reset will start the bootloader code,
but the bootloader code will immediately restart the sketch without
checking for a new download.
A hardware reset on the AVR reset pin,
will start the bootlaoder code (usually blink the LED)
and then will look for a download on the serial port
for a short period of time before starting the sketch.
Thanks, I am using standard 328 optiboot, and trying to get into the bootloader "forever loop" from within my sketch. Equivalent of a hard reset.
I think I am starting to get the idea now - looking at the optiboot source ...
/* main program starts here */
int main(void) {
............
// After the zero init loop, this is the first code to run.
//
// This code makes the following assumptions:
// No interrupts will execute
// SP points to RAMEND
// r1 contains zero
//
// If not, uncomment the following instructions:
// cli();
asm volatile ("clr __zero_reg__");
// Adaboot no-wait mod
ch = MCUSR;
MCUSR = 0;
if (!(ch & _BV(EXTRF))) appStart();
........
#if LED_START_FLASHES > 0
/* Flash onboard LED to signal entering of bootloader */
flash_led(LED_START_FLASHES * 2);
#endif
/* Forever loop */
for (;;) {
.....
... the adaboot no-wait mod causes the bootloader to restart the app in case of a "soft" reset, such as a watchdog trip. You only pass through to the 3 flashes [which is where I want to go] if there is a pulse on the external Reset line.
oric_dan:
I don't quite understand what this does, however,
asm volatile ("clr __zero_reg__");
The bootloader is linked wouthout the normal C runtime startup code.
The compiler expects that code to be included.
One important thing the C startup code does is put a value of 0 into a register reserved for this purpose.
The compiler generates code assuming that reserverd register has a zero in it for comparison and test puposes.
That line puts the zero into the register that is reserved for that purpose.
What do you mean by this:
Thanks, I am using standard 328 optiboot, and trying to get into the bootloader "forever loop" from within my sketch. Equivalent of a hard reset.
What do you mean by "forever loop".
If all you want to do is reset the AVR and restart your sketch, then use the watchdog timer.
Attached is a sketch that has a routine that shows how to do this.
The beginning of the "forever loop" is shown at the bottom of the code I posted above ... right after the Led flashes.
THAT is where I want to get to, starting from inside my runnning sketch. I want to get into the guts of the bootloader, not simply restart my sketch. [this is related to a wireless programming project, where the sketch will trap out an RS232 serial character sequence, and then jump into the bootloader].
I see now that I can simply remove the adaboot mod, trigger a watchdog reset, and it's done. Thanks for the help, to both of you.
Ah, you aren't really want to get to the bootloader, you want to get to the downloader loop
inside the bootloader.
If this is for you own boards, and you are not using the watchdog timer,
I'd go modify the bootloader code to not do the fast sketch start at least not for the watchdog
and rebuild the bootloader.
That way all you need to do is a watchdog reset and it will fall into the downloader loop.
Keep in mind that the "forever" loop really isn't forever.
The watchdog timer breaks out of it to start the sketch.
Depending on your needs, you also may want to extend the downloader wait loop timeout
as currently it is only 1 second. You may want/need a longer timeout.
Thanks, I've looked into the issue of watchdog timeout length before auto-appstart.
I tracked down the relevant parts in the avrdude sourcecode related to uploads, and especially sync'ing with the bootloader. 1-sec watchdog timeout is actually marginally short, as the avrdude sync-up routine is really not very robust. One sync-up check only, and if it fails, unfortunately avrdude bails. There should be 6 checks before bailing.
If you want the sketch to trigger a hard reset via an I/O line then you'll need an external circuit to extend the pulse. That could be a capacitor circuit, or using a hardware timer.