Here is my entry into the “smallest blink program contest” compiled in the arduino IDE. Can you determine how it works?
//program only for atmega168 based arduino with supplied bootloader
typedef void (*func_type)(uint8_t);
func_type flash_led = (func_type) 0x1d17;
int main(void) {
for(;;)
flash_led(0xff);
}
The arduino IDE reports 184 bytes. The relevant part of the program compiles to the following loop of 14 bytes:
Obviously, the standard startup and arduino code add about 150 bytes. I’ve compiled the same code inside ATMEL Studio using a slimmed down gcrt1.s start file, eliminating the IVT and reduced the entire hex file to 32 total bytes.
Using the bootloader code to do your dirty work is cheating; you might as well program a completely empty sketch and let it loop through the empty memory until it hits the bootloader again. (although... good luck getting just the sketch area to be "empty." The bootloader doesn't erase it, and upload typically skips 'empty' memory.)
You're correct, remnants of old programs could very well be scattered throughout the flash and probably prevent the program from falling through to the bootloader.
Using the bootloader code to do your dirty work is cheating
I disagree; it's making maximum use of the existing facilities.
It reminds me of a programming challenge when I was a student.
The challenge was to calculate and print the value of e in as few bytes of code as possible, on an IBM-360 compatible mainframe.
The immediate fails were written in high-level languages like FORTRAN or Algol.
The better ones were written in assembler, but because of the I/O libraries to get the result out, the executables ran to several kilobytes.
The winner was about 30 or 40 bytes of pure assembler; it simply calculated e from the series in one of the floating-point registers, and then did a divide-by-zero.
This caused a core dump, and the core dump print-out included the FP registers.
The winner had the prize confiscated as soon as it was awarded, for wasting paper - a full core-dump ran to about a box of 132 column paper.
The challenge was never run again, to the best of my knowledge.
AWOL:
The winner was about 30 or 40 bytes of pure assembler; it simply calculated e from the series in one of the floating-point registers, and then did a divide-by-zero.
This caused a core dump, and the core dump print-out included the FP registers.
Divide by zero! Very clever, but very wasteful of paper as you said.
yaafm:
(Incidentally - I'm not sure your code would actually work because you're setting bit 5 of the DDR and then clearing it again when you set bit 4).
LOL - it’s not MY argument it’s YOURS. On your web site you say:
Eight bytes difference. So really, you can blink an LED in 8 bytes. That is the bottom line.
I was just pointing out (and doing it tongue in cheek BTW) that if YOU want to use that argument you could go the whole nine yards and blink a SECOND LED for ZERO extra bytes if you re-write your code as I suggested.
I would hazard a guess that Nick is Huh-ing at your assertion that it doesn't work, whereas my scope trace in previous code clearly shows that it is working. Just a guess though....
JimboZA:
I would hazard a guess that Nick is Huh-ing at your assertion that it doesn't work, whereas my scope trace in previous code clearly shows that it is working. Just a guess though....
I expect you're correct. However you're statement...
JimboZA:
Interestingly, the built-in led appears never on, an external one appears always on.
is exactly right and exactly confirms my assertion that Nick's code doesn't work as presented.
The built in LED on pin 13 appears never on because he's set it as an output (correctly) but then immediately RESET it to an input with his line that sets pin 12 as an output. (It's not just the one's that are important, the zero's have an effect too). He should have either OR'ed them OR as I said in my earlier post done both bits at the same time by writing 0x30 to the DDR.
To be clear - with Nick's code pin 12 will blink but pin 13 will not.