While implementing UAVCANv1 in C using libcanard and the nunavut C templates. I’ve noticed that RAM requirements for such a application can be quite high, furthermore I do see some potential memory savings if we add some changes in the implementation
A good example would be making a simple publisher using the reg/drone/service/battery/status_0.2.uavcan message.
- First we need to allocate a heap that libcanard can use to allocate memory on it, we use O1Heap as our memory allocator, to calculate to the correct we use this formula H(M,n) = 2 M (1 + ⌈log2 n⌉), where M = (reg_drone_service_battery_Status_0_2_EXTENT_BYTES_ 600UL ) and n=1, Thus we need 600bytes of preallocated heap in this single publisher example
- Then in our publish function we need to allocate the generated reg_drone_service_battery_Status_0_2 C data structure on our stack, which is 1044 bytes
- To serialize the C data structure we’ve to allocate a payload buffer array with the size of (reg_drone_service_battery_Status_0_2_SERIALIZATION_BUFFER_SIZE_BYTES_ 534UL) bytes
- Then we allocate CanardTransfer put the payload in and copy this data again using canardTransfer
In total we need atleast 600 + 1044 + 534 = 2178 bytes of RAM to make this simple example to work. And this is just a single thread with a single publisher and no subscriber, if we add multiple publisher and we listen for different subscribers this will grow hard.
About the potential memory savings I see 2 options that might mitigate this.
-
currently nunavut generates all entries for an array, thus in the case of the cell voltages we generate a Float32[255] whereas we might only want to report let’s say 6 voltages, now we need to allocate 1020 bytes on our stack instead of 24 bytes. Yet we always know we’re not going to exceed this at all, could there be a possibility to limit this compile time? E.g. somekind of define we can override?
-
To publish a message you’ve allocate 3 times
- Allocate C struct
- Allocate payload array
- let libcanard allocate the canardtransfer in the preallocated O1Heap array
Yet in theory we could avoid allocating the payload array and use the preallocated memory in the O1Heap instead. Of course this would be require some architectural changes in libcanard though.