uorb: compress format definitions

Reduces flash usage by ~16KB.

- compress formats at build-time into a single string with all formats
- then at runtime iteratively decompress using
  https://github.com/atomicobject/heatshrink
This commit is contained in:
Beat Küng
2023-11-08 00:31:26 -05:00
committed by Thomas Stastny
parent 142e44c418
commit 1ad5a9de08
27 changed files with 1736 additions and 252 deletions
+23 -36
View File
@@ -40,6 +40,7 @@
#include "uORBManager.hpp"
#include "uORBCommon.hpp"
#include "uORBMessageFields.hpp"
#include <lib/drivers/device/Device.hpp>
@@ -196,7 +197,7 @@ int orb_get_interval(int handle, unsigned *interval)
const char *orb_get_c_type(unsigned char short_type)
{
// this matches with the uorb o_fields generator
// this matches with the uorb type_map_short python data
switch (short_type) {
case 0x82: return "int8_t";
@@ -239,25 +240,29 @@ void orb_print_message_internal(const orb_metadata *meta, const void *data, bool
const uint8_t *data_ptr = (const uint8_t *)data;
int data_offset = 0;
for (int format_idx = 0; meta->o_fields[format_idx] != 0;) {
const char *end_field = strchr(meta->o_fields + format_idx, ';');
// Find message format
char format_buffer[128];
uORB::MessageFormatReader format_reader(format_buffer, sizeof(format_buffer));
if (!end_field) {
PX4_ERR("Format error in %s", meta->o_fields);
return;
}
if (!format_reader.readUntilFormat(meta->o_id)) {
PX4_ERR("Failed to get uorb format");
return;
}
const char *c_type = orb_get_c_type(meta->o_fields[format_idx]);
const int end_field_idx = end_field - meta->o_fields;
int field_length = 0;
while (format_reader.readNextField(field_length)) {
const char *c_type = orb_get_c_type(format_buffer[0]);
int array_idx = -1;
int field_name_idx = -1;
for (int field_idx = format_idx; field_idx != end_field_idx; ++field_idx) {
if (meta->o_fields[field_idx] == '[') {
for (int field_idx = 0; field_idx < field_length; ++field_idx) {
if (format_buffer[field_idx] == '[') {
array_idx = field_idx + 1;
} else if (meta->o_fields[field_idx] == ' ') {
} else if (format_buffer[field_idx] == ' ') {
field_name_idx = field_idx + 1;
break;
}
@@ -266,19 +271,10 @@ void orb_print_message_internal(const orb_metadata *meta, const void *data, bool
int array_size = 1;
if (array_idx >= 0) {
array_size = strtol(meta->o_fields + array_idx, nullptr, 10);
array_size = strtol(format_buffer + array_idx, nullptr, 10);
}
char field_name[80];
size_t field_name_len = end_field_idx - field_name_idx;
if (field_name_len >= sizeof(field_name)) {
PX4_ERR("field name too long %s (max: %u)", meta->o_fields, (unsigned)sizeof(field_name));
return;
}
memcpy(field_name, meta->o_fields + field_name_idx, field_name_len);
field_name[field_name_len] = '\0';
const char *field_name = format_buffer + field_name_idx;
if (c_type) { // built-in type
bool dont_print = false;
@@ -458,17 +454,10 @@ void orb_print_message_internal(const orb_metadata *meta, const void *data, bool
} else {
// extract the topic name
char topic_name[80];
const size_t topic_name_len = array_size > 1 ? array_idx - format_idx - 1 : field_name_idx - format_idx - 1;
if (topic_name_len >= sizeof(topic_name)) {
PX4_ERR("topic name too long in %s (max: %u)", meta->o_name, (unsigned)sizeof(topic_name));
return;
}
memcpy(topic_name, meta->o_fields + format_idx, topic_name_len);
topic_name[topic_name_len] = '\0';
// Get the topic name
const size_t topic_name_len = array_size > 1 ? array_idx - 1 : field_name_idx - 1;
format_buffer[topic_name_len] = '\0';
const char *topic_name = format_buffer;
// find the metadata
const orb_metadata *const *topics = orb_get_topics();
@@ -499,7 +488,5 @@ void orb_print_message_internal(const orb_metadata *meta, const void *data, bool
data_offset += found_topic->o_size;
}
}
format_idx = end_field_idx + 1;
}
}