20 comments

[ 2.7 ms ] story [ 56.5 ms ] thread
"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!

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)

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.
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 :(

>> if you are using a heap on really small embedded device you're gonna have a bad time any way.

Yep. malloc() is generally discouraged on those things and should be seen as a big red flag in any code review.

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.
In a real world this is even more critical: you don't want, for example, your car brakes to fail because of OOM.
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!"
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
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.

interesting visualizations
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.

While it's nicely written, my first question is why are you running JS on a microcontroller?
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.
also espruino (http://www.espruino.com/) and tessel (https://tessel.io/) (Tessel 1, not 2)
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.

Don't set a constant poison, the attacker will just overwrite the poison with A5s. Generate a random byte on start-up.
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.