Speed up post-reset booting of "uno" or avoid bootloader entirely

I'm working on a project which uses an ATMEGA328P chip on a custom PCB of my own design. Under certain circumstances the reset pin, usually pulled high with an external resistor have fitted, of this ATMEGA gets taken low by an external signal and the ATMEGA resets. Resetting like this is necessary for my project's design. I've described this as an "uno" because on the custom PCB my ATMEGA chip is fitted with the same 16MHz Oscillator and 22pF capacitor pair that an uno has, it runs from a regulated 5V supply like an uno does, and as there are not the necessary pins free for any form of in system programming I pop this ATMEGA out of the custom board's 28pin DIP holder, stick it into the DIP socket of an actal arduino uno, program it as if it were an uno, then put my programmed ATMEGA back in the DIP socket of the PCB. Once the project is finished the ATMEGA will no longer need reprogramming unless I find a bug in need of fixing, I hence don't want to do anything weird with fuse bits which makes the ATMEGA non-reprogrammable (I don't want to have to turn to high voltage programming to reset it), but don't mind doing things which mean the ATMEGA will need a it mroe laborious a programming process than clicking "upload".

My problem is that after resetting the ATMEGA with the reset pin it takes more thn 2 seconds to get my arduino sketch running, I need to reduce this time to 0.5 seconds maximum, though I'd ideally like it to be under 100ms or even under 50ms from the reset pin going high again to my sketch starting.

When I reset an atmega by cutting off the 5V supply, then turning it on again the booting is much quicker than 2 seconds, but due to what else is on my custom PCB and what pins of the ATMEGA and other things are available I am NOT able to use a "cut off the power supply the restore it" method to reset the atmega. I am also not able to use software methods and cannot do anything involving using an input pin to somehow trigegr a reset. I need reset to be done in the usual way by taking the first pin of the ATMEGA328P DIP packaae to ground.

I have already written a sketch in the arduino IDE using a mix of arduino functions and AVR register access functions, it works very well and I don't want to change it. I don't want to do anything which would force me to use a more raw form of code without the useful arduino functions.

I understand that the reason booting up takes so long after the reset pin has been low and then released to 5V again is because the arduino bootloader is waiting to see if it is being reprogrammed, but 2 seconds is a long time.

I think that a fix will either involve changing the bootloader to be faster or getting my code onto the ATMEGA without using a bootloader at all.

If I try to change the bootloader how is this done, or would reducing the booting time to reduce the 2 second delay to more like 50ms to100ms cause problems with my ability to upload programs to the ATMEGA?

The alternative seems to be getting tid of the bootloader entirely, but I don't know hpw easily this is done. Firstly I need to check whether, if programmed with an ISP method rather than the usual arduino way, the time for starting a .ino sketch after reset went high again would be reduced to nearly instantaneous?

I have several uno boards and loads of arduino uno bootloaded ATMEGA328P chips to hand and believe that I could take the ATMEGA out of an uno, put into it the ATMEGA which will go into my cutom PCB, then use one of my other unos as an arduino ISP. I have used an arduino uno as an ISP before, but only to put the usual bootloader onto a brand new unbootloaded ATMEGA328P chip. I'm not sure whether, or if so how, an arduino uno as a ISP can be used to put sketches on another ATMEGA328P in a way which allows that latter ATMEGA328P to run the sketch wthout first bootloading.

I hear rumours about an "upload with programmer" function in the arduino IDE but coldn't find a good tutorial about getting a sketch onto an atmega328p such that it doesn't have a bootloader on, nor am I sure whether all arduino functions will still work properly if a .ino sketch is directly programmed to an ATMEGA and the bootloader is avoided. I also hear rumours about using AVR dude from command line but this looks quite complex and seems to involve make files and compiling lots of source code before it can be done. Even then there look to be lots of command line options which avrdude needs to be fed with, and I'm not sure what the correct set of arguments for an uno like atmega328p chip would be when an arduino is being used as the ISP.

Also, once a sketch is uploaded by an ISP method and the atmega328p chip no longr has a bootloader, does reprogramming the atmega328p with new versions of the sketch require any weird steps, or is it just the same as programming it with an ISP the first time, and if you ever did want to make the chip act like a regular uno again could you put a bootloader back onto it (not that I itend to unless my sketch suddenyl needs further debugging).

Can anyone provide advice on these matters? Thanks.

P.S.I could buy an actual AVR ISP of some kind if necessary, but would rather use an arduino uno as ISP instead because I have to work from many different computers (windows x86, linux x86 (multiple different distros, some machines intel, others AMD), raspbian ARM...) and hear that ISP devices often have bothersome drivers which don't handle different types of computer too well.

  • Connect your "Arduino as ISP" to the ICSP header on the Uno you're using to program the chip.
  • Open the sketch you want to upload.
  • Tools > Board > Arduino/Genuino Uno
  • Tools > Port > select the port of your "Arduino as ISP".
  • Tools > Programmer > Arduino as ISP
  • Sketch > Upload Using Programmer

That will upload the sketch and erase the bootloader. There will now be no bootloader delay after reset. The only other effect of this is that you will no longer be able to do normal uploads to that chip until you've replaced the bootloader via Tools > Burn Bootloader. However, can continue to do "Upload Using Programmer" as many times as you like, following the same instructions above. That's it, the lack of a bootloader has absolutely no effect on anything else.

The Uno bootloader takes up 0.5 kB of program memory. After erasing the bootloader, you might expect that you'd get an extra 0.5 kB to use for your sketch, but this is not the case. If you do need that extra memory, you can do so fairly easily via MiniCore:

I can give instructions for that if you want.

5a. Adjust the fuses. BOOTRST needs to be changed to unprogrammed / 1. Without that change, if the application code crosses the bootloader boundary, very bad things happen.

Thousands of people (including myself many times) have used the Arduino IDE's Upload Using Programmer over the last decade without changing this fuse and I've never once seen any mention of "very bad things" happening to a single one of them.

I've never witnessed a wild turkey cross paths with a motorcyclist killing both. My lack of observation does not prove it cannot happen.

Reason it out.

What happens when BOOTRST is programmed?

What happens when BOOTRST is programmed and there is no bootloader?

What happens when BOOTRST is programmed and the application code encroaches on the area normally used by the bootloader?

Or, if you dig long and hard you will find an example or two on this forum. That's how I'm aware of the problem.

the device will jump to the boot loader address at Reset,

Since the "program" recipe does not use -D, -Uflash:w performs a chip erase before programming. On reset, the erased boot section will be jumped through, straight to the application section.

What circumstances could cause that to happen? It seems to me that if something is going so wrong that application code encroaches on the boot section, you're going to have a bad time regardless of whether you have a bootloader installed.

pert:
What circumstances could cause that to happen?

Application is greater than 32256 bytes (for an Uno). Everything beyond that is written were the bootloader would normal be. Execution starts at whatever happens to be at 0x7E00.

The Arduino IDE will fail the compilation and abort the upload if the application exceeds 32256 bytes on an Uno (or whatever {upload.maximum_size} is for the selected board). I guess the only way you could do it via the Arduino IDE is if you selected the wrong board (e.g. select Uno when you have a stock Nano).

For clarity my sketch is around 8700 bytes when compiled. Nowhere near to the 32kb sort of size where you need to remove the bootloader to make suifficient room. I want to get rid of having a bootloader purely for speed reasons, I don't care about the extra program memory space tht it frees up. With this in mind does that BOOTRST fuse need fiddling (if so how) or not? I'm assuming that the act of programming via an ISP method will either wipe the bootloader or cause it to be skipped and ignored, if not then need I wipe the bootloader of my atmega328p before doing the ISP upload of my sketch to it?

Thanks for the prompt replies

Infraviolet:
With this in mind does that BOOTRST fuse need fiddling

Speaking only for myself, I'm still sticking with "no".

Infraviolet:
if so how

If you do want to do it, here is the easiest way to do it via the Arduino IDE:

  • Install MiniCore, following these instructions: GitHub - MCUdude/MiniCore: Arduino hardware package for ATmega8, ATmega48, ATmega88, ATmega168, ATmega328 and ATmega328PB
  • Tools > Board > ATmega328
  • Tools > Bootloader > No
  • Tools > Clock > 16 MHz external
  • Tools > Variant > 328P / 328PA
  • Connect your "Arduino as ISP" to the ICSP header on the Uno you're using to program the chip.
  • Plug your "Arduino as ISP" in to your computer.
  • Tools > Port > select the port of your "Arduino as ISP".
  • Tools > Programmer > Arduino as ISP
  • Tools > Burn Bootloader - This will set the BOOTRST fuse correctly (because you set Tools > Bootloader > No).
  • Wait for the Burn Bootloader process to finish.
  • Open the sketch you want to upload.
  • Sketch > Upload Using Programmer

You only need to do the Burn Bootloader process once.

I'm assuming that the act of programming via an ISP method will either wipe the bootloader

That's correct. Upload Using Programmer clears the entire flash memory, including the boot section, before uploading the sketch.

Thanks for the prompt replies

You're welcome.

I originally had a couple of error in the instructions in my previous reply, due to the forum eating my first attempt and then me trying to do a lazy copy/paste on the second attempt. I have now edited them to be correct.

pert:
I guess the only way you could do it via the Arduino IDE is if you selected the wrong board (e.g. select Uno when you have a stock Nano).

A year from now, when @Infraviolet wants to update the application, will you remember the processor is incorrectly configured?

Or will you suggest they use "bare 328" as the board?

Or will you suggest they use "bare 328" as the board?

No, I don't foresee myself doing something like that.

Correctly configuring BOOTRST is best practices. There's no doubt about that. I understand and respect your point of view. I learned something from this discussion that will make me better at providing help to Arduino users.

However, I'm going to be stubborn and stick with my opinion. Once people start messing with ISP, I expect a certain level of competence (despite much evidence that this is not warranted). Screwing up (like selecting the wrong board) can have consequences, that's just a fact of life. In this case, the consequences are fairly minor. So I'll continue to advise people to use Upload Using Programmer with the wrong BOOTRST setting.

Very often, we tell people to connect a button directly between the pin and ground. I'd be surprised if you haven't told people to do this. The "very bad things" that will happen if they set that pin OUTPUT, HIGH and hold the button are much worse than some application code ending up in the boot section. And we're giving these instructions to the greenest of beginners! So by your logic, we should certainly be telling them to use a current limiting resistor. I'm not going to do that either.

I think we've presented enough information for Infraviolet to make their own choice. The one thing I should add is that Coding Badly knows WAY more than me on this topic and was actively involved in the Arduino project long before I even knew what a microcontroller was.

pert:
I think we've presented enough information for Infraviolet to make their own choice.

That's the goal. And I agree. We've reached it. Time for @Infraviolet to sink or swim. (Or ask more questions.)

The one thing I should add is that Coding Badly knows WAY more than me on this topic and was actively involved in the Arduino project long before I even knew what a microcontroller was.

Thank you for the kind words!

It does "bother"me that "upload using programmer" doesn't set the fuse appropriately (That would be another variable that "boards.txt" would need to include, but ... it shouldn't be that hard, and it's not like the project isn't pretty free with variables, anyway.) (although, the sheer number of "boards" that would have to be changed is a bit daunting...)

Thanks all, I'm going to go ahead and try the simple method from post #1, if I don't post on this thread agan you'll know it worked for my application.

Ok, so I've tried it, and the nice method in post #1 works, but only for some of my ATMEGA328P chips. I've got about 10 such chips lying around, from about 3 different suppliers. I found that atmega chips bought from RS components, and some chips which came with Uno clones I had bought from a brand called Kuman selling through amazon worked fine. But those bought from farnell didn't.

Although they seem to have the same part numbers as my other chips those which came from farnell were a horror to bootload in the first place when new, many months ago, I had to use Nick Gammon's bootloader method rather than the usual Arduino as ISP sketch. Once bootloaded via Gammon's method they worked fine for normal arduino upload, but I still can't re-bootload them using the Arduino as ISP method and I can't "upload using programmer" to them either. The error I get when trying to upload a bootloader or sketch using a programmer to the farnell chips is:

avrdude: stk500_getparm(): (a) protocol error, expect=0x14, resp=0x14

avrdude: stk500_getparm(): (a) protocol error, expect=0x14, resp=0x01
avrdude: stk500_initialize(): (a) protocol error, expect=0x14, resp=0x10
avrdude: initialization failed, rc=-1
Double check connections and try again, or use -F to override
this check.

avrdude: stk500_disable(): unknown response=0x12
the selected serial port avrdude: stk500_disable(): unknown response=0x12
does not exist or your board is not connected

I can still use them in the regular arduino way using the normal upload method. My RS and kuman/amazon ATMEGA328P chips will all happily be: rebootloaded, or programmed using another uno as an ISP programmer, or uploaded to the normal arduino way. My farnell chips can nly be bootloaded via Gammon's bootloader sketch and then uploaded to the normal way.

For now I can make use of just the RS and amazon chips, but if anyone can suggest what I might need to do to the farnell ones to get them working properly such that they can be bootloaded and ISP programmed like my RS and amazon chips can it would be strongly appreciated.

The exact link for the Kuman/amazon Uno's and the chips in them no longer exists but the RS and farnell ATMEGA chips were bought from:

and

same part number and everything, they should be EXACTLY the same!!

If you are getting something like this:

avrdude: stk500_getparm(): (a) protocol error, expect=0x14, resp=0x10
         Hardware Version: 4238814
         Firmware Version: 26625888.0
         Topcard         : STK502
         Vtarget         : 1.8 V
         Varef           : 0.0 V
         Oscillator      : Off
         SCK period      : 0.1 us

avrdude: stk500_initialize(): (b) protocol error, expect=0x10, resp=0x01
avrdude: initialization failed, rc=-1
         Double check connections and try again, or use -F to override
         this check.

avrdude: stk500_disable(): protocol error, expect=0x14, resp=0x10

avrdude done.  Thank you.

Error while burning bootloader.

Try putting a 10uF capacitor between Reset and Gnd on the Arduino used as ISP.

I didn't get the

Hardware Version: 4238814
Firmware Version: 26625888.0
Topcard : STK502
Vtarget : 1.8 V
Varef : 0.0 V
Oscillator : Off
SCK period : 0.1 us

bit, but the rest is similar. I'll try a 10uF cap from reset to gnd on the ISP arduino (not on the target arduino then?) but this seems to be a chip specific issue. I certainly haven't needed 10uF caps when programming an RS/amazon chip in the target and using an RS/amazon chip in the programmer. What's really odd is that if a farnell atmega328p is in either the ISP or target I get the same problem. Programming only works for me if both the ISP arduino uno's chip and the target arduino uno's chip are non-farnell ones.

P.S. this is a separate matter, but how safe is it to change the fuse bits on one of my RS atmegas? I've read up a bit and found that with the default arduino fuses, but no bootloader, my chip will start working after reset + about 70ms (16K clock cycles, +14 clock cycles, +65ms extra delay). But if I change the low fuse to 0xDF or 0xEF rather than the standard 0xFF then I can cut that 65ms to 4.1ms or nothing while still having the 16014 clock cycles at the start (about 1ms) to protect against non-perfect supplies. Are there any risks from changing the low fuse bits like this? Should I change the extended fuse bits to to go from a 2.7V brown out level to 4.3volt brownout detection? Whenever I'm resetting the ATMEGA chips they'll be on a stable supply, but quite how fast the supply turns on when the system is initially started up is something I'm not so sure of. I would not be altering the high fuse bits away from the 0xDE default. I've never tried changing any fuses before.

The 65ms delay is for the crystal oscillator to start. It probably doesn't need that much time, especially if it's one of the boards with a resonator rather than a crystal. How much time it DOES need is probably a complicated question, though...