Author Topic: Are there too many different bootloaders in the Arduino world?  (Read 7643 times)

0 Members and 1 Guest are viewing this topic.

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4199
  • Country: us
Re: Are there too many different bootloaders in the Arduino world?
« Reply #50 on: February 27, 2023, 06:56:38 am »


Quote
how to read from “special” AVR data storage locations


You might be entertained by looking at the undocumented fuse memory locations as well.  Rumor has it that they might contain additional info similar to the "unique identifier" fields that are documented in some of the later devices (XMega, 328pb)...
https://www.avrfreaks.net/s/topic/a5C3l000000UTRvEAO/t126997

PS:
Quote
I’m adding them as I go.
excellent!  I always hope when I write those little "examples", that people will be able to use them as examples and expand upon them as needed.  Sadly, that doesn't happen that often in the Arduino world; too many users are ... well, USERS...

Consider submitting a pull request, diffs, or your updated version...

« Last Edit: February 27, 2023, 07:25:03 am by westfw »
 
The following users thanked this post: elecdonia

Offline elecdoniaTopic starter

  • Frequent Contributor
  • **
  • Posts: 399
  • Country: us
Re: Are there too many different bootloaders in the Arduino world?
« Reply #51 on: February 28, 2023, 07:03:12 pm »
Question:
I'm testing an ATmega88. It doesn't support reading its device signature from application flash. This is because of a hardware difference: The mega88 doesn't have a "SIGRD" bit in the in its SPMCSR register.

Therefore apps like FuseBytes are incapable of reading the mega88 signature.

However, when I connect AVRDUDE to a mega88 equipped with optiboot through a serial-TTL converter, AVRDUDE is able to obtain the correct device signature. Is this black magic  ???  or clever coding?  8)

I read somewhere that optiboot "hard codes" the device signature rather than actually reading it from the target device.

I may have confirmed this: I looked at binary dumps of optiboot 7.0 hex files for mega88, mega168, mega328, and their -p and -pb cousins, I discovered different values at offsets 0x15E and 0x162. It appears that the low-order 4 bits of each location are used to encode single hex digits of appropriate signature data. (This seems efficient: no wasted space at all. Just the bare minimum amount of data)

This makes me curious about several things:
     Why was it necessary to embed the device signature into optiboot?
     Is the device signature hard-coded into all optiboot binaries, or do some of them actually read the signature from the target AVR?
     How does optiboot deliver this signature information in proper STK500 format to AVRDUDE?
     I looked at boot.h and optiboot_flash.c but I don't understand how this works yet.

I must say I'm impressed that optiboot works with such a large family of different AVR devices, old and new. The effort put forth to get all of these devices working with optiboot must have been considerable. Three cheers!  :clap:
I’m learning to be a leading-edge designer of trailing-edge technology.
 

Offline elecdoniaTopic starter

  • Frequent Contributor
  • **
  • Posts: 399
  • Country: us
Re: Are there too many different bootloaders in the Arduino world?
« Reply #52 on: February 28, 2023, 07:19:57 pm »
I discovered some ATmega48 devices in my IC chip archives. Mfg date is 2005.

I was disappointed that MiniCore says: "no bootloader" for the mega48. Then when I read the Atmel datasheet I realized the mega48 doesn't have a dedicated boot area or a fuse bit to vector a reset to the boot section. Perhaps bootloaders don't exist for such small devices? Why would they be needed anyway?

Otherwise, MiniCore does a nice job of supporting the ATmega48 in the Arduino IDE. One just needs to remember to use "upload sketch through programmer."
I installed and ran the plain old "blink" sketch, although at first it ran waaaaaayyy   tooooooo slowwwwwww.
That's because I didn't realize the Arduino IDE "burn bootloader" procedure must be used to configure the ATmega48 fuses.
   After all, why should one perform the "burn bootloader" procedure when a bootloader for this device doesn't even exist?

After running "burn bootloader" with proper clock frequency parameters everything works great. The LED blinks once per second at 16, 8, or 1MHz. The original "very slow" blinking was because all AVR devices come from the factory configured for 1MHz internal clock.

Now I'm looking for interesting sketches which will fit into 4K of flash...

I’m learning to be a leading-edge designer of trailing-edge technology.
 
The following users thanked this post: tooki, Nominal Animal

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4199
  • Country: us
Re: Are there too many different bootloaders in the Arduino world?
« Reply #53 on: February 28, 2023, 11:15:35 pm »
Quote
I'm testing an ATmega88. It doesn't support reading its device signature from application flash. This is because of a hardware difference: The mega88 doesn't have a "SIGRD" bit in the in its SPMCSR register.
Wow.  Is in an actual ATmega88, rather than an ATmega88A, ATmega88P, or ATmega88PA?What happens if you compile with one of those other processor types specified, or simply define SIGRD as 5?
Quote
     Why was it necessary to embed the device signature into optiboot?
I believe the original reasoning was that it saves space.  Load a value into a register and send it, vs load a code into SPMCSR, load an address into X, do the SPM instruction, and send it.
With the 328 vs 328P fiasco, it became useful for the bootloader to "lie" to avrdude/ArduinoIDE.
Quote
     Is the device signature hard-coded into all optiboot binaries, or do some of them actually read the signature from the target AVR?
It's hard-coded into all of them.  Maybe not optiboot-X.
Quote
     How does optiboot deliver this signature information in proper STK500 format to AVRDUDE?
It detects when avrdude does a "signature read" command , and sends the bytes.  There isn't much to "stk500v1"
Code: [Select]
/* Get device signature bytes  */
    else if (ch == STK_READ_SIGN) {
      // READ SIGN - return what Avrdude wants to hear
      verifySpace();
      putch(SIGNATURE_0);
      putch(SIGNATURE_1);
      putch(SIGNATURE_2);
    }
This assembles to "LDI r24, 0xNN" followed by "RCALL putch"; probably the reason that you see nybbles rather than full byte values in the hex dump is that the AVR instruction set encoding for LDI is a bit weird:1727504-0
Quote
The effort put forth to get all of these devices working with optiboot must have been considerable.
Well, it's been a lot of years, and a lot of people helped.  Sometimes I feel like my main function as "optiboot maintainer" has been to hold back new features, rather than add them.  (after all, Arduino itself is doing fine with optiboot source that supports far fewer parts.)


 

Offline elecdoniaTopic starter

  • Frequent Contributor
  • **
  • Posts: 399
  • Country: us
Re: Are there too many different bootloaders in the Arduino world?
« Reply #54 on: March 01, 2023, 05:55:33 pm »
Wow.  Is it an actual ATmega88?
Yes it is. I have a big stash of AVR devices with mfg. dates as far back as 2001. The "V" suffix on the chip's label indicates this is the "low-voltage" version of the ATmega88.
Quote
What happens if you compile with one of those other processor types specified, or simply define SIGRD as 5?
Defining SIGRD in the FuseBytes sketch allows the sketch to compile and load. However, the data returned by boot_signature_byte_get(x) isn't the signature data. I'll attempt to identify where the returned data actually comes from. Also I intend to search the sources for the AVR core and system libraries to learn where these obscure system function names like "boot_signature_byte_get(x)" are defined.
Quote
It detects when avrdude does a "signature read" command , and sends the bytes.  There isn't much to "stk500v1"
Code: [Select]
/* Get device signature bytes  */
    else if (ch == STK_READ_SIGN) {
      // READ SIGN - return what Avrdude wants to hear
      verifySpace();
      putch(SIGNATURE_0);
      putch(SIGNATURE_1);
      putch(SIGNATURE_2);
    }
This assembles to "LDI r24, 0xNN" followed by "RCALL putch"; probably the reason that you see nibbles rather than full byte values in the hex dump is that the AVR instruction set encoding for LDI is a bit weird.
So where are the specific argument values for "SIGNATURE_x" defined?
For the ATmega88 these values are 0x1E 0x93 0x0A.
I'll try searching the src, make, boot.h files, etc. for symbols containing "SIGNATURE"
I’m learning to be a leading-edge designer of trailing-edge technology.
 

Offline elecdoniaTopic starter

  • Frequent Contributor
  • **
  • Posts: 399
  • Country: us
Re: Are there too many different bootloaders in the Arduino world?
« Reply #55 on: March 01, 2023, 06:26:20 pm »
Quote
This assembles compiles to "LDI r24, 0xNN" followed by "RCALL putch"; probably the reason that you see nibbles rather than full byte values in the hex dump is that the AVR instruction set encoding for LDI is a bit weird:
The second byte of the mega88 signature is 0x93.    LDI r24, 0x93 assembles into the following 16 bits of raw machine code: 0xE983

That is odd! :-//

The LDI instruction copies an 8-bit constant from flash into a register. This part is simple.
I wonder why they separated the argument (an 8-bit constant) into two nibbles with the 4 bits for the destination register located in the middle?
Perhaps this allows the LDI instruction to execute in fewer clock cycles?
Internal MCU hardware logic design is a specialty of which I know very little.

But then there is this person who scratch-built a functional CPU where the logical functions are performed by relays:
(Note that memory and IO are constructed with logic chips. Only the actual "processor" section is made from relays)

I’m learning to be a leading-edge designer of trailing-edge technology.
 

Offline elecdoniaTopic starter

  • Frequent Contributor
  • **
  • Posts: 399
  • Country: us
Re: Are there too many different bootloaders in the Arduino world?
« Reply #56 on: March 02, 2023, 03:24:20 am »
Quote
The second byte of the mega88 signature is 0x93.
LDI r24, 0x93 assembles into the following 16 bits of raw machine code: 0xE983
One related point:

In flash memory AVR device 16-bit opcodes are arranged in “little endian” fashion.
Therefore a “byte by byte” sequential flash memory dump displays the 0xE983 op code as:

0x83E9
« Last Edit: March 03, 2023, 02:37:34 am by elecdonia »
I’m learning to be a leading-edge designer of trailing-edge technology.
 

Offline fastbike

  • Contributor
  • Posts: 21
  • Country: nz
Re: Are there too many different bootloaders in the Arduino world?
« Reply #57 on: March 02, 2023, 05:09:06 pm »
My end products will likely contain “bare metal” AVR devices, but I’m not starting out that way.

Then your project will not have an Arduino bootloader and you will have to re-do all your Arduino work. If you want to go bare metal, start bare metal. This will save you lots of time and effort.
That's not the reality of using Arduino. I successfully use it to target ARM0 devices without a bootloader.
 

Offline elecdoniaTopic starter

  • Frequent Contributor
  • **
  • Posts: 399
  • Country: us
Re: Are there too many different bootloaders in the Arduino world?
« Reply #58 on: March 07, 2023, 12:26:44 am »
Quote
Next I run this “FuseBytes” sketch to double-check that all the fuses are exactly the way I want
I don't think "FuseBytes" handles all the different chips you are using.
This is correct. I'm adding all the AVR parts I have on hand and will additionally add other popular AVR chips.

I'm learning a great deal from reviewing the Atmel/Microchip datasheets. Some AVR parts have 16 different clock options:
    External or internal clock source
    RC oscillator (usually internal to the MCU chip, but some AVR devices support placing the R and C on the PC board)
    A configuration expressly for using tiny 32kHz cylindrical watch crystals
    Ceramic resonator or quartz crystal
    "Full-swing" or "Low-power" oscillator modes for quartz crystal or ceramic resonator
    Several different frequency ranges for the “Low-power” oscillator mode: 0.4-0.9MHz, 1-3MHz, 3-8MHz, 8-16MHz. The “Low-power” oscillator mode consumes even less power when a lower frequency range is selected. I intend to compare 3-8MHz to 8-16MHz while using an 8MHz crystal or resonator.

The official docs are rather complex (to say the least).

Several options are recommended only when using a ceramic resonator.
 
The reason for this is that actual quartz crystals stabilize very slowly after power-up. Their "Q" is so high that it requires 16,000 up to 32,000 clock cycles after power-up before the clock signal builds up to the proper amplitude and becomes fully stable.

Ceramic resonators have lower "Q" and achieve the proper amplitude and stability about 10 times faster than quartz crystals. This makes ceramic resonators preferable for applications which must start up very quickly after power-up.

RC oscillators are the fastest of all in terms of "start-up" times.

The fuse settings settings seen in Arduino "boards.txt" files generally use the slowest start-up settings.
 
« Last Edit: March 26, 2023, 03:13:22 pm by elecdonia »
I’m learning to be a leading-edge designer of trailing-edge technology.
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4199
  • Country: us
Re: Are there too many different bootloaders in the Arduino world?
« Reply #59 on: March 07, 2023, 06:56:30 am »

Quote
Several AVR parts have as many as 16 different clock options
I count 4 bits of "oscillator type", 2 bits of "Start up time", plus the ClkDiv8 fuse, the prescaler register, and the OSCCAL register for adjusting the internal oscillator.  (8MHz is "nominal", but you could adjust it to something more appropriate for your actual application if you want. (8MHz isn't particularly great for standard baud rates, for instance.)

Quote
[/size]actual [/size]quartz crystals[/size] stabilize very slowly
Sometimes I wonder how important that "stabilization" is.  Presumably any oscillation is fine up until you need something that is actually speed critical, and you could do your own stabilization timing in software.  OTOH, it seems to be pretty rare to require startup less than the ~70ms of the default Arduino settings.  Might be important for extreme low-power applications, since it applies to wakeup from sleep modes as well, and 65ms waiting for the crystal to be "stable" seems like quite a waste.


The newer AVRs (mega0, "xtiny", AVR-D*) let you switch clock configurations from software...



 

Offline elecdoniaTopic starter

  • Frequent Contributor
  • **
  • Posts: 399
  • Country: us
Re: Are there too many different bootloaders in the Arduino world?
« Reply #60 on: March 07, 2023, 06:41:44 pm »
I count 4 bits of "oscillator type", 2 bits of "Start up time"
"Oscillator type" (4 bits) and "startup time" (2 bits) both influence how much time the AVR device requires to begin functioning after applying power.
Additionally "oscillator type" specifies the amplitude of oscillation for ceramic resonators and quartz crystals. The amount of power consumed by the clock oscillator itself is important for extreme "pico-power" applications. Therefore adjustable clock oscillator amplitude is a useful feature.
  • "Oscillator type" specifies how many clock cycles must occur between "power-up" and "normal operation." This also applies after exiting the "power save" state. Typical values are 258, 1k, or 16k clock cycles. Example: 16k clock cycles with 8MHz clock is 2msec.
  • Data in the 2 bits of "startup time" specifies the additional delay which occurs after any form of "reset," with typical values of "14 clock cycles +  0, 4.1, or 65msec."
Quote
8MHz is "nominal", but you could adjust it to something more appropriate for your actual application if you want. (8MHz isn't particularly great for standard baud rates, for instance.)
A majority of mass-produced Arduino-compatible boards with AVR MCU operate at 16 MHz. The actual "frequency determining device" is either a ceramic resonator or a quartz crystal.

I frequently use the "8MHz calibrated internal RC oscillator" in my projects. 8MHz provides a perfect 38.4k baud rate. It isn't terrible at 57.6k either. Unfortunately it is very much "out-of-spec" at 115.2k baud. I use 38.4k baud for my 8MHz projects. So far I've always obtained error-free 38.4k baud serial communication without readjusting the factory-default oscillator calibration.

Quote
Sometimes I wonder how important that "stabilization" is.  Presumably any oscillation is fine up until you need something that is actually speed critical, and you could do your own stabilization timing in software.  OTOH, it seems to be pretty rare to require startup less than the ~70ms of the default Arduino settings.  Might be important for extreme low-power applications, since it applies to wakeup from sleep modes as well, and 65ms waiting for the crystal to be "stable" seems like quite a waste.

The newer AVRs (mega0, "xtiny", AVR-D*) let you switch clock configurations from software...
Good points! It's likely that Atmel was considering extreme temperatures and power supply instability when formulating their recommended start-up times.
« Last Edit: March 07, 2023, 07:11:23 pm by elecdonia »
I’m learning to be a leading-edge designer of trailing-edge technology.
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4199
  • Country: us
Re: Are there too many different bootloaders in the Arduino world?
« Reply #61 on: March 07, 2023, 10:09:44 pm »
Quote
I frequently use the "8MHz calibrated internal RC oscillator" in my projects. 8MHz provides a perfect 38.4k baud rate. It isn't terrible at 57.6k either. Unfortunately it is very much "out-of-spec" at 115.2k baud.
Sure, but 7.5MHz or 9.1MHz would hit more of the standard rates.
I think TI's MSP430 made big inroads on average current consumption by tuning an internal clock from a crystal (DFLL?) and being able to start up REALLY QUICK from power-down modes.  "Wakeup in 6us..."
 

Offline elecdoniaTopic starter

  • Frequent Contributor
  • **
  • Posts: 399
  • Country: us
Re: Are there too many different bootloaders in the Arduino world?
« Reply #62 on: March 08, 2023, 07:37:53 pm »
I think TI's MSP430 made big inroads on average current consumption by tuning an internal clock from a crystal (DFLL?) and being able to start up REALLY QUICK from power-down modes.  "Wakeup in 6us...
I worked on a project containing the MSP430 for my former employer ~10 years ago. The IDE we used was costly (IIRC it was "IAR embedded workbench"), but I didn't have to pay for it myself. In contrast the associated TI device programming hardware for the MSP430 wasn't terribly costly. 

I fully agree that MSP430 excels for extremely low-power applications.
« Last Edit: March 10, 2023, 06:47:49 pm by elecdonia »
I’m learning to be a leading-edge designer of trailing-edge technology.
 

Offline elecdoniaTopic starter

  • Frequent Contributor
  • **
  • Posts: 399
  • Country: us
Re: Are there too many different bootloaders in the Arduino world?
« Reply #63 on: March 10, 2023, 09:53:12 pm »
You might be entertained by looking at the undocumented fuse memory locations as well.  Rumor has it that they might contain additional info similar to the "unique identifier" fields that are documented in some of the later devices (XMega, 328pb)...
     https://www.avrfreaks.net/s/topic/a5C3l000000UTRvEAO/t126997

That's fascinating. I've been reading another discussion of undocumented locations in the AVR signature area.

This appeared in a discussion about (clone) Arduino pro-mini boards which were found to have sleep currents many times higher (150uA) than what was expected (~1uA):

     https://www.eevblog.com/forum/microcontrollers/arduino-pro-mini-two-copies-have-different-sleep-currents/msg3233760/#msg3233760
I’m learning to be a leading-edge designer of trailing-edge technology.
 

Offline elecdoniaTopic starter

  • Frequent Contributor
  • **
  • Posts: 399
  • Country: us
Re: Are there too many different bootloaders in the Arduino world?
« Reply #64 on: March 23, 2023, 04:47:34 pm »
Quote
Next I run this “FuseBytes” sketch to double-check that all the fuses are exactly the way I want
I don't think "FuseBytes" handles all the different chips you are using.  But it's been a long time since I looked at it.
After working with this FuseBytes sketch and testing it with a whole bunch of different AVR devices (ATmega328P, ATmega644, ATmega1284, ATmega2560) I've learned a great deal about how to use the compiler directives such as    #if defined( ... ),    #else if defined( ... ), and    #endif   to get the sketch to compile appropriately for specific AVR types. There's nothing better than studying "well designed" code! Just my opinion...

I even managed to create a "small" version of FuseBytes which runs on mega48, mega8, and mega88. There probably isn't much demand for such small devices these days, but because I have tubes full of them I went ahead and tested/modified FuseBytes so that it could be used with them.

My AVR device collection dates back to several projects I did between 2000 and 2010. These mostly started with PIC devices but I soon grew tired of writing PIC code in assembler and frequently getting caught by the strange way some of the PIC devices "segmented" their program memory with hardware "bank select" register bits.     :palm:   |O   :horse:
I soon grew fond of the AVR architecture which fit my needs perfectly.  :-+     For years I wrote my AVR code in assembler too (until the Arduino project happened).
I’m learning to be a leading-edge designer of trailing-edge technology.
 

Offline elecdoniaTopic starter

  • Frequent Contributor
  • **
  • Posts: 399
  • Country: us
Re: Are there too many different bootloaders in the Arduino world?
« Reply #65 on: March 23, 2023, 04:51:02 pm »
I now have an answer this topic's title question:

Optiboot is the best choice among all popular bootloaders for Arduino on Atmel AVR devices

It doesn't surprise me that most of the AVR-based Arduino boards come with optiboot bootloaders already installed.
I’m learning to be a leading-edge designer of trailing-edge technology.
 

Offline elecdoniaTopic starter

  • Frequent Contributor
  • **
  • Posts: 399
  • Country: us
Re: Are there too many different bootloaders in the Arduino world?
« Reply #66 on: March 30, 2023, 03:19:52 am »
After working with this FuseBytes sketch and testing it with a whole bunch of different AVR devices (ATmega328P, ATmega644, ATmega1284, ATmega2560) I've learned a great deal about how to use the compiler directives such as    #if defined( ... ),    #else if defined( ... ), and    #endif  to get the sketch to compile appropriately for specific AVR types. I even managed to create a "small" version of FuseBytes which runs on mega48, mega8, and mega88.
So I’ve continued developing and expanding FuseBytes.

Latest addition is a menu providing an in-depth full page view for each AVR fuse (low, high, extended, and lock). I developed a function which displays all of the possible options for configuring each fuse. This started as an informal way for me to test my edits of the original sketch, confirming that the output was correct for each and every fuse bit. Then I delved into using compiler directives to simulate the fuses of a different AVR device than the device actually running the sketch. I expanded the “bootloader details” to provide a complete hex dump of the bootloader. This is user controlled - it can display from one line (16 words, 32 bytes) up to the entire bootloader. The "code" section and attached .txt file shows the output as displayed in the Arduino serial monitor.

I’m gradually creating a flexible but simple menu system which may grow into a full command line interpreter. I need this for the projects I’m developing. I haven’t yet found any ready-to-use menu or CLI sketches which do what I want them to do.

Code: [Select]
Board ID:  328-P1 Ver: 230329-01 Compiled for ATmega328P

Signature:  1E 95 0F ATmega328P

Fuses:  E2 D6 FD   (L, H, E)      Lock:  EF      OscCal:  88

Low:  11100010 (0xE2)
      ||||++++_______ 8MHz calibrated internal RC oscillator
      ||++___________ Startup delay: 0b10
      |+_____________ Clock output pin disabled
      +______________ Clock frequency divider: 1/1

High: 11010110 (0xD6)
      |||||||+_______ Reset starts bootloader
      |||||++________ Bootloader size: 512 bytes
      ||||+__________ EEPROM saved during programming
      |||+___________ Watchdog timer programmable
      ||+____________ ISP programming enabled
      |+_____________ DebugWire disabled
      +______________ Reset pin enabled

Extended: 11111101 (0xFD)
          |||||+++_______ BOD: 2.7V

Lock: 11101111 (0xEF)
      ||||||++_______ ISP programming: R/W flash & EEPROM
      ||||++_________ Bootloader: R/W app flash
      ||++___________ App: Read only from boot flash

Bootloader detail:
  Optiboot ver:  8.0
  Size:          512 bytes (256 words)
  Start address: 0x7E00
Bootloader code displayed as AVR opcodes (little endian):
C001 C0B7 2411 B784 E890 9390 0061 9210 0061 2388 F061 2F98 709A 3092 F041 FF81
C002 EF97 BF94 2E28 E080 D0C6 C0E9 E085 9380 0081 E082 9380 00C0 E188 9380 00C1


_______________________________________________________________________________

        Show current fuse configuration:
f - Summary
d - Details

Show all available options for:
l - low fuse
h - high fuse
e - extended fuse
k - lock fuse

i - Show board ID
w - Write board ID
s - Show AVR MCU signature

b - Analyze bootloader
x - Toggle built-in LED
r - Show all info
? - Show this menu


_______________________________________________________________________________

Show all low fuse options
                        Clock options:
Low:  11100000 (0xE0)
      ||||++++_______ External clock source
      ||++___________ Startup delay: 0b10
      |+_____________ Clock output pin disabled
      +______________ Clock frequency divider: 1/1

Low:  11100001 (0xE1)
      ||||++++_______ Reserved
      ||++___________ Startup delay: 0b10
      |+_____________ Clock output pin disabled
      +______________ Clock frequency divider: 1/1

Low:  11100010 (0xE2)
      ||||++++_______ 8MHz calibrated internal RC oscillator
      ||++___________ Startup delay: 0b10
      |+_____________ Clock output pin disabled
      +______________ Clock frequency divider: 1/1

Low:  11100011 (0xE3)
      ||||++++_______ 128kHz internal RC oscillator
      ||++___________ Startup delay: 0b10
      |+_____________ Clock output pin disabled
      +______________ Clock frequency divider: 1/1

Low:  11100100 (0xE4)
      ||||++++_______ 32kHz LF watch crystal (fast start)
      ||++___________ Startup delay: 0b10
      |+_____________ Clock output pin disabled
      +______________ Clock frequency divider: 1/1

Low:  11100101 (0xE5)
      ||||++++_______ 32kHz LF watch crystal (slow start)
      ||++___________ Startup delay: 0b10
      |+_____________ Clock output pin disabled
      +______________ Clock frequency divider: 1/1

Low:  11100110 (0xE6)
      ||||++++_______ Full-swing ceramic resonator (fast start)
      ||++___________ Startup delay: 0b10
      |+_____________ Clock output pin disabled
      +______________ Clock frequency divider: 1/1

Low:  11100111 (0xE7)
      ||||++++_______ Full-swing crystal or resonator (slow start)
      ||++___________ Startup delay: 0b10
      |+_____________ Clock output pin disabled
      +______________ Clock frequency divider: 1/1

Low:  11101000 (0xE8)
      ||||++++_______ 0.4-0.9MHz LP ceramic resonator (fast start)
      ||++___________ Startup delay: 0b10
      |+_____________ Clock output pin disabled
      +______________ Clock frequency divider: 1/1

Low:  11101001 (0xE9)
      ||||++++_______ 0.4-0.9MHz LP ceramic resonator (slow start)
      ||++___________ Startup delay: 0b10
      |+_____________ Clock output pin disabled
      +______________ Clock frequency divider: 1/1

Low:  11101010 (0xEA)
      ||||++++_______ 1-3MHz LP ceramic resonator (fast start)
      ||++___________ Startup delay: 0b10
      |+_____________ Clock output pin disabled
      +______________ Clock frequency divider: 1/1

Low:  11101011 (0xEB)
      ||||++++_______ 1-3MHz LP crystal or resonator (slow start)
      ||++___________ Startup delay: 0b10
      |+_____________ Clock output pin disabled
      +______________ Clock frequency divider: 1/1

Low:  11101100 (0xEC)
      ||||++++_______ 3-8MHz LP ceramic resonator (fast start)
      ||++___________ Startup delay: 0b10
      |+_____________ Clock output pin disabled
      +______________ Clock frequency divider: 1/1

Low:  11101101 (0xED)
      ||||++++_______ 3-8MHz LP crystal or resonator (slow start)
      ||++___________ Startup delay: 0b10
      |+_____________ Clock output pin disabled
      +______________ Clock frequency divider: 1/1

Low:  11101110 (0xEE)
      ||||++++_______ 8-16MHz LP ceramic resonator (fast start)
      ||++___________ Startup delay: 0b10
      |+_____________ Clock output pin disabled
      +______________ Clock frequency divider: 1/1

Low:  11101111 (0xEF)
      ||||++++_______ 8-16MHz LP crystal or resonator (slow start)
      ||++___________ Startup delay: 0b10
      |+_____________ Clock output pin disabled
      +______________ Clock frequency divider: 1/1

                        Startup delay:
Low:  11000010 (0xC2)
      ||||++++_______ 8MHz calibrated internal RC oscillator
      ||++___________ Startup delay: 0b00
      |+_____________ Clock output pin disabled
      +______________ Clock frequency divider: 1/1

Low:  11010010 (0xD2)
      ||||++++_______ 8MHz calibrated internal RC oscillator
      ||++___________ Startup delay: 0b01
      |+_____________ Clock output pin disabled
      +______________ Clock frequency divider: 1/1

Low:  11100010 (0xE2)
      ||||++++_______ 8MHz calibrated internal RC oscillator
      ||++___________ Startup delay: 0b10
      |+_____________ Clock output pin disabled
      +______________ Clock frequency divider: 1/1

Low:  11110010 (0xF2)
      ||||++++_______ 8MHz calibrated internal RC oscillator
      ||++___________ Startup delay: 0b11
      |+_____________ Clock output pin disabled
      +______________ Clock frequency divider: 1/1

                        Clock output:
Low:  11100010 (0xE2)
      ||||++++_______ 8MHz calibrated internal RC oscillator
      ||++___________ Startup delay: 0b10
      |+_____________ Clock output pin disabled
      +______________ Clock frequency divider: 1/1

Low:  10100010 (0xA2)
      ||||++++_______ 8MHz calibrated internal RC oscillator
      ||++___________ Startup delay: 0b10
      |+_____________ Clock output pin enabled
      +______________ Clock frequency divider: 1/1

                        Clock frequency divider:
Low:  11100010 (0xE2)
      ||||++++_______ 8MHz calibrated internal RC oscillator
      ||++___________ Startup delay: 0b10
      |+_____________ Clock output pin disabled
      +______________ Clock frequency divider: 1/1

Low:  01100010 (0x62)
      ||||++++_______ 8MHz calibrated internal RC oscillator
      ||++___________ Startup delay: 0b10
      |+_____________ Clock output pin disabled
      +______________ Clock frequency divider: 1/8


_______________________________________________________________________________

Show all high fuse options:
                        Reset vector:
High: 11010111 (0xD7)
      |||||||+_______ Reset starts application
      |||||++________ Bootloader size: 512 bytes
      ||||+__________ EEPROM saved during programming
      |||+___________ Watchdog timer programmable
      ||+____________ ISP programming enabled
      |+_____________ DebugWire disabled
      +______________ Reset pin enabled

High: 11010110 (0xD6)
      |||||||+_______ Reset starts bootloader
      |||||++________ Bootloader size: 512 bytes
      ||||+__________ EEPROM saved during programming
      |||+___________ Watchdog timer programmable
      ||+____________ ISP programming enabled
      |+_____________ DebugWire disabled
      +______________ Reset pin enabled

                        Bootloader size:
High: 11010110 (0xD6)
      |||||||+_______ Reset starts bootloader
      |||||++________ Bootloader size: 512 bytes
      ||||+__________ EEPROM saved during programming
      |||+___________ Watchdog timer programmable
      ||+____________ ISP programming enabled
      |+_____________ DebugWire disabled
      +______________ Reset pin enabled

High: 11010100 (0xD4)
      |||||||+_______ Reset starts bootloader
      |||||++________ Bootloader size: 1k bytes
      ||||+__________ EEPROM saved during programming
      |||+___________ Watchdog timer programmable
      ||+____________ ISP programming enabled
      |+_____________ DebugWire disabled
      +______________ Reset pin enabled

High: 11010010 (0xD2)
      |||||||+_______ Reset starts bootloader
      |||||++________ Bootloader size: 2k bytes
      ||||+__________ EEPROM saved during programming
      |||+___________ Watchdog timer programmable
      ||+____________ ISP programming enabled
      |+_____________ DebugWire disabled
      +______________ Reset pin enabled

High: 11010000 (0xD0)
      |||||||+_______ Reset starts bootloader
      |||||++________ Bootloader size: 4k bytes
      ||||+__________ EEPROM saved during programming
      |||+___________ Watchdog timer programmable
      ||+____________ ISP programming enabled
      |+_____________ DebugWire disabled
      +______________ Reset pin enabled

                        EEPROM retention:
High: 11011110 (0xDE)
      |||||||+_______ Reset starts bootloader
      |||||++________ Bootloader size: 512 bytes
      ||||+__________ EEPROM erased during programming
      |||+___________ Watchdog timer programmable
      ||+____________ ISP programming enabled
      |+_____________ DebugWire disabled
      +______________ Reset pin enabled

High: 11010110 (0xD6)
      |||||||+_______ Reset starts bootloader
      |||||++________ Bootloader size: 512 bytes
      ||||+__________ EEPROM saved during programming
      |||+___________ Watchdog timer programmable
      ||+____________ ISP programming enabled
      |+_____________ DebugWire disabled
      +______________ Reset pin enabled

                        Watchdog timer:
High: 11010110 (0xD6)
      |||||||+_______ Reset starts bootloader
      |||||++________ Bootloader size: 512 bytes
      ||||+__________ EEPROM saved during programming
      |||+___________ Watchdog timer programmable
      ||+____________ ISP programming enabled
      |+_____________ DebugWire disabled
      +______________ Reset pin enabled

High: 11000110 (0xC6)
      |||||||+_______ Reset starts bootloader
      |||||++________ Bootloader size: 512 bytes
      ||||+__________ EEPROM saved during programming
      |||+___________ Watchdog timer always on
      ||+____________ ISP programming enabled
      |+_____________ DebugWire disabled
      +______________ Reset pin enabled

                        ISP programming:
High: 11110110 (0xF6)
      |||||||+_______ Reset starts bootloader
      |||||++________ Bootloader size: 512 bytes
      ||||+__________ EEPROM saved during programming
      |||+___________ Watchdog timer programmable
      ||+____________ ISP programming disabled
      |+_____________ DebugWire disabled
      +______________ Reset pin enabled

High: 11010110 (0xD6)
      |||||||+_______ Reset starts bootloader
      |||||++________ Bootloader size: 512 bytes
      ||||+__________ EEPROM saved during programming
      |||+___________ Watchdog timer programmable
      ||+____________ ISP programming enabled
      |+_____________ DebugWire disabled
      +______________ Reset pin enabled

                        DebugWire:
High: 11010110 (0xD6)
      |||||||+_______ Reset starts bootloader
      |||||++________ Bootloader size: 512 bytes
      ||||+__________ EEPROM saved during programming
      |||+___________ Watchdog timer programmable
      ||+____________ ISP programming enabled
      |+_____________ DebugWire disabled
      +______________ Reset pin enabled

High: 10010110 (0x96)
      |||||||+_______ Reset starts bootloader
      |||||++________ Bootloader size: 512 bytes
      ||||+__________ EEPROM saved during programming
      |||+___________ Watchdog timer programmable
      ||+____________ ISP programming enabled
      |+_____________ DebugWire enabled
      +______________ Reset pin enabled

                        Reset pin:
High: 11010110 (0xD6)
      |||||||+_______ Reset starts bootloader
      |||||++________ Bootloader size: 512 bytes
      ||||+__________ EEPROM saved during programming
      |||+___________ Watchdog timer programmable
      ||+____________ ISP programming enabled
      |+_____________ DebugWire disabled
      +______________ Reset pin enabled

High: 01010110 (0x56)
      |||||||+_______ Reset starts bootloader
      |||||++________ Bootloader size: 512 bytes
      ||||+__________ EEPROM saved during programming
      |||+___________ Watchdog timer programmable
      ||+____________ ISP programming enabled
      |+_____________ DebugWire disabled
      +______________ Reset pin disabled


_______________________________________________________________________________


   Show all extended fuse options:
                             BOD configuration:
Extended: 11111111 (0xFF)
          |||||+++_______ BOD: disabled

Extended: 11111110 (0xFE)
          |||||+++_______ BOD: 1.8V

Extended: 11111101 (0xFD)
          |||||+++_______ BOD: 2.7V

Extended: 11111100 (0xFC)
          |||||+++_______ BOD: 4.3V

Extended: 11111011 (0xFB)
          |||||+++_______ BOD: Invalid data= 3

Extended: 11111010 (0xFA)
          |||||+++_______ BOD: Invalid data= 2

Extended: 11111001 (0xF9)
          |||||+++_______ BOD: Invalid data= 1

Extended: 11111000 (0xF8)
          |||||+++_______ BOD: Invalid data= 0


_______________________________________________________________________________

Bootloader detail:
  Optiboot ver:  8.0
  Size:          512 bytes (256 words)
  Start address: 0x7E00
Bootloader code displayed as AVR opcodes (little endian):
C001 C0B7 2411 B784 E890 9390 0061 9210 0061 2388 F061 2F98 709A 3092 F041 FF81
C002 EF97 BF94 2E28 E080 D0C6 C0E9 E085 9380 0081 E082 9380 00C0 E188 9380 00C1
E189 9380 00C4 E086 9380 00C2 E08E D0B4 9A25 E084 E128 EF3E E091 9330 0085 9320
0084 BB96 9BB0 CFFE 9A1D 95A8 9140 00C0 FD47 C002 5081 F789 D093 3481 F479 D090
2F18 D0A0 3812 F411 E080 C004 E088 3811 F009 E083 D07E E180 D07C CFEE 3482 F419
E184 D098 CFF8 3485 F411 E085 CFFA 3585 F441 D076 2FC8 D074 2FD8 0FCC 1FDD D082
CFEA 3586 F419 E084 D085 CFDE 3684 F591 D067 D066 2EF8 D064 2ED8 E000 E011 0158
EF8F 1AA8 0AB8 D05C 01F8 8380 0185 10FA CFF6 D068 E4F5 12DF C001 CFFF E050 E040
E063 01CE D036 018E E0E0 E0F1 016F E082 0EC8 1CD1 8140 8151 E061 01C8 D02A 5F0E
4F1F 01F6 10FC CFF2 E050 E040 E065 01CE D020 CFB1 3784 F471 D033 D032 2EF8 D030
D041 018E 01F8 9185 018F D023 94FA 10F1 CFF9 CFA1 3785 F439 D035 E18E D01A E985
D018 E08F CF97 3581 F009 CFA9 E088 D024 CFA6 01FC 010A BF67 95E8 2411 B607 FC00
CFFD 7066 F029 2B45 F419 E181 BF87 95E8 9508 9190 00C0 FF95 CFFC 9380 00C6 9508
9180 00C0 FF87 CFFC 9180 00C0 FD84 C001 95A8 9180 00C6 9508 E6E0 E0F0 E198 8390
8380 9508 DFED 3280 F019 E088 DFF5 CFFF E184 CFDF 93CF 2FC8 DFE3 50C1 F7E9 91CF
CFF1 FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF 0800



« Last Edit: March 31, 2023, 06:41:17 pm by elecdonia »
I’m learning to be a leading-edge designer of trailing-edge technology.
 

Offline elecdoniaTopic starter

  • Frequent Contributor
  • **
  • Posts: 399
  • Country: us
Re: Are there too many different bootloaders in the Arduino world?
« Reply #67 on: March 31, 2023, 07:52:35 pm »
A more accurate answer to my question about the large number of different Arduino bootloaders requires explaining how the Arduino environment determines which bootloader to burn onto a board or bare AVR MCU chip.

First of all, because the bootloader communicates over a serial port, this necessitates having several different pre-compiled .hex bootloader files to match the desired AVR MCU clock frequency and baud rate. Choosing the correct .hex  bootloader file to burn onto the board or AVR MCU is handled automatically by the Arduino IDE (nearly all of the time). This configuration data is stored in Arduino "boards.txt" files. Note that "files" is plural because each "board" which can be selected by the user has its own specific "boards.txt" file.

Bootloader configuration parameters in "boards.txt: include:
  • Exact name of AVR MCU part (example: ATmega328P)
  • Clock frequency of AVR MCU (often 16MHz)
  • Baud rate for bootloader (often 115.2k, occasionally 19.2k, 38,4k, or 57.6k)
  • Which AVR UART will be used for bootloader (larger AVR devices have several)
  • Exact details for how to set the "fuses" on the  AVR MCU chip
  • Whether or not a bootloader is to be burned onto the AVR device

All of this is necessary because the bootloader must be aware of the AVR MCU clock frequency and of the desired serial port baud rate. These parameters (and others) must be "hard-coded" into the bootloader itself. "Boards" such as "minicore" which support several different AVR devices contain literally 100's of pre-compiled .hex bootloaders in order to support numerous different hardware, clock frequency, and baud rates. Fortunately the Arduino IDE user is spared most of the effort required to configure these details properly.

Popular Arduino boards (UNO, nano, and similar) come with bootloaders already installed. Even the Chinese clone boards often contain a "functional" bootloader pre-installed. It gets more interesting for those of us who wish to use bare AVR MCU chips or non-AVR MCU devices within the Arduino IDE. Fortunately the excellent "minicore," "mightycore," and "megacore" packages available on Github handle these details quite well. But due to the large number of choices which they support, one must pay attention to the user guide and examples provided.

Important: The Arduino IDE "burn bootloader" command does considerably more than just putting a bootloader onto the board. It also takes care of properly programming the "fuses" inside the AVR MCU. The "bootloader doesn't work" issue is often caused by incorrect fuse settings. Or by failure to select the correct choices within the Arduino IDE "boards" menu system.

For example, the "minicore" package enables the user to select among a large number of different AVR clock frequencies. But in order for this to work, one must "burn bootloader" after changing the AVR clock frequency within the Arduino IDE. This is required even for the case of using AVR MCU chips without a bootloader. I know this may not seem logical. After all, why  "burn bootloader" when one isn't using a bootloader?

The answer is this:  The Arduino IDE "burn bootloader" command properly sets the "fuses" inside the AVR MCU.

One alternative is to learn how to use AVRDUDE from either a command line or through the superb AVRDUDESS  GUI. But this requires detailed knowledge of AVR MCU hardware.

I'll provide specific examples and walk-throughs soon. I have successfully installed bootloaders onto many different AVR MCU devices. 
 
   

« Last Edit: April 01, 2023, 02:58:25 am by elecdonia »
I’m learning to be a leading-edge designer of trailing-edge technology.
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4199
  • Country: us
Re: Are there too many different bootloaders in the Arduino world?
« Reply #68 on: March 31, 2023, 08:55:59 pm »
May I quote that last message on the arduino forums, pretty much in its entirety? (It’s a really excelllent summary!)
If so, how would you like to be attributed?

 

Offline M0HZH

  • Regular Contributor
  • *
  • Posts: 206
  • Country: gb
    • QRPblog
Re: Are there too many different bootloaders in the Arduino world?
« Reply #69 on: March 31, 2023, 09:21:05 pm »
Ob xkcd:

(Attachment Link)

I came here to post this exact picture, but I knew in my heart it's been already posted.
 

Offline elecdoniaTopic starter

  • Frequent Contributor
  • **
  • Posts: 399
  • Country: us
Re: Are there too many different bootloaders in the Arduino world?
« Reply #70 on: April 01, 2023, 02:54:27 am »
May I quote that last message on the arduino forums, pretty much in its entirety? (It’s a really excelllent summary!)
If so, how would you like to be attributed?
Thanks! For now I’m low-key and don’t need any more attribution than a link to to this eevblog topic.

I find it amusing that I started this topic because I had a bunch of Arduino boards where more than 1 or 2 were really flaky in the bootloader department. So I suspected problems with the bootloader firmware. I discovered several different varieties of bootloaders on my boards, most but not all being some version of optiboot. But in reality my problem was with 3V and 5V logic failing to communicate with each other. Yep: A hardware problem. Nothing wrong with the bootloaders or the Arduino IDE, AVRDUDE, or anything else.

I still have plenty more Arduino boards and bare AVR MCU chips to analyze with FuseBytes. It’s a lot like “Situation: Now there are 15 competing standards” but in hardware. The complete AVR device family tree is like a giant live oak. I’ll never have time to check them all — just the ones I physically have on hand, which is more than I want to count right now.

Later, since I have a GitHub account (and if I learn how to navigate the licensing stuff and the developer features) then I’ll put some of my embedded code there. I’m also willing to privately share my functional code. Just send me a PM if interested.
I’m learning to be a leading-edge designer of trailing-edge technology.
 

Online tooki

  • Super Contributor
  • ***
  • Posts: 11501
  • Country: ch
Re: Are there too many different bootloaders in the Arduino world?
« Reply #71 on: April 01, 2023, 09:59:58 am »
Quote
Then your project will not have an Arduino bootloader and you will have to re-do all your Arduino work.


This is completely false.  The Arduino bootloaders are all completely separate and non-interacting with the user applications, whether they are "Arduino sketches" or programs written in some other development environment.  You can write Arduino sketches without using the bootloader (saves 0.5 to 8k of memory) (there's even an "upload using programmer" command), or you can use the Arduino bootloaders with non-Arduino applications.

The worst that is likely to happen is that for newer chips (ARM in particular), you may have to rebuild the application with a new segment start address for the vectors.  There are no run-time dependencies on the bootloader, and the bootloaders do their best to put the chip in a "just reset" state before starting the application.
I’ll add, because I have stated this elsewhere on the forum a few times and each time it comes as a surprise to some people:
“Arduino” really means three distinct big things:
1. Arduino-designed and branded MCU dev boards
2. The Arduino software framework, which provide easy-to-use wrappers for common functions and a few basic system functions like the millis() timer.
3. The Arduino IDE

These things are completely divisible, and you can use them in more or less any combination. (The only thing you can’t do, as far as I know, is use the Arduino IDE without using the Arduino framework, or with another programming language. Not that I see any reason you’d want to since the IDE is the least compelling part of the whole package!) You can use Arduino boards with other IDEs and languages. You can use third party boards within the Arduino IDE. You can use third party boards and another IDE, but use the Arduino framework (very common, for example programming the ESP32 with the Arduino framework with the PlatformIO IDE).

So you really can cherry-pick what you want out of the Arduino ecosystem. I’ll also add that while the Arduino framework provides wrappers for many functions, you don’t have to use them. For example, the digitalWrite() function is notoriously slow, but you are perfectly free to install an alternative library with faster IO, or write directly to the port registers. This means you can start programming with Arduino functions, and then progressively move away from them, since it’s basically C++ otherwise. It’s not an all-or-nothing situation like moving to a completely different platform.
« Last Edit: April 01, 2023, 10:01:48 am by tooki »
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4199
  • Country: us
Re: Are there too many different bootloaders in the Arduino world?
« Reply #72 on: April 01, 2023, 08:28:43 pm »
Quote
The only thing you can’t do, as far as I know, is use the Arduino IDE  using the Arduino framework
Ah, but you can.  Simply leave your "sketch" .ino file completely empty, and create a new tab with .S, .c, or .cpp file that defines main(), and it will override and omit pretty much all of the Arduino code.

I don't know why anyone would want to do that, since it's pretty universally agreed that the Arduino IDE editor is one of its weaker points, and you'd have a problem if you wanted to change compiler directives.  But it is possible.  (oh, and the resulting file will still upload using the bootloader, too.   So I guess if you wanted one-button upload of AVR assembly language using the gnu assembler,  the IDE might be useful; certainly as useful as the classes I've taken where you're given a template for some other IDE and a bare minimum of info as to how you'd modify that, or create something from scratch...
 

Offline elecdoniaTopic starter

  • Frequent Contributor
  • **
  • Posts: 399
  • Country: us
Re: Are there too many different bootloaders in the Arduino world?
« Reply #73 on: April 02, 2023, 12:43:40 am »
...it's pretty universally agreed that the Arduino IDE editor is one of its weaker points.
Somehow I’ve managed to write a lot of code with the Arduino IDE editor but that doesn’t mean that I enjoy using it. I’m ready to change to something better. Perhaps Platformio? Notepad++?
« Last Edit: April 02, 2023, 02:34:55 am by elecdonia »
I’m learning to be a leading-edge designer of trailing-edge technology.
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4199
  • Country: us
Re: Are there too many different bootloaders in the Arduino world?
« Reply #74 on: April 02, 2023, 07:11:36 am »
The Arduino IDE's "use external editor" works pretty well, for such a simple compromise.  If you already have a favorite code editor.  When I have to do "serious work", I edit my Arduino sketches with EMACS.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf