Architecture
The layered design of kbox-stack — facade, database, DPT helpers, peripheral interfaces, and security — plus telegram data flow, the heap-free memory model, and where your code plugs in.
Layer overview
kbox-stack is organized as a small set of layers. Only the top and the interface
boundary are public; the concrete orchestrator, database internals, and security engine
live inside the .a.
┌────────────────────────────────────────────────────────────┐
│ Your application logic (KnxLogicBase / ILogic) │
├────────────────────────────────────────────────────────────┤
│ Facade: IKnxStack (Init / Work / Process / …) │
├─────────────────────┬──────────────────┬────────────────────┤
│ GroupObjectTables │ DPT helpers │ Security │
│ (group addr │ (Dpt::D9 float, │ (ISecurity — │
│ ↔ object) │ raw ↔ meaning) │ optional, secure)│
├─────────────────────┴──────────────────┴────────────────────┤
│ Peripheral interfaces (DI boundary — PORTABLE): │
│ IBusDriver ITransmitter IFlash IClock │
│ ILed IButton IWatchDog │
├────────────────────────────────────────────────────────────┤
│ Platform layer (NOT part of the core): │
│ Hal* implementations — STM32 HAL today │
└────────────────────────────────────────────────────────────┘The dashed rule that matters most is the peripheral interface boundary. Everything
above it is the portable core; everything below it is a platform. The core is compiled
into the archive with no reference to any concrete Hal* type.
Peripheral Interfaces
STM32 HAL Platform
Telegram data flow
A group-write from the bus travels through the stack like this:
IBusDriver) receives raw bytes from the KNX TP1 line and queues them.IKnxStack::Work() drains the RX queue and decodes each frame into a telegram.GroupValueWrite is applied to the database, producing a list of changed objects; each change is reported to your logic via the onDifference callback.SendTelegramGroupValueWrite(deviceObject).ITransmitter).So the round trip is: bus → driver → stack → onDifference → your logic →
SendTelegramGroupValueWrite → stack → driver → bus.
Static memory model
No heap. The stack object is placement-new'd into a caller-owned
KnxStackStorage — a fixed, statically-sized buffer you declare at file scope. There is
no malloc in the construction path. The storage size depends on the configured maximum
APDU length (KNX_APDU_MAX): a larger APDU selects a larger buffer.
Because the storage is caller-owned and static, its lifetime is your responsibility.
If KnxStackStorage is stack-local, the IKnxStack& returned by the factory dangles the
moment its scope ends. See Constructing the Stack
and the Integration Contract.
Portable core, pluggable platform
The core (IKnxStack, database, DPT helpers, security) has no dependency on any
concrete HAL. It sees only the I<X> peripheral interfaces. To retarget kbox-stack to
a different MCU you implement those interfaces for your platform and rebuild the
binary — the prebuilt archive that ships today is Cortex-M3 / STM32F103xB. The design
is portable; the binary is platform-specific. See Porting.
Where your code plugs in
Your application logic derives from KnxLogicBase (which implements the stack's
ILogic interface). Its constructor takes an IKnxStack& and auto-registers itself
via SetLogic — so you never forget to wire it up.
#include <Stack/Logic/KnxLogicBase.h>
class MyLogic : public KnxLogicBase {
public:
explicit MyLogic(IKnxStack& stack) : KnxLogicBase(stack) { /* ... */ }
void Work() override { /* product logic — stack.Work() calls this each loop */ }
};Beyond the Work() hook, your device reacts to bus events through the six callbacks you
register in StackParameters:
| Callback | Fires when |
|---|---|
onDifference | A group write changed one or more objects (the main event) |
onKnxTelegram | A raw application-level bus telegram arrived |
onTelegram | Any raw telegram arrived (byte span) |
onErrorKnxTelegram | A faulty telegram was received |
onResetCommand | An A_Restart was processed |
onStackError | The stack hit an error condition (e.g. a segment-size error) |
See Group Objects for the DeviceObject model and
Configuration for the full callback and parameter set.