Yeah as I thought. If you keep the firmware at only 1 possible argument value for frequency
, you get a firwmare which has these functions:
avr-objdump.exe -d C:\Users\Maxi\Desktop\Programming_stuff\playground\.pio\build\attiny85\firmware.elf
C:\Users\Maxi\Desktop\Programming_stuff\playground\.pio\build\attiny85\firmware.elf: file format elf32-avr
Disassembly of section .text:
00000000 <__vectors>:
<vector table>
0000001e <__ctors_end>:
<low-level-init>
0000002e <__bad_interrupt>:
2e: e8 cf rjmp .-48 ; 0x0 <__vectors>
00000030 <beep_once.constprop.0>:
30: 80 b7 in r24, 0x30 ; 48
32: 85 68 ori r24, 0x85 ; 133
34: 80 bf out 0x30, r24 ; 48
36: 8f e1 ldi r24, 0x1F ; 31
38: 8d bd out 0x2d, r24 ; 45
3a: 89 b7 in r24, 0x39 ; 57
3c: 8f 7d andi r24, 0xDF ; 223
3e: 89 bf out 0x39, r24 ; 57
40: 8c b5 in r24, 0x2c ; 44
42: 80 61 ori r24, 0x10 ; 16
44: 8c bd out 0x2c, r24 ; 44
46: 88 ee ldi r24, 0xE8 ; 232
48: 93 e0 ldi r25, 0x03 ; 3
4a: 08 b6 in r0, 0x38 ; 56
4c: 05 fe sbrs r0, 5
4e: fd cf rjmp .-6 ; 0x4a <__SREG__+0xb>
50: 28 b7 in r18, 0x38 ; 56
52: 20 64 ori r18, 0x40 ; 64
54: 28 bf out 0x38, r18 ; 56
56: 01 97 sbiw r24, 0x01 ; 1
58: c1 f7 brne .-16 ; 0x4a <__SREG__+0xb>
5a: 80 b7 in r24, 0x30 ; 48
5c: 88 7f andi r24, 0xF8 ; 248
5e: 80 bf out 0x30, r24 ; 48
60: 8c b5 in r24, 0x2c ; 44
62: 8f 7e andi r24, 0xEF ; 239
64: 8c bd out 0x2c, r24 ; 44
66: 08 95 ret
00000068 <silence>:
...
0000008c <main>:
8c: d1 df rcall .-94 ; 0x30 <beep_once.constprop.0>
8e: 88 ee ldi r24, 0xE8 ; 232
90: 93 e0 ldi r25, 0x03 ; 3
92: ea df rcall .-44 ; 0x68 <silence>
94: cd df rcall .-102 ; 0x30 <beep_once.constprop.0>
96: 88 ec ldi r24, 0xC8 ; 200
98: 90 e0 ldi r25, 0x00 ; 0
9a: e6 df rcall .-52 ; 0x68 <silence>
9c: ff cf rjmp .-2 ; 0x9c <main+0x10>
0000009e <_exit>:
9e: f8 94 cli
000000a0 <__stop_program>:
a0: ff cf rjmp .-2 ; 0xa0 <__stop_program>
Notice how there’s a function called
00000030 <beep_once.constprop.0>:
“constant propagation” is exactly the optimization step which I talked about earlier: Just use the known constant, precompute the needed values in the function. The compiler did that here for you.
Now let’s use one argument with 1000
and one 1500
and the firmware now has these functions:
>avr-objdump.exe -d C:\Users\Maxi\Desktop\Programming_stuff\playground\.pio\build\attiny85\firmware.elf | grep ">:"
00000000 <__vectors>:
0000001e <__ctors_end>:
0000002e <__bad_interrupt>:
00000030 <beep_once.constprop.0>:
000000c0 <silence>:
000000e4 <main>:
000000fe <__subsf3>:
00000100 <__addsf3>:
00000122 <__addsf3x>:
000001c8 <__divsf3>:
000001e2 <__divsf3x>:
000001e6 <__divsf3_pse>:
00000298 <__fixunssfsi>:
000002f0 <__floatunsisf>:
000002f4 <__floatsisf>:
0000036a <__fp_inf>:
00000376 <__fp_nan>:
0000037c <__fp_pscA>:
0000038a <__fp_pscB>:
00000398 <__fp_round>:
000003ba <__fp_split3>:
000003ca <__fp_splitA>:
000003fe <__fp_zero>:
00000400 <__fp_szero>:
0000040c <__mulsf3>:
00000422 <__mulsf3x>:
00000426 <__mulsf3_pse>:
000004e2 <__divmodsi4>:
000004fa <__divmodsi4_neg2>:
00000508 <__divmodsi4_exit>:
0000050a <__negsi2>:
0000051a <__udivmodsi4>:
00000526 <__udivmodsi4_loop>:
00000540 <__udivmodsi4_ep>:
0000055e <_exit>:
00000560 <__stop_program>:
You can clearly see how there are a trillion compiler-integrated functions for floating point operations for add, sub, div, mul, negate, NaNs, infinity… all the required stuff to do floating point operations that is.
And that’s why your firmware size explodes.