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;
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...
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?
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?
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;
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...