Tricking Arduino IDE into Flashing My Own Pre-Compiled Binary
2021.01.25 | Yuki Rea
This is not meant to be a tutorial or how-to, merely the story of a dumb hack I had to come up with in order to flash my own firmware onto a microcontroller when nothing else worked. This is a fairly niche problem but one that I needed a solution ASAP, the set up goes like this. I was helping a friend build and program a custom macro keypad for their workstation utilizing QMK keyboard firmware and an Atmel ATmega32u4 microcontroller. The Atmel Microcontroller was on a knock-off Arduino board which seemed to have a non-standard bootloader on it. I did not have a Linux machine with me at the time and we needed to get the compiled firmware onto the Atmel board the same day. AVRDUDE, Teensy Loader, QMK Toolbox, and every other flashing utility we tried to use on Windows would not complete a successful flash of our firmware. We would either get errors, corrupted firmware, or the flash utility could not recognize the Atmel MCU at all. The only thing that worked was using a default sketch in Arduino IDE and uploading the sketch to the Atmel board from there. This confirmed that the board itself worked, but we need to flash our own custom firmware and not an Arduino sketch. At this point, I sparked an idea, what if we could trick the Arduino software suite into flashing our own firmware onto the MCU? This can't work I thought, but at this point anything was worth a shot, I needed to test the firmware before I left for the day.
To my surprise, this worked, and this is how. I first looked at what the Arduino software suite does when it compiles each sketch. It drops the compiled sketch into a temporary directory with a filename unique to the sketch. Various places online suggested copying the AVRDUDE flash command that Arduino uses to flash the MCU and replace the file name with the file you want to flash. No matter what I did, AVRDUDE always failed to flash the firmware. The trick was to rename my hex file to the same file name that Arduino will compile and replace it with my own. The only problem is that Arduino will overwrite the file every time you attempt to flash a sketch. We cannot just replace the file beforehand and make it read only so it can not be overwritten, Arduino will fail with an error because it unable to write the file. To work around this I renamed the hex file in advance and placed it in another directory. Then I clicked the "Upload" button to start compiling the sketch. Watching the console output for when Arduino has finished writing it's compiled sketch, I immediately copy and replace my file over the one Arduino has just written. This has to be done very quickly before the flash starts. If you are fast enough, Arduino will issue the AVRDUDE command and flash our hex file. After all of that hassle, I was then able to flash the MCU normally with QMK Toolbox, AVRDUDE still would not work unless using my Arduino IDE trick.