[c] Direkt auf Speicherstelle zugreifen

flohaase

Mitglied
Hallo zusammen,

ich arbeite mit einem MPC5554 Prozessor und habe dazu ein Beispiel C-Programm.

Code:
DSPI_A.MCR.R = 0x00000001;
DSPI_A.MCR.R = 0x00000000;
DSPI_A.MCR.R = 0x00000001;
DSPI_A.MCR.R = 0x00000000;

Auf diese Weise kann ich ein einzelnes Bit im Register MCR des DSPI Moduls A ändern. Die Syntax ist so weit in Ordnung, weil es dazu ein passendes h-file gibt.

Nun würde ich gerne direkt, ohne diese Syntax und zwar mit absoluten Adresse auf das Register zugreifen. Aus dem Datenblatt kann ich folgende Adresse lesen:

0xFFF9_0000 (DSPI A) | DSPIx_MCR | DSPI module configuration register | Size 32 bit

Das Bit, dass ich ändern möchte, ist das 32. (=31, weil 0 das 1. Bit ist) Bit des Registers MCR.

Meine Annahme ist nun, dass ich das Bit mit der Registeradresse 0xFFF90031 ändern muss. Das Klappt aber nicht so ganz.

Hier mein Programm dazu:

Code:
int main(void) {

	diag_printf("\n\nSPI HALT register test\n\n");

	int base_address = 0xFFF90000;	// DPSI A start address of MPC5554
	int offset       = 0x00000000;	// offset of MCR
	int bit_halt_reg = 0x00000031;	// bit 31 = HALT register
	int result_address = 0;
	int *p_address = NULL;
	int value = 0;

	result_address = base_address + offset + bit_halt_reg;
	
	printf("base_address      = %#10x\n", base_address);
	printf("offset            = %#10x\n", offset);	
	printf("bit_halt_reg      = %#10x\n", bit_halt_reg);	
	printf("result_address    = %#10x\n", result_address);
	printf("value             = %d\n", value);
	
	p_address = result_address; // address with &var or direct address input
	
	diag_printf("HALT register     = %i\n", *p_address); // read HALT register

	*p_address = value; // write HALT register
	
	printf("new HALT register = %i\n", *p_address); // read HALT register again

	while(1);
	
	return 0;

}

Weiß einer, warum sich das Bit nicht ändern?

Danke, Gruß Flo
 
Hi

du bringst da Bits/Bytes und Dezimal/Hex ganz schön durcheinander.

Zuerst zur Grundadresse: Schau einfach in die Headerdatei,
woher das DSPI_A.MCR.R kommt.
Mit 31. bzw. 32. Bit meinst du das niederwertigste oder höchstwertigste
(von links oder rechts gehen das letzte/erste Bit)?

Notiz: 32bit Bigendian Powerpc
 
Hallo flohaase,

Code:
DSPI_A.MCR.R = 0x00000001;
DSPI_A.MCR.R = 0x00000000;
DSPI_A.MCR.R = 0x00000001;
DSPI_A.MCR.R = 0x00000000;

Auf diese Weise kann ich ein einzelnes Bit im Register MCR des DSPI Moduls A ändern. Die Syntax ist so weit in Ordnung, weil es dazu ein passendes h-file gibt.
Damit änderst du nicht nur ein einzelnes Bit, sondern das komplette 32-Bit-Register. Wenn du nur das "HALT"-Bit setzen willst, müsstest du stattdessen mit DSPI_A.MCR.B.HALT darauf zugreifen.

Nun würde ich gerne direkt, ohne diese Syntax und zwar mit absoluten Adresse auf das Register zugreifen. Aus dem Datenblatt kann ich folgende Adresse lesen:

0xFFF9_0000 (DSPI A) | DSPIx_MCR | DSPI module configuration register | Size 32 bit

Das Bit, dass ich ändern möchte, ist das 32. (=31, weil 0 das 1. Bit ist) Bit des Registers MCR.

Meine Annahme ist nun, dass ich das Bit mit der Registeradresse 0xFFF90031 ändern muss. Das Klappt aber nicht so ganz.
Das ist gleich doppelt falsch. Zahlen die mit "0x" beginnen sind im Hexadezimalsystem notiert. 31 ist im Hexadezimalsystem 0x1F, also müsste die Adresse wenn dann 0xFFF9001F lauten. Das ist aber auch falsch, weil nicht jedes Bit eine eigene Speicheradresse besitzt, sondern nur jedes Byte (8 Bits). Das komplette 32-Bit-Register DSPIA_MCR ist also in den Adressen 0xFFF90000 bis einschließlich 0xFFF90003 zu finden. Das Setzen des 31. Bits würde dann so funktionieren (ungetestet):

C:
uint32_t* DSPIA_MCR = (uint32_t*) 0xFFF90000;
// HALT (Bit 31) auf 1 setzen
*DSPIA_MCR |= 0x80000000;
// HALT (Bit 31) auf 0 setzen
*DSPIA_MCR &= ~0x80000000;

Grüße
Matthias
 
Zurück