Micro Property é um serializador de dados binários minimalista para sistemas embarcados. Parte 2

Há algum tempo, publiquei meu artigo sobre o desenvolvimento de uma bicicleta bicicleta, no qual descrevi os motivos que me levaram a fazer isso.



Em suma, eu precisava de uma biblioteca em miniatura para microcontroladores com um serializador de dados binários e a subsequente transmissão dessas mensagens por linhas de comunicação de baixa velocidade, enquanto os formatos usuais xml, json, bson, yaml, protobuf, Thrift, ASN.1, etc. não se encaixava por vários motivos.



Como era de se esperar, a solução acabou sendo mais do que uma bicicleta e, no entanto, a própria publicação do artigo sobre o Habré me ajudou muito. O fato é que durante a análise inicial de possíveis bibliotecas, por algum motivo, esqueci os serializadores MessagePack, CBOR e UBJSON.



Links para eles foram escritos para mim nos comentários após a publicação do artigo. E eu imediatamente percebi que provavelmente o CBOR , UBJSON pode resolver facilmente o problema antes de mim. E eles fazem isso muito melhor do que meu próprio desenvolvimento.



Depois disso, eu estraguei minha interface com a biblioteca CBOR (para não remover o código-fonte) e ... decidi abandonar este formato em favor do MessagePack :-)









CBOR vs. MessagePack



Na verdade, os formatos CBOR e MessagePack usam o mesmo princípio de serialização de dados. Eles são baseados em um método prático de escrever TLVs , com a única exceção de que na forma clássica, um TLV sempre contém um campo de tag e um campo de comprimento de dados. Mas o campo com os próprios dados pode estar ausente (se o tamanho dos dados for zero).



E nesses serializadores, os desenvolvedores foram ainda mais longe, e criaram formatos quase engenhosos nos quais a presença de um campo com o tamanho dos dados depende do tipo de dados e não é necessária para campos de tamanho fixo, e o primeiro byte armazena tanto o tipo de campo com o tamanho dos dados quanto seu imediato valor (é claro, se a profundidade de bits permitir).



No artigo original , eu escrevi sobre o fato de que preciso da compactação máxima de dados binários, e ambos os formatos lidam com essa tarefa com força. Eles são muito semelhantes entre si e diferem apenas no número de bits em que os valores do tipo de campo são armazenados.



No formato CBOR, a sobrecarga mínima de armazenamento para cada campo é de três bits, ou seja, no primeiro byte de cada campo, os três primeiros bits são responsáveis ​​pelo tipo de conteúdo e, dependendo disso, são interpretados a presença e o tamanho dos outros campos, podendo os 5 bits restantes já conter o próprio valor do campo.



Mas no MessagePack eles foram ainda mais longe! Neste formato, a sobrecarga mínima de armazenamento para um valor é apenas 1 (UM!)bit de informação. Consequentemente, 7 bits podem ser usados ​​para armazenar informações adicionais e os valores com o conjunto de bits mais significativo são usados ​​para indicar informações adicionais sobre o tipo de campo.



É claro que o intervalo de representação de valores negativos com este método de codificação é reduzido devido aos números positivos (apenas 32 números negativos podem ser armazenados em um byte, e os outros valores exigirão o segundo byte). Mas este é o desequilíbrio correto e está na direção certa, porque na prática, os números positivos são usados ​​com muito mais frequência do que os negativos.



Em outras palavras, um byte no formato CBOR pode acomodar valores inteiros de 0 a 23 e no formato MessagePack de 0 a 127!



Foi esse momento, além de uma biblioteca normal com a implementação do formato em uma dezena de idiomas diferentes, que determinou minha escolha final pelo formato MessagePack. Acho que não sou o único que pode estar interessado nesses detalhes da implementação desses formatos, então acho que é certo compartilhar essas informações.



Como resultado, o formato original do serializador ficou ainda mais compacto, inclusive devido a algumas convenções (por exemplo, a estrutura dos dados codificados deve ser limitada apenas a uma lista plana e recusa de usar tipos não reclamados), e meu sono tornou-se mais calmo, porque deixou de ser uma dor de cabeça sobre a compatibilidade ao nível dos formatos de mensagens encaminhadas entre dispositivos.

Muito obrigado aos usuários Habra Spym e edo1hque respondeu a um post anterior e assim ajudou a encontrar uma solução para um problema realmente sério com tão pouco esforço!

Fontes primárias:



Especificação CBOR . Existe um bom artigo com uma descrição sobre Habré .



A especificação MessagePack é muito fácil de ler na documentação e não requer nenhuma tradução ou explicação adicional.



All Articles