HomeKitADK icon indicating copy to clipboard operation
HomeKitADK copied to clipboard

Default memory footprint is too large

Open rojer opened this issue 5 years ago • 9 comments

With default values for kHAPIPSessionStorage_DefaultNumElements (17), kHAPIPSession_DefaultInboundBufferSize (32K) and kHAPIPSession_DefaultOutboundBufferSize (32K) the RAM footprint of a basic app ends up being over 1M. Pre-allocating all the buffers is safe in terms of peak memory footprint but is unacceptable for smaller platforms - e.g. on ESP8266 we only have 40K or so to work with, ESP32 has 200K or so, STM32 MCUs typically used in IoT applications have 128K to 1M of RAM total. For the library to be usable on those platforms, this needs to be addressed.

Immediate question: why are buffers 32K in size when the HAP protocol defines maximum payload size for an HTTP request at 1K? (HomeKit Accessory Protocol Specification non-Commercial Version R2, section 6.5.2)

rojer avatar Jan 07 '20 15:01 rojer

I'm also looking for guidance on the size of the scratch buffer - 32K is obviously a no go, but how much is really needed?

rojer avatar Jan 09 '20 04:01 rojer

ESP32 has 200K or so

That's weird, Espressif distributes the MFi version of the HomeKit ADK for the ESP32... Surely there is some info we are missing here.

https://www.espressif.com/en/products/software/esp-homekit-sdk

Clovel avatar Jan 14 '20 08:01 Clovel

they may have reduced buffer size and/or number of sessions. this is why i'm looking for clarity on the required size. 32K seems excessive when the spec says max payload size is 1K. @aajain-com ?

rojer avatar Jan 14 '20 20:01 rojer

if anyone's interested, i've been gradually converting static allocations to dynamic in my Mongoose OS port: readContexts, writeContexts, eventNotifications.

i/o buffers will be more challenging, but i have no choice...

rojer avatar Jan 26 '20 19:01 rojer

if anyone's interested, i've been gradually converting static allocations to dynamic

I believe that in embedded systems, dynamic allocation is generally frowned upon, and with good reasons.

Maybe compile time configuration is a more fitting solution ? Like a "easy-to-access" header defining all the buffer sizes or a configuration file used to set the defines at compile-time.

Clovel avatar Jan 26 '20 19:01 Clovel

i am well aware of that. but Mongoose OS, for one, embraces dynamic allocation, we're brave like that :) i mean, i'm all for static allocation, but current sizes are simply not viable for many platforms, including all of the ones we support. for me, the choice is between "no way, forget it" and "will work unless all the clients decide to request all the attributes at the same time".

"easy-to-access" header defining all the buffer sizes or a configuration file used to set the defines at compile-time.

it's perfectly possible to define all the necessary constants right now, the problem is that the produce of all the necessary buffers blows through available memory for the platforms in question.

rojer avatar Jan 26 '20 19:01 rojer

it's perfectly possible to define all the necessary constants right now, the problem is that the produce of all the necessary buffers blows through available memory for the platforms in question.

Is it not possible to simply calculate the total size of the buffers beforehand ? For example, "we know the ESP8266 does not have enough memory for the default sizes, but if you set them at these values, it's going to work". If it is possible, maybe we could make a document giving the buffer sizes that should be defined for popular platforms ?

Clovel avatar Jan 27 '20 08:01 Clovel

A port for ESP32/ESP32S2 has been made available here: https://github.com/espressif/esp-apple-homekit-adk

shahpiyushv avatar May 15 '20 09:05 shahpiyushv

FWIW, i found 1.5k i/o buffer size to be adequate. it has to be greater than 1k + some crypto padding to be able to contain 1k encrypted frames. further, in my mongoose-os port of the library. i've successfully made all the buffers dynamic, so that at present the largest statically allocated structure is the sessions array, followed by the scratch buffer. esp8266 build of the shelly-homekit firmware is able to support 9 concurrent connections with about 20k to spare.

the key changes are:

  • readContexts - https://github.com/mongoose-os-libs/homekit-adk/commit/ace7e0f915bfb04090b4d2f012c69afb39fbf0b4
  • writeContexts - https://github.com/mongoose-os-libs/homekit-adk/commit/5a97a69b3d4ef23f24cd9b82ab3d38a35f0f0496
  • eventNotifications - https://github.com/mongoose-os-libs/homekit-adk/commit/2ddb18858d0041e72d1817c1078169ec47c4296a
  • inboundBuffer - https://github.com/mongoose-os-libs/homekit-adk/commit/c2aaf26b1e71beb56946d238a692c49a9f0b030a
  • outboundBuffer - https://github.com/mongoose-os-libs/homekit-adk/commit/d70ad2c8003176221ba2c9c149f3730f0e2350a4

if there is interest, i can try to upstream the changes, as a compile-time option.

rojer avatar Aug 03 '20 00:08 rojer