Ardunio 328p bootloader main loop and reset questions

Hello,

I am trying to understand the bootloader process better, so I have been fooling around with the optiboot bootloader. I load the bootloader using the avrdude. I have been using the soft serial on dig pins 2 & 3 to see what is going on in the main loop. I removed everything from the main loop except for below. After the bootloader is loaded, I reset the board, by disconnecting and reconnecting the usb cord. When the board restarts the bootloader loops through the main function a 8-16 times in short succession, then loops at a slower interval. Where does this sequence come from? Are the later intervals the watchdog timer timing out? Where is this set at? Am I not stopping the watchdog?

Another question I have, is it possible to get a condition, where the watchdog reset and an external reset are both true? What would cause such a condition?

Any help you can provide on these questions would be appreciated.

Thanks,

-ren

int main(void) {
uint8_t ch;
#ifdef SOFT_UART
/* Set TX pin as output */
UART_DDR |= _BV(UART_TX_BIT);
#endif

/* here we learn how we were reset */
reset_reason = MCUSR;
reset_time = WDTCSR;
MCUSR = 0;

/* stop watchdog */
WDTCSR |= _BV(WDCE) | _BV(WDE);
WDTCSR = 0;

softUartSendString("hello");

}

When the board restarts the bootloader loops through the main function a 8-16 times in short succession, then loops at a slower interval.

Are you saying the code in your post is behaving that way?

/* stop watchdog */
   WDTCSR |= _BV(WDCE) | _BV(WDE);

I think that needs to be just an "=" rather than an "|="
This is the "magic" "I'm going to change the WD config" value, and if WDTCSR had any value other than 0 before you run it the value won't be right.

is it possible to get a condition, where the watchdog reset and an external reset are both true?

I don't think so.

Do you ever turn the watchdog on?

You don't have any code at the end of main() to stop the AVR. Depending on compile switches and fuse settings, that means that main with return, and go off and do SOMETHING. Perhaps run off into random memory. Perhaps restart. Perhaps spin loop until reset by watchdog or some other mechanism.

The way optiboot works is that any reset condition OTHER than an "external reset" causes the bootloader to turn off the watchdog and start the app immediately. Otherwise the watchdog is turned ON and the bootloader starts looking for commands. If no commands are found by the time the watchdog triggers, the WD resets the CPU, that's a reason other than external reset, and the app starts...

CodingBadly,

Yes, that code is producing the aforementioned sequence.

westfw,

You know I went back to the original optiboot code I have and couldn't find that WDTCSR coding, I think I lifted from another bootloader. I will take a look into that line.

No, I never turn on the watchdog. I would just expect the main loop to keep looping once it completes. The first 8-16 loops execute immediately. However, after that it executes every +5 seconds. Which has got me confused. Maybe it is set in the fuses?

Thanks for your replies!

-ren

westfw,

Brownout is the only other reset other than external and watchdog, correct? Brownout is only valid when you have that set as a condition in the fuses, correct?

Thanks,

-ren

You need to reread westfw's reply.

int main(void)
{
// snip

softUartSendString("hello");

// When you return from main on an AVR processor, what runs next? There's no operating system so that does not get control.
}

Coding Badly,

OK, if I update with a return of 0(see below), control will go back to operating system. Will the main function loop? I am curious as to what the differences would be between returning 0, returning 1, and using a watchdog reset.

-ren

int main(void) {
uint8_t ch;
#ifdef SOFT_UART
/* Set TX pin as output */
UART_DDR |= _BV(UART_TX_BIT);
#endif

/* here we learn how we were reset */
reset_reason = MCUSR;
reset_time = WDTCSR;
MCUSR = 0;

/* stop watchdog */
WDTCSR |= _BV(WDCE) | _BV(WDE);
WDTCSR = 0;

softUartSendString("hello");

return 0;
}

I guess I'll have to spell it out...

control will go back to operating system

There is no operating system. Do not return from main. A bootloader (like Optiboot) jumps to the application code at the end.

Exactly what happens will depend on the compiler/linker switches. The existing optiboot makefiles in particular will cause the program to behave differently than an Arduino sketch compiled from the IDE.

As others have said, there is no operating system.

This is (maybe?) one of the reasons that an Arduino sketch has setup() and loop() instead of a main(); it helps emphasize one of the ways that a microcontroller program is different from a desktop program that does run under an operating system...