Go Down

Topic: Conosci i bitfield? (Read 691 times) previous topic - next topic

MauroTec

Spesso si scrive codice di impulso, basta distrarsi un'attimo per costatare che ti sei fatto fuori più del 50% di RAM, e ancora hai da scrivere tanto codice. C'è un modo per fare economia di ram ( ce ne sono tanti, e alcuni non li conosco neanche io ), uno di questi sono i campi di bit.

I campi di bit sono delle strutture (struct) che hanno come membri una variabile con dimensione specificata.
La struttura è comoda perchè la puoi passare ad una funzione attraverso il suo puntatore senza spreco di risorse CPU (inteso come cicli di clock spesi). Il bello che la struttura può contenere altre strutture fino ad occupare una gran quantità di ram, ma usata bene.

Es:
Code: [Select]

struct StateMachine {
    unsigned int IN_progess:1;
    unsigned int IN_pause:1;
    unsigned int IN_poweron:1;
    unsigned int IN_resume:1;
} machine;


La struttura occupa 4 bit, e posso modificare il loro stato così:

Code: [Select]

machine.IN_progress = false;
machine.IN_pause = false;
machine.IN_poweron = true;
machine.IN_resume = false;


Ovviamente il numero dopo il ":" specifica la dimensione del campo di bit.
Se voglio  che resume sia grande 4 bit scrivero: unsigned int IN_resume:4;

Spero possa tornare utile a chi è a corto di ram.

Ciao.





AvrDudeQui front end per avrdude https://gitorious.org/avrdudequi/pages/Home

lesto

ottimo, non sapevo che si potessero dimensionare delle variabili in bit! farò tesoro del suggerimento!
ma i : si devono usare per forza all'interno di una struct?
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Stefanoxjx


ottimo, non sapevo che si potessero dimensionare delle variabili in bit! farò tesoro del suggerimento!
ma i : si devono usare per forza all'interno di una struct?


Nooooooooooooo non ci credo!!!!
Lesto che non sa una cosa sul C  :smiley-eek-blue:

Comunque, scherzi a parte, grazie a Mauro della chicca.
Lo sapevo che si poteva fare, però l'avevo studiato moooooooooooolti anni fa in qualche libro di C e onestamente
avendo rispolverato il C di recente me ne ero anche dimenticato  :smiley-roll-blue:
www.multiwii.it
www.sdmodel.it

lesto


Nooooooooooooo non ci credo!!!!
Lesto che non sa una cosa sul C  :smiley-eek-blue:


il mio linguaggio di punta è il java  :smiley-mr-green:
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

flz47655

Ma non potevi semplicemente usare dei boolean come tipi?

alexdb


Ma non potevi semplicemente usare dei boolean come tipi?


i boolean sono salvati come un intero, e quindi occupano mooolto più spazio :)

flz47655

E' vero, però occupano un solo byte. Ho visto che ci sono le funzioni BitRead, BitWrite, etc.. per lavorare sui byte ma la tua soluzione sembra interessante e pulita.

Ciao

alexdb


E' vero, però occupano un solo byte.

appunto :) con i campi bit puoi far stare 8 valori booleani in un solo intero, con un boolean "normale" in un byte ci sta solo un valore booleano...
Quote

Ho visto che ci sono le funzioni BitRead, BitWrite, etc.. per lavorare sui byte ma la tua soluzione sembra interessante e pulita.

Ciao

si è molto più pulita e veloce, perchè non devi chiamare funzioni, ma utilizzi solo caratteristiche del C...

MauroTec

Quote
Lo sapevo che si poteva fare, però l'avevo studiato moooooooooooolti anni fa in qualche libro di C e onestamente
avendo rispolverato il C di recente me ne ero anche dimenticato  smiley-roll-blue

Sono di quelle cose che studi ma consideri di poca importanza, anche perché sul pc ordierni di ram c'è a iosa, ma qui la ram scarsegia e lo sketch non gallegia :P.

Quote
ottimo, non sapevo che si potessero dimensionare delle variabili in bit! farò tesoro del suggerimento!
ma i : si devono usare per forza all'interno di una struct?


Ho cercato un tipo di dato bit e non l'ho trovato, so che altri compilatori hanno questi tipo ma avr-gcc no.

Quindi deve essere un membro di una struttura, del resto è pure comodo mettere insieme dei flag nella stessa struttura anziché una decina o più variabili sparse a destra e a manca.

Si può anche usare come variabile di ritorno per le funzioni, e non ci dovrebbe essere consumo di clicli cpu quando fa la copia di ritorno perché in effetti deve compiare solo i membri che se sono 8 è come ritornare un byte.

La struttura si può anche inizializzare così
struct lcdpin {
    db0:1;
    db1:1;
    db2:1;
    db3:1;
} lcdport  { 0,0,0,0 };

Quote
E' vero, però occupano un solo byte. Ho visto che ci sono le funzioni BitRead, BitWrite, etc.. per lavorare sui byte ma la tua soluzione sembra interessante e pulita.


Non conosco queste funzioni, probabile siano delle macro ed in tal caso sono rapide in esecuzione più delle funzioni.


AvrDudeQui front end per avrdude https://gitorious.org/avrdudequi/pages/Home

hreplo



La struttura occupa 4 bit, e posso modificare il loro stato così:




in realtà l'occupazione è sempre uno o due bytes a seconda del bitfield, se unsigned char o unsigned int che definisci nella struct. i bit non usati vanno persi per l'allineamento della memoria.

poi i boolean occupano solo una locazione (1 byte) in quanto char e NON int (2 byte).

bye

flz47655

Però è possibile creare una struttura unica ed inserire molti stati per "minimizzare la perdita", meno di un byte il compilatore evidentemente non può riservare per una variabile (lo dico senza aver letto il datsheet però)

Ciao

Tobo

Ma...tutta la struttura occupa uno o due byte, oppure è l'occupazione per ogni variabile all'interno della struttura?
Mom: Can he lead a normal life?
Doctor: NO! he'll be an engineer!

lesto

la struttura occupa spazio per multipli di 8, ma può contenere variabili che occupano un solo bit.

Dicaimo che così diventa più semplice l'algebra del bitshift
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

MauroTec

Quote
in realtà l'occupazione è sempre uno o due bytes a seconda del bitfield, se unsigned char o unsigned int che definisci nella struct. i bit non usati vanno persi per l'allineamento della memoria.


Esatto, ho dimenticato di scriverlo. Ho dato per scontato ciò che non lo è.

Se si ha bisogno di 8 campi di bit da 1 bit ciscuno, conviene usare "unsigned char" o "uint8_t".

Il paragone con un bool non regge, 8 campi di bit da 1 bit, sono un byte, mentre 8 bool sono 8 byte.

Ciao.
AvrDudeQui front end per avrdude https://gitorious.org/avrdudequi/pages/Home

Go Up