[Patch] Replacing boolean flag variables with bit field

This forum is dedicated to software development related to MultiWii.
It is not the right place to submit a setup problem.
Software download
Post Reply
Tommie
Posts: 438
Joined: Sun Apr 08, 2012 9:50 am

[Patch] Replacing boolean flag variables with bit field

Post by Tommie »

The Multiwii firmware is riddled with a lot of boolean flag variables,
each needing one byte of RAM. Since memory is a scarce ressource, this
commit groups all (most) of these variables into a single bit array that
it accessed through the convinience functions get_flag/set_flag. Instead
of defining new variables, please just ammend the enum mwc_flags; the
array size is adapted automatically.

Any ideas about this change? Works fine for me and hould be easily extendable:
https://github.com/wertarbyte/multiwii- ... 02c08279ae

Hint: I originally wanted to add the enumeration to MultiWii.ino, but it breaks the build process for me since function prototypes are inserted before the enum definition :-/

Tommie
Posts: 438
Joined: Sun Apr 08, 2012 9:50 am

Re: [Patch] Replacing boolean flag variables with bit field

Post by Tommie »

I made a few additional patches to reduce the memory (both RAM and ROM) footprint:

Omit servo variables unless needed: https://github.com/wertarbyte/multiwii- ... 5b4bfaaaeb
Shrink rcalue array for standard receivers: https://github.com/wertarbyte/multiwii- ... 7dc0c8b08d
make Buzzer optional: https://github.com/wertarbyte/multiwii- ... 2b77fb0309

Feel free to discuss :-)

ronco
Posts: 317
Joined: Thu Aug 18, 2011 2:58 pm

Re: [Patch] Replacing boolean flag variables with bit field

Post by ronco »

Hi Tommie,

Nice! :)

i dont really know how flags work .. but that sounds good. maybe you can explain why this uses less RAM & ROM and how it works?

regards Felix

Tommie
Posts: 438
Joined: Sun Apr 08, 2012 9:50 am

Re: [Patch] Replacing boolean flag variables with bit field

Post by Tommie »

ronco wrote:i dont really know how flags work .. but that sounds good. maybe you can explain why this uses less RAM & ROM and how it works?

It preserves RAM because having a uint8_t in memory will require a complete byte, even if you are only using one bit of it (like a boolean flag, 1/0). By using a bitmask (flag_mask[]), we can aggregate eight boolean variables into a single byte and assign one bit for each.

At the moment, 16 former flag variables are combined into the bit field; instead of requiring 16 uint8_t variables and wasting 16 Byte, these flags now only afford two bytes; if additional variables are added, the code automatically increases the size of the byte array used:

Code: Select all

enum mwc_flag {
  FLAG_OK_TO_ARM,
  FLAG_ARMED,
  FLAG_I2C_INIT_DONE,
  FLAG_ACC_CALIBRATED,
  FLAG_NUNCHUKDATA,
  FLAG_ACC_MODE,
  FLAG_MAG_MODE,
  FLAG_BARO_MODE,
  FLAG_GPS_HOME_MODE,
  FLAG_GPS_HOLD_MODE,
  FLAG_HEADFREE_MODE,
  FLAG_PASSTHRU_MODE,

  FLAG_GPS_FIX,
  FLAG_GPS_FIX_HOME,

  FLAG_SMALL_ANGLES_25,

  FLAG_CALIBRATE_MAG,

  FLAG_CNT
};
...
/* bitmask for all the flags specified in def.h */
uint8_t flag_mask[FLAG_CNT+7 / 8] = {0};


Tommie
Posts: 438
Joined: Sun Apr 08, 2012 9:50 am

Re: [Patch] Replacing boolean flag variables with bit field

Post by Tommie »

Already commented on that :-)

Alexinparis
Posts: 1630
Joined: Wed Jan 19, 2011 9:07 pm

Re: [Patch] Replacing boolean flag variables with bit field

Post by Alexinparis »

Hi,
So around 16 bytes saved in RAM, but what is the trade off with flash size ?

Tommie
Posts: 438
Joined: Sun Apr 08, 2012 9:50 am

Re: [Patch] Replacing boolean flag variables with bit field

Post by Tommie »

Don't know, but acceptable. If you exceed flash size, you notive while flashing. If your stack crashes into your heap, you only notice when your ISRs are trashed and the copter takes off to location unknown. Luckily, I was able to grab it before it could deal some real damage.

Therefore, SRAM is far more important than flash size. My firmware is now at 27064 byte, including GPS, Sonar, MAG, some larger custom stuff (data transfer framework), LED flashers, landing lights and the new descriptive strings for PIDITEMS and BOXITEMS.

User avatar
EOSBandi
Posts: 802
Joined: Sun Jun 19, 2011 11:32 am
Location: Budapest, Hungary
Contact:

Re: [Patch] Replacing boolean flag variables with bit field

Post by EOSBandi »

Tommie wrote:Don't know, but acceptable. If you exceed flash size, you notive while flashing. If your stack crashes into your heap, you only notice when your ISRs are trashed and the copter takes off to location unknown. Luckily, I was able to grab it before it could deal some real damage.

Therefore, SRAM is far more important than flash size. My firmware is now at 27064 byte, including GPS, Sonar, MAG, some larger custom stuff (data transfer framework), LED flashers, landing lights and the new descriptive strings for PIDITEMS and BOXITEMS.


Tommie,
What about implementing a safeguard for the stack/heap limit ? We are walking on a thin line, so it would be better to know how much memory do we left....
EOSBandi

Tommie
Posts: 438
Joined: Sun Apr 08, 2012 9:50 am

Re: [Patch] Replacing boolean flag variables with bit field

Post by Tommie »

EOSBandi wrote:What about implementing a safeguard for the stack/heap limit ? We are walking on a thin line, so it would be better to know how much memory do we left....

How would you implement this? If I call a method with a local variable "uint8_t buf[TOO_LARGE_FOR_MY_STACK]", how will you detect if the stack pointer just tripped over the heap? And far more important, how would you handle that?

One could think about using "malloc" for local buffers; but I'm not sure whether the ATMega can handle it gracefully. And even with that you'd still need to have a way to bail out of your function.

//edit: http://www.nongnu.org/avr-libc/user-manual/malloc.html
doesn't look so bad at all. I'll see what can be done with that...

//edit: OK, it looks bad at all. Using malloc adds about 600 byte to the firmware. Even I have to admit that this is too much.

User avatar
EOSBandi
Posts: 802
Joined: Sun Jun 19, 2011 11:32 am
Location: Budapest, Hungary
Contact:

Re: [Patch] Replacing boolean flag variables with bit field

Post by EOSBandi »

What about this : http://forum.pololu.com/viewtopic.php?f ... read#p4218
It does not use malloc. We can check free mem in the main loop and activate a failsafe or a buzzer below a given treshold.

Tommie
Posts: 438
Joined: Sun Apr 08, 2012 9:50 am

Re: [Patch] Replacing boolean flag variables with bit field

Post by Tommie »

In the mainloop, the stack has already collapsed again. You'd need probes throughout the program (see my latest patch), but if you encounter the situation, it's probably already to late.
That's the problem with Turing machines: You cannot decide whether they fill your memory or terminate. Greetings to the busy beaver and Rice's theorem.

So all you can do is compile your firmware, place probes in strategic locations (ISR, some bigger and deeper functions), watch the min_mem value and hope for the best.
Static verification is probably out of the window with that big pile of C++ :-)

Post Reply