Ca, c'est n'importe quoi...Envoyé par EmcyThierryEnvoyé par K&R2, section 6.9
Ca, c'est n'importe quoi...Envoyé par EmcyThierryEnvoyé par K&R2, section 6.9
"The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
"If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow
FAQ-Python FAQ-C FAQ-C++
+
Je viens de me rendre compte que Priority vaut 3 bit => donc c'est plus la peine de chercher à passer sur 3 bytes
avec cette methode :
=> j'ai l'erreur suivante : Error [1171] bitfield width greater than 8 detected => ça doit etre normale vu que ce ne sont pas des int...que faire alors ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 typedef struct _StructVLAN { unsigned long Enb:1; unsigned long ID:12; unsigned long Priority:3; unsigned long Member:5; unsigned long Tagged:5; unsigned long NU:6; // bits non utilisés } StructVLAN; extern StructVLAN TabVLAN_Filter[16];
Bon voici un exemple (lecture seulement) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148 #include "stdlib.h" /* ---------------------------------------------------------------------- ---------------------------------------------------------------------- This routine reads any number of bits starting at any adress within a byte and outputs it as an 32-bits integer. It's the basic stone of the GRIB format decoding. ---------------------------------------------------------------------- ---------------------------------------------------------------------- */ void Grib_Get_Bits_From_Bytes ( char *Message, int *Stockage, int Adresse, int Nbits ) { int I_Depart, I_Origine, I_End ; int N_Car, I_Equiv, I, J, I_Start, Ko, K1 ; char Buffer ; /* --- Gets the starting bit, and the number of bytes to be read */ I_Depart = Adresse / 8 ; I_Origine = Adresse - I_Depart*8 ; if ( Nbits > 8 ) N_Car = 1 + (Nbits-1)/8 ; else if ( (I_Origine+Nbits) > 8 ) N_Car = 2 ; else N_Car = 1 ; /* --- Gets the number of bits to be read in the last byte */ Ko = 8 ; /* Correction JS 28/06/2000 : incorrect formula */ if ( (Nbits/8)*8 != Nbits ) /* Nbits modulo 8 != 0 */ { if ( N_Car > 1 ) Ko = 8 - (8*N_Car - (I_Origine + Nbits)) ; else Ko = I_Origine+Nbits ; } I_Equiv = 0 ; /* --- If there are several bits to be retrieved */ if ( Nbits != 1 ) { /* Reads them and stores them at the right place relative to weights */ for ( I = 1 ; I <= N_Car ; I++ ) { Buffer = *(Message+I_Depart+I-1) ; if ( (I == 1) && (I_Origine != 0) ) I_Start = I_Origine ; else I_Start = 0 ; if ( ( I == N_Car) && (Ko != 8) ) I_End = Ko ; else I_End = 8 ; for ( J = I_Start ; J < I_End ; J++ ) { if ( getbitbyte(&Buffer, 7-J) == 1 ) { setbit ( &I_Equiv, (7-J)+(N_Car-I)*8 ); } } } /* If we are not finishing on byte boundary, resets the end of the byte */ if ( Ko != 8 ) { J = I_Equiv ; I_Equiv = 0 ; for ( I = Ko ; I < (8*sizeof(int)) ; I++ ) { K1 = getbit ( &J, I ); if ( K1 == 1 ) setbit ( &I_Equiv, (I-Ko) ); } } } /* --- If only one bit to retrieve */ else { Buffer = *(Message+I_Depart); if ( getbitbyte ( &Buffer, 7-I_Origine ) == 1 ) setbit ( &I_Equiv, 0 ) ; } *Stockage = I_Equiv ; } /* ---------------------------------------------------------------------- Gets bit # Numero in integer Entier ---------------------------------------------------------------------- */ int getbit ( int *Entier, int Numero ) { return ((*Entier >> Numero) & ~(~0 << 1)) ; } /* ---------------------------------------------------------------------- Gets bit # Numero in byte Byte ---------------------------------------------------------------------- */ int getbitbyte ( char *Byte, int Numero ) { return ((*Byte >> (Numero)) & ~(~0 << 1)) ; } /* ---------------------------------------------------------------------- Sets bit # Numero in integer Entier ---------------------------------------------------------------------- */ void setbit ( int *Entier, int Numero ) { *Entier = *Entier | (1 << Numero) ; }
Avec un exemple d'utilisation :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 Adr = 0 ; Grib_Get_Bits_From_Bytes ( Message, &Struct->Ni, Adr, 16 ) ; Grib_Get_Bits_From_Bytes ( Message, &Struct->Nj, Adr+16, 16 ); Grib_Get_Bits_From_Bytes ( Message, &Struct->Hemisphere_1, Adr+32, 1 ); Grib_Get_Bits_From_Bytes ( Message, &Struct->Lat_1, Adr+33, 23 ) ; .... Grib_Get_Bits_From_Bytes ( Message, &Struct->Hemisphere_Of_South_Pole, Adr, 1 ) ; Grib_Get_Bits_From_Bytes ( Message, &Struct->Lat_South_Pole, Adr+1, 23 ) ;
"Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".
Consultant indépendant.
Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
C, Fortran, XWindow/Motif, Java
Je ne réponds pas aux MP techniques
Ca fonctionne chez moi (Windows), mais peut-être que votre système cible ne supporte pas des champs de bits de taille supérieure à celle de l'octet. Dans ce cas, vous pouvez considérer le tableau suivant:Envoyé par Emcy
et utiliser des opérations sur les bits pour manipuler le contenu (AND, OR, décalages...)
Code : Sélectionner tout - Visualiser dans une fenêtre à part char tabvlan[4];
souviron34, il me semble que ta solution est un peut lourde => ça consomme pas mal de temps de cycle, non ?
sinon, il y a cette methode qui à l'air de fonctionner :
Pour ecrire dans une variable, il faut que je fasse comme ça ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 typedef struct _StructA { unsigned int Enb:1; unsigned int Member:5; unsigned long NU:2; // bits non utilisés } StructA; typedef struct _StructB { unsigned int Priority:3; unsigned int Tagged:5; } StructB; typedef struct _StructVLAN { StructA A; StructB B; unsigned int ID; } StructVLAN; extern StructVLAN TabVLAN_Filter[16];
et pour lire, c'est comme ça ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 unsigned char toto; toto = 1; // ou 0 TabVLAN_Filter[16].A.Enb = toto;
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 unsigned char toto; toto = TabVLAN_Filter[16].A.Enb;
A part l'indice qui doit être inférieur strictement à 16, ça me semble correct.Envoyé par Emcy
je répond juste à la question initiale : comment coder 5 champs dont des flags et des entier (dont le max est 5 bits) sur le moins de bits possibles...
Et je donne l'exemple qui permet de coder des chaînes, des entiers, des caractères, des double, sur le moins de bits possibles c'est tout...
Ta struct A prend 2 entiers et un long....
M'enfin c'est vous qui voyez.....
"Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".
Consultant indépendant.
Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
C, Fortran, XWindow/Motif, Java
Je ne réponds pas aux MP techniques
Si l'on va dans ce sens, on peut aussi se demander s'il est pertinent de stocker les deux entiers Member et Tagged sous forme ASCII dans la structure...
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
Champs de bits :Envoyé par Emcy
http://emmanuel-delahaye.developpez....s.htm#bitfield
Chaque élément de devrait pas occuper plus de 32 bits.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 typedef struct { unsigned Enb:1; //bool 1 ou 0 unsigned ID:12; // chiffre écrit en binaire entre 0 et 4095 unsigned Priority:1; //bool 1 ou 0 unsigned Member:5; // chiffre écrit en binaire sur 5bits unsigned Tagged:5; // chiffre écrit en binaire sur 5bits } StructVLAN; extern StructVLAN TabVLAN_Filter[16];
L'accès est un peu plus lent et le code généré un peu plus gros. Il faut voir ce que tu gagnes vraiment.
De toutes façons, tu as intérêt à stocker les données numériques en binaire plutôt qu'en texte.
Pas de Wi-Fi à la maison : CPL
et enfin , même si c'est correct, 1) ça ne marche qu'avec des int, et 2) ce n'est pas défini comme portable (big endian vs little endian)...
"Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".
Consultant indépendant.
Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
C, Fortran, XWindow/Motif, Java
Je ne réponds pas aux MP techniques
Pas vraiment, je trouve 5 octets (sans doute un long plus un byte). En revanche, si on note partout unsigned int (pas de long), au final la taille est un octet.Envoyé par souviron34
Non.Envoyé par Emcy
http://emmanuel-delahaye.developpez....s.htm#bitfield
Pas de Wi-Fi à la maison : CPL
Quelle importance pour des données internes ?Envoyé par souviron34
Pas de Wi-Fi à la maison : CPL
tu as raison
.. je vais encore reflechir u peu pour la solution a adopter
merci pour votre aide
Je pense qu'il n'y a plus trop à réfléchir, à moins de faire une usine à gaz pour utiliser un tableau de 3 bytes dont les 24 bits sont manipulés à la main... (en supposant que tes bytes fassent 8-bit, ce qui n'est pas démontré, vu que tu n'as pas indiqué quelle était ta plateforme).Envoyé par Emcy
Pas de Wi-Fi à la maison : CPL
je ne comprend pas, j'enregistre mon tableau dans une EEPROM puis je vais récupérer les valeur et les valeurs ont changées
ma structure :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80 // ******** structure VLAN Filter ******************** typedef struct _StructA { unsigned int Enb:1; unsigned int Member:5; unsigned int NU:2; // bits non utilisés } StructA; typedef struct _StructB { unsigned int Priority:3; unsigned int Tagged:5; } StructB; typedef struct _StructVLAN { unsigned int ID; StructA A; StructB B; } StructVLAN; extern StructVLAN TabVLAN_Filter[16]; // *************************************************** void Init_TabVLAN_Filter(void) { const StructVLAN varInit; unsigned char i; varInit.ID = 4095; varInit.A.Enb = 0; varInit.A.Member = 0x15; varInit.B.Tagged = 0x0A; varInit.B.Priority = 7; for ( i = 0; i < 16; i++ ){ TabVLAN_Filter[i] = varInit; } EtatTabVLAN_Filter(); } void EtatTabVLAN_Filter(void) // fonction pour debug { unsigned char i, j; unsigned char tmp; USARTComment("\n\r*********** Etat de TabVLAN_Filter ***********"); for ( i = 0; i < 16; i++ ){ USARTComment("\n\r=>VLAN "); itoa(i, chaine_debug); USARTPutString((BYTE*)chaine_debug); USARTComment(" --> "); USARTComment("\n\r Enb : "); //tmp = TabVLAN_Filter[i].A.Enb; //itoa(tmp, chaine_debug); itoa(TabVLAN_Filter[i].A.Enb, chaine_debug); USARTPutString((BYTE*)chaine_debug); USARTComment("\n\r ID : "); itoa(TabVLAN_Filter[i].ID, chaine_debug); USARTPutString((BYTE*)chaine_debug); USARTComment("\n\r Priority : "); itoa(TabVLAN_Filter[i].B.Priority, chaine_debug); USARTPutString((BYTE*)chaine_debug); USARTComment("\n\r Member : "); affichage_val_hexa(TabVLAN_Filter[i].A.Member, 4); USARTComment("\n\r Tagged : "); affichage_val_hexa(TabVLAN_Filter[i].B.Tagged, 4); USARTComment("\n\r"); } }
ma gestion de l'EEPROM :
=> a l'initialisation, les valeurs sont bonnes. Par contre, je ne sais pas si c'est à la lecture ou a l'ecriture de l'EEPROM qu'il y a le probleme...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85 #define EEPROM_OFFSET 0xC8 // (200) #define SIZE_Tab_varCu sizeof(Tab_varCu) #define SIZE_TabVLAN_Filter sizeof(TabVLAN_Filter) #define START_Tab_varCu (EEPROM_OFFSET) #define END_Tab_varCu (EEPROM_OFFSET + SIZE_Tab_varCu) #define START_TabVLAN_Filter (EEPROM_OFFSET + SIZE_Tab_varCu) #define END_TabVLAN_Filter (EEPROM_OFFSET + SIZE_Tab_varCu + SIZE_TabVLAN_Filter) // écriture dans l'EEPROM void SaveEEPROM_TabVLAN_Filter(void) { unsigned int c; char *p; USARTComment("\n\rSauvegarde TabVLAN_Filter\n\r"); //.USARTComment("\n\rAddr Start : "); //.affichage_val_hexa(START_TabVLAN_Filter, 4); //.USARTComment("\n\rAddr End : "); //.affichage_val_hexa(END_TabVLAN_Filter, 4); p = (char*)TabVLAN_Filter; for ( c = START_TabVLAN_Filter; c < END_TabVLAN_Filter; c++ ){ WriteEEPROM_PIC(c,*p++); } //.USARTComment("\n\r => Sauvegarde TabVLAN_Filter OK\n\r"); EtatTabVLAN_Filter(); } // chargement dans l'EEPROM void LoadEEPROM_TabVLAN_Filter(void) { unsigned int c; char *p; USARTComment("\n\rLit les variables de TabVLAN_Filter\n\r"); USARTComment("\n\rAddr Start : "); affichage_val_hexa(START_TabVLAN_Filter, 4); USARTComment("\n\rAddr End : "); affichage_val_hexa(END_TabVLAN_Filter, 4); p = (char*)TabVLAN_Filter; for ( c = START_TabVLAN_Filter; c < END_TabVLAN_Filter; c++ ){ *p = ReadEEPROM_PIC(c); p++; } //.USARTComment("\n\r => Lecture TabVLAN_Filter OK\n\r"); EtatTabVLAN_Filter(); } // écriture dans l'EEPROM void WriteEEPROM_PIC(unsigned char adr, unsigned char val) { unsigned char gie_save; // save etat GIE while(EECON1bits.WR); //on attend que l'ecriture precedente soit finie EEADR= adr; EEDATA= val; EECON1bits.EEPGD = 0; EECON1bits.CFGS = 0; EECON1bits.WREN = 1; // valide ecriture gie_save = INTCONbits.GIE; INTCONbits.GIE = 0; // devalid inter EECON2=0x55; EECON2=0xaa; EECON1bits.WR=1; INTCONbits.GIE = gie_save; EECON1bits.WREN = 0; // devalid ecriture } // lecture dans l'EEPROM unsigned char ReadEEPROM_PIC(unsigned char adr) { while(EECON1bits.WR); //on attend que l'ecriture precedente soit finie EEADR=adr; EECON1bits.EEPGD = 0; EECON1bits.CFGS = 0; EECON1bits.RD=1; return EEDATA; }
Le code posté est incomplet. Déjà il y a un problème ici :Envoyé par Emcy
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 void Init_TabVLAN_Filter (void) { /* -ed- const StructVLAN varInit; varInit.ID = 4095; varInit.A.Enb = 0; varInit.A.Member = 0x15; varInit.B.Tagged = 0x0A; varInit.B.Priority = 7; Pourquoi const ? Ou alors, il faut aller au bout du raisonnement... */ static const StructVLAN varInit = { 4095, /* ID */ { 0, /* A.Enb */ 0x15, /* A.Member */ }, { 7, /* B.Priority */ 0x0A, /* B.Tagged */ } }; unsigned char i; for (i = 0; i < 16; i++) { /* -ed- TabVLAN_Filter n'est pas défini... */ TabVLAN_Filter[i] = varInit; } EtatTabVLAN_Filter (); }
Pas de Wi-Fi à la maison : CPL
j'ai fait les modif, mais ça fait toujours pareil (lorsque je lance la fonction EtatTabVLAN_Filter à l'initialisation de la variable TabVLAN_Filter, les bonnes valeurs s'affichent mais après ecriture et lecture de l'EEPROM, ça ne marche plus correctement.
TabVLAN_Filter est declaré comme variable global comme ceci :
StructVLAN TabVLAN_Filter[16];
=> qu'elles parties te manque t-il ?Le code posté est incomplet
je viens de voir que le probleme ne vient pas de la car j'ai essayé de lancer une lecture dans l'EPROM juste après une ecriture dans l'EEPROM et j'ai bien les bonnes valeurs qui s'affichent => je vais chercher ailleur...
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager