You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

194 lines
7.7 KiB

  1. # Squeezing the most out of AVR
  2. AVR is severely resource-constrained, and as QMK continues to grow, it is approaching a point where support for AVR may need to be moved to legacy status as newer development is unable to fit into those constraints.
  3. However, if you need to reduce the compiled size of your firmware, there are a number of options to do so.
  4. ## `rules.mk` Settings
  5. First and foremost is enabling link time optimization. To do so, add this to your rules.mk:
  6. ```make
  7. LTO_ENABLE = yes
  8. ```
  9. This will cause the final step to take longer, but should get you a smaller compiled size. This also disables Action Functions, and Action Macros, both of which are deprecated.
  10. This will get you the most savings, in most situations.
  11. From there, disabling extraneous systems will help -- e.g.:
  12. ```make
  13. CONSOLE_ENABLE = no
  14. COMMAND_ENABLE = no
  15. MOUSEKEY_ENABLE = no
  16. EXTRAKEY_ENABLE = no
  17. ```
  18. This disables some of the functionality that you may not need. But note that extrakeys disables stuff like the media keys and system volume control.
  19. If that isn't enough to get your firmware down to size, then there are some additional features that you can disable:
  20. ```make
  21. SPACE_CADET_ENABLE = no
  22. GRAVE_ESC_ENABLE = no
  23. MAGIC_ENABLE = no
  24. ```
  25. These features are enabled by default, but may not be needed. Double check to make sure, though.
  26. Largest in size is "magic" -- the QMK magic keycodes -- which control things like NKRO toggling, GUI and ALT/CTRL swapping, etc. Disabling it will disable those functions.
  27. If you use `sprintf` or `snprintf` functions you can save around ~400 Bytes by enabling this option.
  28. ```make
  29. AVR_USE_MINIMAL_PRINTF = yes
  30. ```
  31. This will include smaller implementations from AVRs libc into your Firmware. They are [not fully featured](https://www.nongnu.org/avr-libc/user-manual/group__avr__stdio.html#gaa3b98c0d17b35642c0f3e4649092b9f1), for instance zero padding and field width specifiers are not supported. So if you use `sprintf` or `snprintf` like this:
  32. ```c
  33. sprintf(wpm_str, "%03d", get_current_wpm());
  34. snprintf(keylog_str, sizeof(keylog_str), "%dx%d, k%2d : %c");
  35. ```
  36. you will still need the standard implementation.
  37. ## `config.h` Settings
  38. If you've done all of that, and you don't want to disable features like RGB, Audio, OLEDs, etc, there are some additional options that you can add to your config.h that can help.
  39. Starting with Lock Key support. If you have a Cherry MX Lock switch (lucky you!), you don't want to do this. But chances are, you don't. In that case, add this to your `config.h`:
  40. ```c
  41. #undef LOCKING_SUPPORT_ENABLE
  42. #undef LOCKING_RESYNC_ENABLE
  43. ```
  44. Oneshots. If you're not using these, you can disable the feature by adding this to your `config.h`:
  45. ```c
  46. #define NO_ACTION_ONESHOT
  47. ```
  48. The same with tapping keys (mod tap, layer tap, etc)
  49. ```c
  50. #define NO_ACTION_TAPPING
  51. ```
  52. ## Audio Settings
  53. If you're using the Audio feature, by default that includes the music mode feature. This tranlates matrix positions into notes. It's neat for sure, but most likely, you're not using it. You can disable it by adding this to your `config.h`:
  54. ```c
  55. #define NO_MUSIC_MODE
  56. ```
  57. And by adding this to your `rules.mk`
  58. ```make
  59. MUSIC_ENABLE = no
  60. ```
  61. ## Layers
  62. There are also some options for layers, that can reduce the firmware size. All of these settings are for your `config.h`.
  63. You can limit the number of layers that the firmware uses -- if you're using less than 8 layers in total:
  64. ```c
  65. #define LAYER_STATE_8BIT
  66. ```
  67. or if you require up to 16 layers instead:
  68. ```c
  69. #define LAYER_STATE_16BIT
  70. ```
  71. Or if you're not using layers at all, you can outright remove the functionality altogether:
  72. ```c
  73. #define NO_ACTION_LAYER
  74. ```
  75. ## OLED tweaks
  76. One place you can save a bunch of space here is by not using `sprintf` or `snprintf`. This function call takes up ~1.5kB of firmware space, and can be rewritten. For instance, WPM uses this a lot.
  77. You can convert this:
  78. ```c
  79. // OLD CODE
  80. char wpm_str[4] = {0};
  81. sprintf(wpm_str, "WPM: %03d", get_current_wpm());
  82. oled_write(wpm_str, ' '), false);
  83. ```
  84. into this:
  85. ```c
  86. // NEW CODE
  87. oled_write_P(PSTR("WPM: "), false);
  88. oled_write(get_u8_str(get_current_wpm(), ' '), false);
  89. ```
  90. which outputs `WPM: 5`. Or this:
  91. ```c
  92. // NEW CODE
  93. oled_write_P(PSTR("WPM: "), false);
  94. oled_write(get_u8_str(get_current_wpm(), '0'), false);
  95. ```
  96. which outputs `WPM: 005`.
  97. ## RGB Settings
  98. If you're using RGB on your board, both RGB Light (Underglow) and RGB Matrix (per key RGB) now require defines to enable different animations -- some keyboards enable a lot of animations by default, so you can generally gain back some space by disabling specific animations if you don't use them. For RGB Light you can disable these in your keymap's `config.h`:
  99. ```c
  100. #undef RGBLIGHT_ANIMATIONS
  101. #undef RGBLIGHT_EFFECT_BREATHING
  102. #undef RGBLIGHT_EFFECT_RAINBOW_MOOD
  103. #undef RGBLIGHT_EFFECT_RAINBOW_SWIRL
  104. #undef RGBLIGHT_EFFECT_SNAKE
  105. #undef RGBLIGHT_EFFECT_KNIGHT
  106. #undef RGBLIGHT_EFFECT_CHRISTMAS
  107. #undef RGBLIGHT_EFFECT_STATIC_GRADIENT
  108. #undef RGBLIGHT_EFFECT_RGB_TEST
  109. #undef RGBLIGHT_EFFECT_ALTERNATING
  110. #undef RGBLIGHT_EFFECT_TWINKLE
  111. ```
  112. For RGB Matrix, these need to be explicitly enabled as well. To disable any that were enabled by the keyboard, add one or more of these to your keymap's `config.h`:
  113. ```c
  114. #undef ENABLE_RGB_MATRIX_ALPHAS_MODS
  115. #undef ENABLE_RGB_MATRIX_GRADIENT_UP_DOWN
  116. #undef ENABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT
  117. #undef ENABLE_RGB_MATRIX_BREATHING
  118. #undef ENABLE_RGB_MATRIX_BAND_SAT
  119. #undef ENABLE_RGB_MATRIX_BAND_VAL
  120. #undef ENABLE_RGB_MATRIX_BAND_PINWHEEL_SAT
  121. #undef ENABLE_RGB_MATRIX_BAND_PINWHEEL_VAL
  122. #undef ENABLE_RGB_MATRIX_BAND_SPIRAL_SAT
  123. #undef ENABLE_RGB_MATRIX_BAND_SPIRAL_VAL
  124. #undef ENABLE_RGB_MATRIX_CYCLE_ALL
  125. #undef ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT
  126. #undef ENABLE_RGB_MATRIX_CYCLE_UP_DOWN
  127. #undef ENABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON
  128. #undef ENABLE_RGB_MATRIX_CYCLE_OUT_IN
  129. #undef ENABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL
  130. #undef ENABLE_RGB_MATRIX_CYCLE_PINWHEEL
  131. #undef ENABLE_RGB_MATRIX_CYCLE_SPIRAL
  132. #undef ENABLE_RGB_MATRIX_DUAL_BEACON
  133. #undef ENABLE_RGB_MATRIX_RAINBOW_BEACON
  134. #undef ENABLE_RGB_MATRIX_RAINBOW_PINWHEELS
  135. #undef ENABLE_RGB_MATRIX_RAINDROPS
  136. #undef ENABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS
  137. #undef ENABLE_RGB_MATRIX_HUE_BREATHING
  138. #undef ENABLE_RGB_MATRIX_HUE_PENDULUM
  139. #undef ENABLE_RGB_MATRIX_HUE_WAVE
  140. #undef ENABLE_RGB_MATRIX_PIXEL_FRACTAL
  141. #undef ENABLE_RGB_MATRIX_PIXEL_FLOW
  142. #undef ENABLE_RGB_MATRIX_PIXEL_RAIN
  143. #undef ENABLE_RGB_MATRIX_TYPING_HEATMAP
  144. #undef ENABLE_RGB_MATRIX_DIGITAL_RAIN
  145. #undef ENABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE
  146. #undef ENABLE_RGB_MATRIX_SOLID_REACTIVE
  147. #undef ENABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE
  148. #undef ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE
  149. #undef ENABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS
  150. #undef ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS
  151. #undef ENABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS
  152. #undef ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS
  153. #undef ENABLE_RGB_MATRIX_SPLASH
  154. #undef ENABLE_RGB_MATRIX_MULTISPLASH
  155. #undef ENABLE_RGB_MATRIX_SOLID_SPLASH
  156. #undef ENABLE_RGB_MATRIX_SOLID_MULTISPLASH
  157. ```
  158. # Final Thoughts
  159. If you've done all of this, and your firmware is still too large, then it's time. It's time to consider making the switch to ARM. Unfortunately, right now is the worst possible time for that, due to the silicon shortage, and supply chain issues. Getting an ARM chip is difficult, at best, and significantly overpriced, at worst.
  160. -- Drashna
  161. That said, there are a number of Pro Micro replacements with ARM controllers:
  162. * [Proton C](https://qmk.fm/proton-c/) (out of stock)
  163. * [Bonsai C](https://github.com/customMK/Bonsai-C) (Open Source, DIY/PCBA)
  164. * [Raspberry Pi 2040](https://www.sparkfun.com/products/18288) (not currently supported, no ETA)
  165. There are other, non-Pro Micro compatible boards out there. The most popular being:
  166. * [WeAct Blackpill F411](https://www.aliexpress.com/item/1005001456186625.html) (~$6 USD)