2012-11-02 4 views
5

Ich möchte einige Bits eines Registers direkt mit seiner physikalischen Adresse manipulieren. Jedoch konnte ich keinen Weg finden, dies zu machen. Ich habe ein paar Posts zum Setzen von Bitmasken gesehen, aber ich finde sie zu verwirrend.Wie ändere ich eine 32bit Register spezifische Bits, ohne andere Bits zu ändern?

Meine Register physikalische Adresse ist: 0x4A10005C

ich seine Bit manipulieren wollen, die zwischen 18-16 Bits war. Ich möchte 0x3 innerhalb dieser Bits setzen.

Ich werde wirklich froh sein, wenn Sie eine Antwort oder eine Möglichkeit geben können, es zu tun. Vielen Dank.

+0

ohne zu verstehen, wie Bit-Operationen funktionieren und so etwas wie Bit-Masken könnte es wirklich schwierig sein, Bits zu manipulieren ... – codewarrior

+0

Was ist verwirrend über Bit-Masken für Sie? – Mike

+0

Es gibt 2 Möglichkeiten, um auf Bit-Level-Informationen BITWISE-Operatoren und Bitwise-Struktur in c –

Antwort

5

Sie können einen Zeiger auf das Register nur definieren und dann normale C bitweise Operationen verwenden, um die einzelnen Bits zu manipulieren:

volatile uint32_t * const my_register = (uint32_t *) 0x4A10005C; 
           // set up a pointer to the register 

uint32_t val = *my_register; // read register 

val &= ~(0x7 << 16);   // clear bits 16..18 

val |= (0x3 << 16);   // set bits 16..18 to 0x03 (i.e. set bits 16 and 17) 

*my_register = val;   // write register 

(Das setzt voraus, oben, dass Sie über drei Bits innerhalb des Registers sprechen, 16 Bits , 17 und 18, und dass Sie Bit 18 auf Null gesetzt werden sollen und die Bits 16 und 17 bis 1.)

+1

zuzugreifen. Man sollte diese Bits auch mit '& ~ (Maske) löschen, sonst wird es nicht immer funktionieren, außer für All-Bits-Set-to-One Werte wie '0x7'. Was es 18 gebissen hat, war "1"? –

+0

@Hristo: danke - ich denke, dass Sie meine frühere Bearbeitung verpasst haben. –

+0

Yup, es war wie Datenrennen Bedingung :) –

0
structure r32 { 
unsigned int bit0 :1; 
unsigned int bit1 :1; 
unsigned int bit2 :1; 
unsigned int bit3 :1; 
unsigned int bit4 :1; 
unsigned int bit5 :1; 
. 
. 
. 
unsigned int bit31 :1; 
} 

in der Haupt

structure r32 *p; 
volatile uint32_t * const my_register = (uint32_t *) 0x4A10005C; 

p = (structure r32 *) my_register; 

und dann zu Bit 5 zum Beispiel den Zugriff auf

p->bit4 = 0; 
+1

Obwohl dies in den meisten Fällen funktionieren mag (vorausgesetzt, dass die Reihenfolge der Bits korrekt ist, was es nicht sein mag), gibt es keine Garantien über die Anordnung oder Platzierung von Bitfeldern in C. –

5

Bitmasken sind ziemlich einfach so lassen Sie uns durch diese erste laufen zu verstehen:

Lassen Sie sagen, Ihr 32-Bit-Register enthält einen Wert jetzt werde ich willkürlich 0xF48C6219 Pick

ich nehme an, Sie wissen, wie hex in das Binärformat zu konvertieren, wenn nicht ... sagen wir einfach, einen Rechner oder google verwenden (anstatt gehen in die nitty gritty, dass auch). So kann unser Hex-Wert binär dargestellt werden als:

+-- bit 31       +-- bit 0 
|          | 
v          v 
1111 0100 1000 1100 0110 0010 0001 1001 
       ^^      
       | | 
       +-+-- bits you want to set, 16-18 

Boolesche Logik sagt uns, dass:
1) etwas ODER-Verknüpfung (|) mit 1 gibt Ihnen einen Wert von 1. Oder "setzt" das Bit.
2) alles AND'd (&) mit 0 gibt Ihnen einen Wert von 0. Oder "löscht" das Bit.

Wenn wir also Bits 16-18 möglich räumen wollten und mit einer Maske wie:

Basisnummer: 1111 0100 1000 1100 0110 0010 0001 1001 == 0xF48C6219
Maske Nummer: 1111 1111 1111 1000 1111 1111 1111 1111 == 0xFFF8FFF

1111 0100 1000 1100 0110 0010 0001 1001 
& 1111 1111 1111 1000 1111 1111 1111 1111 
------------------------------------------ 
    1111 0100 1000 1000 0110 0010 0001 1001 

Jetzt Sie oder ihn mit dem, was Sie dort setzen:

neuer Maske Nummer: 0000 0000 0011 0000 0000 0000 0000 0000 == 0x00030000

1111 0100 1000 1000 0110 0010 0001 1001 
| 0000 0000 0000 0011 0000 0000 0000 0000 
----------------------------------------- 
    1111 0100 1000 1011 0110 0010 0001 1001 

So im Code:

#define CLEAR_MASK 0x70000 //70000 is shorter to write, so just do this and flip it 
#define SET_3_MASK 0x30000 

volatile uint32_t * const reg = (uint32_t *) 0x4A10005C;//set a pointer to the register 
*reg &= ~CLEAR_MASK; //~ filps the bits 
*reg |= SET_3_MASK; 

Sie können Tricks mit Bits verschieben und so weiter, aber das ist die Grundlagen von Bitmasken und wie sie funktionieren. Ich hoffe es hilft.

+0

danke für die Kommentare und Erläuterungen dazu. Es wird mir in weiteren Entwicklungen sehr helfen. – denizt

+0

Schöne Formatierung Mike. :) – Whoami

0

Ich beziehe mich immer auf this website, wenn Sie Bit Twiddling tun.

+0

Link-Only-Antwort ist [keine gute Antwort] (https://meta.stackexchange.com/q/8231/230282) –