Infinite watchdog reset loop with Pro Mini and ATmegaBOOT bootloader

Hi all,

The following sketch when uploaded to my pro mini 3.3V enters an infinite watchdog reset loop (red led flashing continuously).

I have seen a couple posts suggesting that this may be due to bad handling of the watchdog registers by the ATmegaBOOT_168_atmega328_pro_8MHz bootloader... but before I try to replace that bootloader which has been working fine in all other aspects I would like to make sure that I am using the wdt library correctly:

#include <Arduino.h>
#include <avr/wdt.h>

void setup()
{
  MCUSR = 0;
  wdt_disable();

  wdt_enable(WDTO_2S);
}

void loop()
{
  if (millis() % 5 == 0) {
    while (1) {}
  }
  wdt_reset();
}

The suggestions I have seen are:

  1. burn the optiboot bootloader: the concern I have with that is that I want to run the board at 1MHz, and I see in boards.txt that the upload speed is set to 115200: if I pick a slower speed before burning the optiboot bootloader will it remember it once installed? Or is the upload speed hardcoded in the bootloader, and the setting only used when I click "Upload sketch"?

  2. I have seen other suggestions to move the wdt_disable() into .init0 or .init3 sections... however there are a few flavors and it isn't completely clear that it solves the problem.

Here is my boards.txt entry:

## Door Sensor, based on Pro Mini 3.3V
## ------------------------------------------------

pro.menu.cpu.1MHzatmega328=Door Sensor - ATmega328 (1.8V, 1 MHz)

pro.menu.cpu.1MHzatmega328.upload.maximum_size=30720
pro.menu.cpu.1MHzatmega328.upload.maximum_data_size=2048
pro.menu.cpu.1MHzatmega328.upload.speed=7200

## 1MHz and brown out disabled
pro.menu.cpu.1MHzatmega328.bootloader.low_fuses=0x62
pro.menu.cpu.1MHzatmega328.bootloader.high_fuses=0xDA
pro.menu.cpu.1MHzatmega328.bootloader.extended_fuses=0xFF
pro.menu.cpu.1MHzatmega328.bootloader.file=atmega/ATmegaBOOT_168_atmega328_pro_8MHz.hex

pro.menu.cpu.1MHzatmega328.build.mcu=atmega328p
pro.menu.cpu.1MHzatmega328.build.f_cpu=1000000L

I'd really like to have watchdog enabled on my sensors, any suggestion welcome... thanks!
Franck

Yeah, this is well known.

The pro mini bootloader is kinda crap. I would recommend bootloading it with the version of optiboot that comes with MiniCore - GitHub - MCUdude/MiniCore: Arduino hardware package for ATmega8, ATmega48, ATmega88, ATmega168, ATmega328 and ATmega328PB Gives you more space, uploads faster, and fixes the watchdog bug.

DrAzzy:
Yeah, this is well known.

The pro mini bootloader is kinda crap. I would recommend bootloading it with the version of optiboot that comes with MiniCore - GitHub - MCUdude/MiniCore: Arduino hardware package for ATmega8, ATmega48, ATmega88, ATmega168, ATmega328 and ATmega328PB Gives you more space, uploads faster, and fixes the watchdog bug.

Thanks!
I went ahead and installed optiboot. The watchdog problem is fixed indeed.

I now have failures uploading through FTDI though, which I never had before. I have to randomly press or hold the reset button on the mini to get avrdude to start uploading at attempt 4 or 5.

This is my new boards.txt, did I miss something? Should I try a standard 4800 baud rate?

pro.menu.cpu.1MHzatmega328=Door Sensor - ATmega328 (1.8V, 1 MHz)

#pro.menu.cpu.1MHzatmega328.upload.maximum_size=30720
pro.menu.cpu.1MHzatmega328.upload.maximum_size=32256
pro.menu.cpu.1MHzatmega328.upload.maximum_data_size=2048
pro.menu.cpu.1MHzatmega328.upload.speed=7200

pro.menu.cpu.1MHzatmega328.bootloader.low_fuses=0x62
pro.menu.cpu.1MHzatmega328.bootloader.high_fuses=0xDA
pro.menu.cpu.1MHzatmega328.bootloader.extended_fuses=0xFF
#pro.menu.cpu.1MHzatmega328.bootloader.file=atmega/ATmegaBOOT_168_atmega328_pro_8MHz.hex
pro.menu.cpu.1MHzatmega328.bootloader.file=optiboot/optiboot_atmega328.hex
pro.menu.cpu.1MHzatmega328.build.mcu=atmega328p
pro.menu.cpu.1MHzatmega328.build.f_cpu=1000000L

FTDI uploads definitely don't work for me with the optiboot (I changed the high fuse to 0xDE after my previous post).

What is worse is that I have burned the original ATmegaBoot bootloader back, using the same process as the first time, and FTID uploads don't work there anymore :frowning:

The fuses haven't changed, so I'm a bit lost as to what the problem could be... here is the complete avrdude output

[EDIT]: The old bootloader works fine after I changed back the baud rate from 9600 to 7200.

So I can't get Optiboot to work; I tried 4800, 7200 and 9600 for the baud rates. And I had low_fuses=0x62, high_fuses=0xDA and extended_fuses=0xFF.

When trying to upload I can see the red led blinking slowly 3 times, so I am pretty sure that the bootloader code is running - however it seems that it isn't able to sync with avrdude.

Just as a sanity check, install MiniCore to see if that bootloader and board definition will work. If that works then you can compare your non-working optiboot configuration to the known-good optiboot configuration.

I haven't tried the minicore yet, but the optiboot works perfectly if I use 8MHz as a clock speed.

Also, the led flashes 3 times about 10 times as fast at 8MHz, so I think my problem comes from the fact that at 1MHz, the uploaded bootloader code was compiled for 8MHz.

My boards.txt does have those entries (I installed the latest 6.2 optiboot boards manager):

optiboot32.menu.mhz.8MHz.build.f_cpu=8000000L
...
optiboot32.menu.mhz.1MHz.build.f_cpu=1000000L

so I am not too sure what could cause the bootloader code to think that it is running at 8MHz when the clock is in fact set to 1MHz?

Franck

According to this thread Bootloader for Atmega328p with 1 MHz and internal Osc. for Battery use - Microcontrollers - Arduino Forum I may need to build a different optiboot hex file for 1MHz? If that is the case why is the 1MHz option supported in the ootb boards.txt?

I have tried the suggestion to program at 8MHz and switch to 1MHz in my sketch at runtime using

  CLKPR = (1 << CLKPCE);
  CLKPR = B00000011;

This works, although I had to create a weird board with the 8MHz upload speed and the 1MHz f_cpu setting for the sketch to run at the correct speed:

optiboot32.menu.mhz.1MHz=1MHz (int)
optiboot32.menu.mhz.1MHz.build.f_cpu=1000000L
optiboot32.menu.mhz.1MHz.bootloader.low_fuses=0x62
optiboot32.menu.mhz.1MHz.upload.speed=57600

It makes be a bit nervous to have the sketch adjust the clock at runtime... but for now this seems to resolve my watchdog problem :slight_smile:

Franck

franck102:
If that is the case why is the 1MHz option supported in the ootb boards.txt?

I'm not familiar with an "ootb boards.txt". You'd need to post a link to where you found this file.

Why are you so resistant to trying MiniCore? It's very well done and easy to install. If for some reason you don't want to continue using it after verifying that it works you can use it as a reference for how to fix the errors in the custom hardware package you put together for your board.

pert:
I'm not familiar with an "ootb boards.txt". You'd need to post a link to where you found this file.

Why are you so resistant to trying MiniCore? It's very well done and easy to install. If for some reason you don't want to continue using it after verifying that it works you can use it as a reference for how to fix the errors in the custom hardware package you put together for your board.

Sorry, ootb stands for out of the box. I obtained the file by installing the latest (6.2) optiboot as described here:

I have nothing against OmniCore, but as I suspected Optiboot was not the issue and I wanted to really understand the issue before adding more moving parts to the mix.

I will give omnicore a try to see if it allows me to set the fuse to 1MHz without having to recompile the bootloader myself. Optiboot seems to require that and I'd rather not go there.

Thanks, Franck

Ok, I would expect the files from the Optiboot/optiboot repository to work but MiniCore definitely is a lot more actively maintained. The Optiboot/optiboot repository is mostly focused on the bootloader source code itself, the boards definitions are somewhat just added in as an afterthought. MiniCore uses Optiboot, it's just a slightly modified version that allows you to write to flash from the application but other than that should work exactly as the bootloaders from the Optiboot/optiboot repository. The bootloaders have already been compiled with MiniCore so it's pretty much just install and go and we made the installation process really easy via Boards Manager so it should only take a few minutes to do a quick test. If it works you can just grab the bootloader file from MiniCore to use as you like.

Here's the thing about bootloaders and clock speed. The bootloader receives the data over serial and writes it to flash. That serial communication must be done at a known baud rate. So that's why it's important for the bootloader to know the clock speed of the microcontroller as the baud rate is dependent on that. So in the makefile used to compile a bootloader you can set the clock speed to compile a bootloader specifically for the configuration of your board. That's great but if you're trying to support a bunch of different clock speeds, as MiniCore and the optiboot boards definitions do, that can mean having a lot of bootloader files. There is a trick that allows you to use the same bootloader file for multiple clock speeds. Let's say you have a bootloader that is compiled to communicate at 115200 baud an expects the microcontroller to be running at 16 MHz. Now if you run that bootloader on a microcontroller running at 8 MHz the bootloader actually ends up trying to communicate at 57600 instead of 115200 because the clock is half the expected speed. If the computer is sending the data at 115200 that will never work. So the trick is to change the upload.speed in boards.txt to 57600. That way even though the bootloader is communicating at half the expected baud rate it works fine because you have told the computer to also communicate at 57600. You can use the same trick for other clock rates, by just adjusting upload.speed value accordingly. This does mean that the upload is slower but it's not a huge difference with the small programs that are usually uploaded to an AVR.

Great explanation, thanks!

Couldn't the bootloader code read the CLKPR register and adjust its baud rate based on the prescaler setting?

Franck

MiniCore worked flawlessly at the first attempt, with 328p / BOD disabled / 1MHz... nice work and thanks for the suggestion!

Franck