James
James

Reputation: 21

Type casting and pointers

I have a piece of code I am unsure on would very much appreciate a run down on its workings.

The first bit is about type casting. Can someone tell me if I'm reading the following code correctly:

#define A_TIME          0xC0500000
#define B_TIME           *(UINT_8 *)(A_TIME + 0x00002909)

Is the output of this that B_TIME is a pointer to an unsigned integer of 8 bits = 0x09? I'm unsure of how type casting works? Does it assign the 8 LSB to B_TIME? Also, I'm confused by the *(UINT_8 *)? What exactly does this mean/say? It's a pointer to a unsigned integer of 8 bits?

The second part will probably be clear to me once I know the above but I'll post it anyway:

UINT_8  Timer = 0;
Input_Time (&Timer);



#define C_TIME                 *(UINT_16 *)0xC0C0B000
#define MASK                        0x003F

void Input_Time (UINT_8 *Time)
{
    *Time = 0xC0;  
    *Time |= (UINT_8)((C_TIME >> 4) & MASK);

    return;
}

What is the value of *Time following Input_Time function? Could someone step through the code and explain each step for me?

Apologies for the noviceness (is that a word?!) of the question.

Much appreciated. James

EDIT:

OK, I'm happy with the above. Thanks. I'm now confused as to the following which happens within the code, after Input_Time() has been called:

#define OUT_TIME *(UINT_8 *)0xC0411297
OUT_TIME = Timer;

How is this possible? Isn't OUT_TIME the 8-bit value within the address 0XC0411297? How does that work?

Upvotes: 1

Views: 206

Answers (2)

Carl Norum
Carl Norum

Reputation: 224844

The code you're looking at looks like it's accessing memory mapped registers.

  1. B_TIME will access an 8-bit register located at address A_TIME plus the specified offset - in this case, that means 0xC0502909. What actually gets read depends on the hardware you're using. Let's break down what happens in pieces. B_TIME, wherever it is used, gets replaced with the text:

    *(UINT_8 *)(A_TIME + 0x00002909)
    

    And in turn, the A_TIME is replaced with 0xC0500000, yielding:

    *(UINT_8 *)(0xC0500000 + 0x00002909)
    

    A little working out of arithmetic gives:

    *(UINT_8 *)(0xC0502909)
    

    Which means "treat 0xC0502909 as a pointer to an 8-bit value and then dereference it".

  2. Your second question follows the same behaviour. There is a register mapped at 0xC0C0B000 that is being read when Input_Time() is called. A 16-bit value is read from that address, is downshifted by 4, and then masked. Assuming this example 16-bit value, using letters to uniquely represent the bits:

    abcdefghijklmnop
    

    Downshifted by 4:

    0000abcdefghijkl
    

    And then the mask (3f hex is 00111111 binary) applied:

    0000000000ghijkl
    

    Then, that result is ORed with the 0xc0 (11000000 binary), yielding:

    0000000011ghijkl
    

    That value is stored back into the 8-bit passed-in-byte, returning:

    11ghijkl
    

    To the caller.

  3. Your new example:

    #define OUT_TIME *(UINT_8 *)0xC0411297
    OUT_TIME = Timer;
    

    Is writing a value to that memory address.

Upvotes: 2

ouah
ouah

Reputation: 145829

The value of B_TIME is a value of type UINT8.

#define B_TIME *(UINT_8 *)(A_TIME + 0x00002909)

The * operator dereferences the pointer to UINT8 in the following expression:

(UINT_8 *)(A_TIME + 0x00002909)

In the above expression the integer constant expression A_TIME + 0x00002909 is converted to a pointer to UINT8 by the mean of the cast (UINT8 *).

Upvotes: 0

Related Questions