Maybe the biggest choices should be build compile time like with a #define. And the smaller optional stuff could be dynamic. Saying that it means going full blown c++. I wouldn't do that.johu wrote: ↑Tue Aug 31, 2021 7:42 amOne possibility would be using placement new (https://en.cppreference.com/w/cpp/language/new). It allocates an object at a pre-allocated buffer of any type. Best to use uint32_t to have 4-byte alignment:celeron55 wrote: ↑Sun Aug 29, 2021 6:48 pm I would often consider it fine to use dynamic allocation when you only do it once at startup, and never free anything. This implies that when changing the configured components in the UI, the only acceptable thing to do is to save the configuration and reboot. This way you begin again with a blank heap to allocate into, and can allocate different objects.
Pointers to statically allocated instances could be more robust though and I often use them myself in more complex firmware. You can use contructors to reset static instances at any time by doing something like staticFooInstance = FooClass();, which will call the constructor of FooClass just like doing new FooClass();, but instead of doing dynamic allocation places the result into the static variable. This is obvious of course, but that's part of why it's good.
Of course we wouldn't be using a specific class that we can just do sizeof() on but would need to come up with an expression that determines the maximum size of classes T1, T2, T3 at compile time.Code: Select all
#include <new> static uint32_t buf[sizeof(Terminal)/sizeof(uint32_t)]; extern "C" int main(void) { Terminal* test = new (buf) Terminal(USART2, termCmds); }
So when changing parameter "InverterType" in the event handler just call new() on the selected inverter class (and maybe delete() on the current one? - might be easier to go destructor-less).
In the Makefile we need to switch to at least c++17. Brings up a few warnings in the existing code but nothing critical.
Maybe we should go full #define mode.
That means the best performance and smallest code/memory footprint. The disadvantage is that you need a new binary for each change in architecture, for me that won't be an issue anyway since every change will involve code anyway.
We could make a build server/scripting so people could click and
Download their binary.