Bit Shifting, Masking ou une structure de champ de bits?

Je suis nouveau à travailler avec des bits. J’essaie de travailler avec un protocole existant, qui peut envoyer trois types de messages différents.

Le type 1 est une structure 16 bits:

struct digital { unsigned int type:2; unsigned int highlow:1; unsigned int sig1:5; unsigned int :1; unsigned int sig2:7; }; 

Les deux premiers bits (type, dans ma structure ci-dessus) sont toujours 1 0. Le troisième bit, highlow, détermine si le signal est activé ou non, et sig1 + sig2 définissent ensemble l’index de 12 bits du signal. Cet index est divisé sur les deux octets par un 0, toujours dans le bit 7.

Le type 2 est une structure 32 bits. Il a un type à 2 bits, un index à 10 bits et une valeur à 16 bits, entrecoupés de 0 aux positions 27, 23, 15 et 7. Une représentation de structure de champ de bits aimerait quelque chose comme ceci:

 struct analog { unsigned int type:2; unsigned int val1:2; unsigned int :1; unsigned int sig1:3; unsigned int :1; unsigned int sig2:7; unsigned int :1; unsigned int val2:7; unsigned int :1; unsigned int val3:7; }; 

sig1 et sig2 forment ensemble l’index 10 bits. val1 + val2 + val3 forment ensemble la valeur à 16 bits du signal à l’index à 10 bits.

Si je comprends comment travailler avec les deux premières structures, je pense pouvoir comprendre la troisième.

Ma question est la suivante: existe-t-il un moyen d’atsortingbuer une valeur unique et de laisser le programme définir les bits devant entrer dans val1, val2 et val3?

J’ai lu des articles sur le décalage de bits, les structures de champs de bits et le remplissage avec des 0. La structure semble être la voie à suivre, mais je ne sais pas comment la mettre en œuvre. Aucun des exemples d’emballages de bits que j’ai vus ne comporte de valeurs divisées. En fin de compte, j’aimerais pouvoir créer une structure analogique, assigner un index (i = 252) et une valeur (v = 32768) et en finir.

Si quelqu’un pouvait suggérer la méthode appropriée ou fournir un lien vers un échantillon similaire, je l’apprécierais grandement. Si cela compte, ce code sera intégré à une application Objective-C plus grande.

Merci.

Brad

Vous pouvez le faire avec une série de quarts de travail, and s, et or s. J’ai fait la partie index 10 bits pour le type 2:

 unsigned int i = 252; analog a = (analog)(((i << 16) & 0x7f0000) | (i << 17) & 0x7000000); 

Ce code fait essentiellement passer les 10 bits d’intérêt d’ int i dans la plage 0x7f0000 , puis le masque de 0x7f0000 fixe les bits 22 à 31 à zéro. Il décale également une autre copie des 10 bits de la plage 17 - 26, puis c’est avec le masque 0x7000000 de définir les bits 0 à 22 et 26 à 31 à zéro. Ensuite, les deux valeurs sont combinées pour créer la valeur souhaitée séparée par zéro.

.. Je ne suis pas absolument sûr d'avoir correctement compté les bitmasks, mais j'espère que vous avez eu l'idée. Il suffit de déplacer, masquer et fusionner.

Edit: Méthode 2:

 analog a; a.sig1 = (i & 0x7f); // mask out bit 8 onwards a.sig2 = ((i<<1) & 0x700); // shift left by one, then mask out bits 0-8 

À la reflection, la méthode 2 est plus lisible, vous devriez donc probablement l’utiliser.

Vous ne devez pas utiliser de champs de bits de structure C, car la disposition physique des champs de bits n’est pas définie. Bien que vous puissiez comprendre ce que fait votre compilateur et faire en sorte que votre présentation corresponde aux données sous-jacentes, le code risque de ne pas fonctionner si vous passez à un autre compilateur ou même mettez à jour votre compilateur.

Je sais que c’est pénible, mais faites la manipulation vous-même.

Ce n’est pas nécessaire, c’est là que le mot clé union entre: vous pouvez spécifier tous les bits en même temps, ou en faisant référence aux mêmes bits avec un nom différent, définissez-les tous en même temps.