Micro Property est un sérialiseur de données binaires minimaliste pour les systèmes embarqués. Partie 2

Il y a quelque temps, j'ai publié mon article sur le développement d'un vélo de vélo, dans lequel je décrivais les raisons qui m'ont poussé à le faire.



En bref, j'avais besoin d'une bibliothèque miniature pour microcontrôleurs avec un sérialiseur de données binaires et la transmission ultérieure de ces messages sur des lignes de communication à bas débit, alors que les formats habituels xml, json, bson, yaml, protobuf, Thrift, ASN.1, etc. ne correspondait pas pour diverses raisons.



Comme prévu, la solution s'est avérée être plus qu'un vélo, et pourtant, la publication même de l'article sur Habré m'a beaucoup aidé. Le fait est que lors de l'analyse initiale des bibliothèques possibles, pour une raison quelconque, j'ai négligé les sérialiseurs MessagePack, CBOR et UBJSON.



Des liens vers eux m'ont été écrits dans les commentaires après la publication de l'article. Et je me suis immédiatement rendu compte que très probablement CBOR , UBJSON pouvait facilement résoudre le problème devant moi. Et ils le font bien mieux que mon propre développement.



Après cela, j'ai vissé mon interface à la bibliothèque CBOR (pour ne pas pelleter le code source), et ... j'ai décidé d'abandonner ce format au profit de MessagePack :-)









CBOR c. MessagePack



En fait , les formats CBOR et MessagePack utilisent le même principe de sérialisation des données. Ils sont basés sur une méthode pratique d'écriture des TLV , à la seule exception que dans la forme classique, un TLV contient toujours un champ de balise et un champ de longueur de données. Mais le champ contenant les données proprement dites peut être absent (si la taille des données est égale à zéro).



Et dans ces sérialiseurs, les développeurs sont allés encore plus loin et ont créé des formats presque ingénieux dans lesquels la présence d'un champ avec une taille de données dépend du type de données et n'est pas requise pour les champs de taille fixe, et le premier octet stocke à la fois le type de champ avec la taille des données et son immédiat value (bien sûr, si la profondeur de bits le permet).



Dans l' article original , j'ai écrit sur le fait que j'ai besoin du maximum de données binaires, et ces deux formats font face à cette tâche avec un bang. Ils sont très similaires les uns aux autres et ne diffèrent que par le nombre de bits dans lesquels les valeurs de type de champ sont stockées.



Au format CBOR, la surcharge de stockage minimale pour chaque champ est de trois bits, c'est-à-dire dans le premier octet de chaque champ, les trois premiers bits sont responsables du type de contenu, et en fonction de celui-ci, la présence et la taille des autres champs sont interprétées, et les 5 bits restants peuvent déjà contenir la valeur du champ elle-même.



Mais dans MessagePack, ils sont allés encore plus loin! Dans ce format, la surcharge de stockage minimale pour une valeur n'est que de 1 (UN!)peu d'informations. En conséquence, 7 bits peuvent être utilisés pour stocker des informations supplémentaires, et des valeurs avec l'ensemble de bits le plus significatif sont utilisées pour indiquer des informations supplémentaires sur le type de champ.



Il est clair que la plage de représentation des valeurs négatives avec cette méthode de codage est réduite en raison des nombres positifs (seuls 32 nombres négatifs peuvent être stockés dans un octet, et les autres valeurs nécessiteront le deuxième octet). Mais c'est le bon déséquilibre et il est déplacé dans la bonne direction, car dans la pratique, les nombres positifs sont beaucoup plus souvent utilisés que les nombres négatifs.



En d'autres termes, un octet au format CBOR peut accueillir des valeurs entières de 0 à 23, et au format MessagePack de 0 à 127!



C'est ce moment, ainsi qu'une bibliothèque normale avec l'implémentation du format dans une douzaine de langues différentes, qui ont déterminé mon choix final en faveur du format MessagePack. Je pense que je ne suis pas le seul à être intéressé par ces détails de la mise en œuvre de ces formats, donc je pense qu'il est juste de partager cette information.



En conséquence, le format d'origine du sérialiseur a été rendu encore plus compact, notamment en raison de certaines conventions (par exemple, la structure des données encodées devrait être limitée uniquement à une liste plate et le refus d'utiliser des types non réclamés), et mon sommeil est devenu plus calme, car plus un casse-tête sur la compatibilité au niveau des formats de messages transmis entre appareils.

Un grand merci aux utilisateurs Habra Espion et edo1hqui a répondu à un article précédent et ainsi aidé à trouver une solution à un problème vraiment sérieux avec si peu d'effort!

Sources primaires:



Spécification CBOR . Il y a un bon article avec une description sur Habré .



La spécification MessagePack est très facile à lire dans la documentation et ne nécessite aucune traduction ou explication supplémentaire.



All Articles