What if we defined a sub-set of UAVCAN designed to be even simpler and more deterministic, requiring no dynamic memory allocation of any kindallowing for more primitive memory management, and eliminating some of the more vexing parts of the protocol for implementers. Specifically the featherweight profile (It’s a working title) would remove variable-length arrays and RPC/service calls (and unions if my proposal to remove unions wholesale is rejected). All full UAVCAN nodes would be able to receive all messages from featherweight nodes and would be able to send featherweight-compatible messages to those nodes (i.e. featherweight is a proper sub-set of the full protocol). We would also add a directive to DSDL to assert that a given message is compatible with the subset.
This is particularly useful for a safety-critical device that is self-programming over CAN. The primary application can be a featherweight but the secondary “flash over CAN” application would implement the full protocol. This allows for a certified hypervisor to protect the two making it easier to certify the primary to a higher design assurance level then the secondary and for the secondary to implement a large number of higher-level functions to facilitate diagnostics and debugging interactions without introducing failure modes to the primary application.
The overall idea makes sense in general and we should track this but I would like to point out that the full protocol does not seem to prescribe any logic that is inherently non-deterministic, nor does it necessarily require dynamic memory.
DSDL is specifically designed to avoid dynamic storage allocation. The upper size bound is always known for any variable-length type. The fact that Libuavcan v1 is going to require it is a mere implementation detail that does not follow from the protocol design (the old Libuavcan and Libcanard did not need it).
Whether the dynamic memory is required at the transport layer is dependent on the application design rather than on the protocol itself. In our generic implementations such as Libuavcan/Libcanard, we have to rely on dynamic memory of some kind because these are generic implementations and we do not have the luxury of making assumptions about how the application is going to be using the protocol. If we had access to the right context, it would be trivial to eliminate all forms of dynamic storage allocation.
I think that the Featherweight Profile belongs to the domain of implementation rather than specification. The main issue I see here is that the statement “featherweight is a proper subset of the full protocol” implies that the complement of that set is unimplementable under strong predictability requirements, which does not seem to be the case. I think we should consider instead turning it into a sort of best-practices advisory document describing how to deploy UAVCAN in high-DAL systems.
(Even if the protocol did require dynamic memory, it wouldn’t make it non-deterministic by itself, either. Contrary to popular misconceptions, dynamic memory can be managed in constant time and with bounded fragmentation. Dynamic memory adds complexity, though, so it is undesirable still.)
I edited my proposal to word it better (The determinism I refer to is the time-bounded determinism of RPC interactions where the guarantees deteriorate as the latencies increase).
Is it something that is purely implementation? Perhaps but we would need to, as we already do, have nothing in the core specification that violated this profile. Because of that, and to be pedantic, the specification would need foreknowledge of these constraints which makes them intrinsic.
I agree. Do you think the set of design principles we set out in section 1.3 is not sufficient? Should we extend it, or do you have something else in mind?