
Heap on Embedded Devices: Analysis and Improvement - dimonomid
https://blog.cesanta.com/embedded-heap-behaviour-analysis-and-improvement
======
omgtehlion
Wow wow, if you are using a heap on really small embedded device you're gonna
have a bad time any way.

Embedded engineering 101: statically allocate everything, and try not to push
the stack too much. But you can not do this with JS :(

~~~
chillingeffect
Yes that is Embedded 101. How about 201, 301, 401 and the real world? Dynamic
allocation happens. Parsing XML and OSC happens. Recording sequences of
various lengths happens. It makes sense to apply intelligence to dynamic
allocation.

~~~
omgtehlion
In a real world this is even more critical: you don't want, for example, your
car brakes to fail because of OOM.

~~~
RealityVoid
I think it really depends on your application. Car systems are pretty
predictable with regards to messages received, they don't have random users
sending impredictable data. I'm a SWE writing firmware for cars and I've got
to admit, I never caught myself thinking: "Gee, I could sure use the heap
right now!"

------
daphreak
"I have worked with a few embedded SDKs (by Microchip, Keil and Espressif),
and all of them have a really dumb built-in implementation of the heap."

Many embedded systems allocate just once at startup and these "really dumb"
implementations are completely sufficient. The vendors provide a fast, low-
overhead solution by default and trust that developers can go find a more
appropriate allocator if they need it for their application. Luckily we have
many implementations to choose from!

~~~
dimonomid
For the system that allocates just once at startup, I can't think of any
noticeable change of performance even if allocator is 20 times slower. But, it
should be memory-efficient, since RAM is really expensive on those devices,
isn't it?

Standard allocators that I'm familiar with use minimum 8 bytes overhead per
allocation. Umm_malloc uses 4 bytes overhead: twice less. If we have 200
allocations, it's 800 wasted bytes already.

Plus, it uses "best-fit" algorithm, so that the resulting fragmentation is far
less than with the "first-fit", which is used in standard allocators. (if one
really wants to, she can use "first-fit" on umm_malloc, too)

~~~
m_eiman
You also want to minimize Flash usage/code size; if your microcontroller has
8KB Flash, a more complex allocator might not be the best use of that Flash.
Especially if you've got a allocate-once pattern.

------
flyinglizard
Generally speaking, you should try really hard to avoid using the heap in any
system that has no virtual memory support. Heap fragmentation will ultimately
get your app.

The exception is in state machines where you know, in a deterministic way,
what the memory layout should be at every given state, and then you can use
heaps to get memory overlap between code pieces that operate exclusively of
each other.

------
cornellwright
While it's nicely written, my first question is why are you running JS on a
microcontroller?

~~~
gh02t
SmartJS is in the same niche as MicroPython, NodeMCU (non-JIT Lua), Netduino
(.net micro) etc: it's a language that is more accessible to people [read:
hobbyists] without a ton of experience programming embedded systems and who
don't want to get familiar with C/C++ to use Arduino. It's not really meant
for production products AFAIK, but to make IoT and other microcontroller stuff
more accessible to e.g. web devs without much hardware experience in the case
of SmartJS.

~~~
ta6334
also espruino ([http://www.espruino.com/](http://www.espruino.com/)) and
tessel ([https://tessel.io/](https://tessel.io/)) (Tessel 1, not 2)

~~~
gh02t
Oh, Tessel is kinda neat. I mostly use ESP8266 with the Arduino libs and
PlatformIO and am not much of a Javascript fan, but I understand the appeal of
these sort of devices.

I'm just looking forward to getting my hands on the ESP32. Espressif is
packing a lot of bang for you buck into those; I just hope they get around to
making a native SDK that is better documented. I've used the native SDK on the
ESP8266 a bit and it was miserable.

------
plasticchris
The allocator that comes with free rtos (I assume he's using it as he mentions
pvPortMalloc) can be extended to support realloc efficiently without too much
trouble so that it will resize if possible. For example
[https://github.com/hello/heap_6](https://github.com/hello/heap_6)

~~~
dimonomid
In this case, pvPortMalloc and friends is what Espressif SDK provides in their
binaries; it doesn't provide sources. So we can't just extend existing
allocator, without actually replacing functions with our implementations by
objdump.

We could replace them with whatever, but umm_malloc is still the most
efficient allocator for memory-constrained devices that I'm aware of.

------
plasticchris
From 2010, very similar approach:
[http://www.asyndetic.com/2010/07/30/visualizing-the-heap-
on-...](http://www.asyndetic.com/2010/07/30/visualizing-the-heap-on-embedded-
systems-part-ii/)

------
shenberg
Don't set a constant poison, the attacker will just overwrite the poison with
A5s. Generate a random byte on start-up.

~~~
chillingeffect
I like your random byte on start-up concept btw.

For the truly paranoid, the compiler must be re-written so that bits within
the stack words must remain unutilized and the remaining bits include a
cryptographically-signed bit field. E.g. a 32-bit machine can allocate 8 bits
of each word for application data and 24 bits for authentication.

------
poseid
interesting visualizations

