Is "(unsigned int *) 0x400253FCU" a pointer in the TI Stellaris Microcontroller header file <LM4F120H5QR.h>?

360 Views Asked by At

BACKGROUND:

I'm learning embedded system programming. During the process I have learn that "Pointer" is a most for embedded system. A pointer is a variable declared in C whose value is the address of another variable. And I can manipulate/change the value of this other variable by dereferencing a pointer.

Example:

int *pt;    // Integer pointer variable declaration.

float *pf;  // Float pointer variable declaration.

int *pt means that pt is a pointer variable capable of pointing to variables of type int. On the other hand, the pointer variable fp can only store the address of a float type variable.

To assign an value (address) to a pointer variable the address operator (&) must be used.

int var = 20;   //Actual variable declaration
int *pt;        //Pointer Variable Declaration

pt = &var;      //Here with the ampersand (&)operator we denotes an 
                //address in memory to the pt pointer.

/*Changing the variable value from 20 to 79*/
*pt = 79;   //Dereference

printf (“Value of *pt variable: %d\n”, *pt); //Output:79
printf (“Value of var variable: %d\n”, var); //Output:79

These two links were very helpful for me to understand pointers:

Pointer Basics in C

Pointer (computer programming)

QUESTION

My question arises when I come across the header file of the Stellaris LM4F120H5QR Microcontroller. This header file define the register locations with memory addresses as follows:

#define GPIO_PORTF_DATA_R       (*((volatile unsigned long *)0x400253FC))

When I came across this syntax I was confused if indeed " (volatile unsigned long *)0x400253FC) " has been define as a pointer and the whole sentence can be interpreted as shows in picture below?

Pointer Dereference Memory Location

If that is not correct, can someone explain the correct way to interpret the register definition for an embedded system header file?

Link for the header file --> Here

2

There are 2 best solutions below

2
Ibram Reda On BEST ANSWER

this is a correct defiention !! and if you try it it will work just fine .... let me help you in understanding this statment how it work

Explanation of accessing a specific memory address

if you have an a specific address in memory FOR example (this address 0x400253FC) and you like to write value of (50) to the first byte the following code will be wrong

// the following code is wrong
0x400253FC = 50 ;

the above code will give a compile error .. so how to tell compiler to make this (0x400253FC) as a memory address ??, simply will do that with help of casting

(unsinged char *)0x400253FC  // cast this number 0x400253FC as char pointer

now you have a pointer so you could dereference it and write the value in memory (where the pointer point to) like this

*((unsinged char *)0x400253FC) = 50; // write the value 50 in address 0x400253FC

some compilers when they make Optimization they will delete this line of code so to prevent the compiler from doing that we add the volatile specifier ... so the expression will be like this

*((volatile unsinged char *)0x400253FC) = 50; // write the value 50 in address 0x400253FC

so this is how to accssess a byte in memory

if you like to access 4 byte in memory so it will be like this

//assuming your compiler consider the long variable as 4 byte
*((volatile unsinged long*)0x400253FC) = 50; // write the value 50 in 4 byte in memory start with address 0x400253FC
0
old_timer On
(*((volatile unsigned long *)0x400253FC)) = 0x12345678

Elementary C, just parse it out. I think you get it not sure where the confusion is.

I think you understand typecasting

unsigned int x;  //a variable

x = 0x400253FC; //assign the variable a value

(volatile unsigned long *)x  //typecast x into a different type volatile unsigned long *

Likewise using a pointer

volatile unsigned long *z;

(*z)=0x12345678; //at the address pointed to by z place the value 0x12345678;

break it into parts.

(
*
(
(volatile unsigned long *)0x400253FC
)
)


0x400253FC a value

(volatile unsigned long *)0x400253FC typecast that value into an unsigned long pointer

((volatile unsigned long *)0x400253FC)  enclose that pointer as a whole at this point it is a pointer, like z from above.

*((volatile unsigned long *)0x400253FC) dereference it one level, like *z above you can now use this to manipulate the unsigned long address.

(*((volatile unsigned long *)0x400253FC)) good idea to wrap defines in parens to not confuse the compiler.  doesn't hurt.

(*((volatile unsigned long *)0x400253FC)) = 0x12345678.  Like *z = 0x12345678 above, write/store 0x12345678 to the address 0x400253FC

#define GPIO_PORTF_DATA_R       (*((volatile unsigned long *)0x400253FC))

GPIO_PORTF_DATA_R = 0x12345678; store/write 0x12345678 to the address 0x400253FC

unsigned long k; k = GPIO_PORTF_DATA_R; load/read from address 0x400253FC and save it in k

If you have an 8 bit wide register then adjust the typecast as such.

#define SOME_8BIT_REG  (*((volatile unsigned char *)0x5006789A))

SOME_8BIT_REG = 0x33;

you could just try it

#define GPIO_PORTF_DATA_R       (*((volatile unsigned long *)0x400253FC))
#define SOME_8BIT_REG  (*((volatile unsigned char *)0x5006789A))

void fun ( void )
{
    GPIO_PORTF_DATA_R = 0x12345678;
    SOME_8BIT_REG = 0x33;
}

00000000 <fun>:
   0:   e3a02033    mov r2, #51 ; 0x33
   4:   e59f1010    ldr r1, [pc, #16]   ; 1c <fun+0x1c>
   8:   e59f0010    ldr r0, [pc, #16]   ; 20 <fun+0x20>
   c:   e59f3010    ldr r3, [pc, #16]   ; 24 <fun+0x24>
  10:   e58103fc    str r0, [r1, #1020] ; 0x3fc
  14:   e5c3209a    strb    r2, [r3, #154]  ; 0x9a
  18:   e12fff1e    bx  lr
  1c:   40025000    
  20:   12345678    
  24:   50067800    

  10:   e58103fc    str r0, [r1, #1020] ; 0x3fc
  32 bit store (write) 0x12345678 to address 0x400253fc

  14:   e5c3209a    strb    r2, [r3, #154]  ; 0x9a
  8 bit store (write) 0x33 to address 0x5006789a

Instruction set doesn't matter

0000000000000000 <fun>:
   0:   48 c7 04 25 fc 53 02    movq   $0x12345678,0x400253fc
   7:   40 78 56 34 12 
   c:   c6 04 25 9a 78 06 50    movb   $0x33,0x5006789a
  13:   33 
  14:   c3                      retq  

Disassembly of section .text:

00000000 <fun>:
   0:   123457b7            lui x15,0x12345
   4:   40025737            lui x14,0x40025
   8:   67878793            addi    x15,x15,1656 # 12345678 <fun+0x12345678>
   c:   3ef72e23            sw  x15,1020(x14) # 400253fc <fun+0x400253fc>
  10:   500687b7            lui x15,0x50068
  14:   03300713            li  x14,51
  18:   88e78d23            sb  x14,-1894(x15) # 5006789a <fun+0x5006789a>
  1c:   8082                    ret