Je suis actuellement entrain de faire un petit programme pour envoyer un paquet série. J'ai représenter mon paquet avec une structure. Voici mon code pour le moment
Pour chaque attribut de mon paquet je spécifie la taille en octet de l'attribut. Mais quand je compile actuellement j'obtiens ces messages: warning: conversion from 'uint8_t' {aka 'unsigned char'} to 'unsigned char:1' changes value from '126' to '0' [-Woverflow]
warning: conversion from 'uint8_t' {aka 'unsigned char'} to 'unsigned char:3' changes value from '108' to '4' [-Woverflow]
Je ne comprend pas pourquoi est-ce que je fait quelque chose de mal? Ma méthode n'est pas la bonne ? Pourquoi est-ce que j'ai un overflow alors que mes valeurs sont bonnes pour les padding associé.
On voit assez rarement ce genre de syntaxe, je l'ai utilisée une seule fois.
De mémoire, ça veut dire que tu vas coder synchro sur un bit et identifiant sur 3 bits.
Là, tu passes la valeur la valeur 0x7E qui vaut 126 en décimal et 1111110 en binaire. Mais tu as spécifié que tu ne voulais qu'un seul bit pour cette variable, donc il conserve le dernier uniquement, soit 0.
C'est ce qui est expliqué ici.
De même, lorsque tu passes 0x6C à identifiant, il conserve les 3 derniers bits soit 100, c'est à dire 4. Ce qui est indiqué dans le second warning.
J'ai une question qui me taraude, sachant que du côté du récepteur dans la doc il est spécifié que identifiant doit avoir un format de 3 octets, non signé valeur acceptable [0, 999 999], quel est la version la plus judicieuse à utiliser ?
uint32_t identifiant : 24; // 3 octets
ou
uint32_t identifiant; // 4 octets
ou alors quelque chose du genre ?
uint8_t[3] identifiant;
identifiant[0] = (n >> 16) & 0xFF; // n étant la valeur à enoyer
identifiant[1] = (n >> 8) & 0xFF;
identifiant[2] = (n >> 0) & 0xFF;
Si vous avez une trame binaire avec un format bien défini il faut utiliser attribute packed et les champs de bits pour vraiment avoir 3 octets. Avec GCC ca devrait suffire pour conserver la cohérence de la structure
Le tableau d’octets fonctionne aussi et est plus portable mais un peu plus cassé pied à utiliser. Il faudrait aussi savoir si votre entier sur 3 octets est en little endian ou big endian
Juste par curiosité est ce vraiment un format binaire ou alors c’est de l’ASCII qu’il faut mettre (3 octets pour « 000 » à « 999 » ça semble logique parce que sinon 2 octets auraient suffit pour un nombre entre 0 et 999
Effectivement oui c'est du little endian en plus du coup mon exemple est faux je crois, il devrait être
identifiant[0] = (n >> 0) & 0xFF; // n étant la valeur à envoyer
identifiant[1] = (n >> 8) & 0xFF;
identifiant[2] = (n >> 16) & 0xFF;
Mon champ identifiant est bien un champ de 3 octets pour pouvoir stocker des valeurs allant de 0 à 999999. Du coup j'utilise la méthode * attribute packed* et les champs de bits