2

I'm trying to reduce my sketch size and managed to reduce both SRAM and Flash memory.

From:
1570 SRAM - 32144 Flash memory
To:
644  SRAM - 19458 Flash memory

This are what I've done so far:

Enabling LTO

Using PROGMEM

Dropping string and using char

Dropping bootloader

Using port manipulation

Using registers to declare pins output/input

Removing/Optimizing/Combining; unnecessary/repeated codes in the sketch

Using EEPROM is not an option for me.

What else i can do to take optimization one or two step further?

ElectronSurf
  • 814
  • 4
  • 17
  • 43

2 Answers2

5

What you can do in addition to the items you mentioned:

SRAM reduction

  • Use the smallest amount of data type for integers, e.g. use an 8 bit data type instead of the default integer, this saves you one byte for every variable. See remark below about types. I made my own types (if not existing) for int32_t, uint32_t, int16_t, uint16_t, int8_t and uint8_t and always use the smallest possible.
  • Use unsigned instead of signed for types that cannot be negative. This might save you one byte if you can prevent using an unsigned byte instead of a signed int because a value can be in range [128..255]. The same for unsigned int instead of signed long.
  • Use bit fields if you use multiple booleans inside a struct or class. Make sure the bit fields are declared consecutively.
  • Pack data in smart structures ... I.e. if you have two variables, where one can be 0..7 and another can also be 0..7, store this together using bit fields (in combination with boolean to bit field above).
  • Prevents float/doubles (see KIIV's comment below), instead:
  • Instead of using a float, multiply the value by the needed accuracy and store it in an integer (if you don't need high accuracy and it fits in the integer type).
  • In case you need a lot of strings to be stored, and those strings do not have characters above 128, you can save 1 bit per byte, of course this means quite some programming work to handle 7 bits 'ASCII' characters.
  • The same, if you have to store a lot of values that can be e.g. 0 to 50, you can use 6 bits instead of 8 bits; you cannot use bit fields, but you can make a smart array and program your own get/set functions to access the 6 bit values.
  • If you use libraries which declare big buffers, try to minimize those buffers, this might cause to copy them and manually change them yourself.
  • Prevent your own buffers to be made global, instead use them as a local variable temporarily when you need them. If you have two of such buffers, you don't have both buffers allocated at the same time; note however, that during execution, that buffer still needs space (so you have to calculate or make a guess/estimation what the maximum stack size will be).

Flash Reduction

  • Don't use duplicated code blocks, but make functions with parameters to differ between the differences of the duplicated code.
  • Instead of lookup tables, create a function that calculates it (if possible). Of course the gain depends on the length of the lookup table and the length of the function.
  • Instead of debugging strings, use numbers.

Both SRAM/Flash Reduction

  • Split your application over multiple MCUs, of course this adds some kind of communication protocol (UART, I2C, SPI).
Michel Keijzers
  • 13,014
  • 7
  • 41
  • 58
0

I'm having flashbacks to my early days as a C programmer in the 80's.

Some thoughts in addition to all of the excellent advice already given ...

  • Depending on how much data your application uses, you may want to read / write data to an SD card (or other external storage). While there is a certain amount of overhead for the libraries, the payoff is you then have virtually unlimited storage. This is the equivalent of how we used to store data on 5 1/4" diskettes back in the old days.

  • Avoid static variables whenever possible.

  • Keep the scope of a variable as small as possible.

  • As a philosophy you should consider unsigned char to be your default data type and only 'upgrade' to a bigger footprint when your code requires.

Rob Sweet
  • 51
  • 9