Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Interpreting: Type Define pointer

Status
Not open for further replies.

joecool21

Newbie level 4
Joined
Jul 25, 2013
Messages
6
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
36
Hi how do I interpret "*" in the following C syntax, is it a form of type casting?
#define device *(( volatile unsigned long *) (0x1000000))

Thanks
 

Does this make sense:
device is a pointer to a unsigned long which holds the address 0x10000000

thanks
 

Does this make sense:
device is a pointer to a unsigned long which holds the address 0x10000000

Code:
#define device *(( volatile unsigned long *) (0x1000000))

Not quite. The value, 0x1000000 is cast as a address pointing to a C Type of unsigned long which also happens to be qualified as volatile, in short, pointers are addresses which point to a specified C/C++ Type.

Also, a crucial part of the defined macro above is the leading indirection operator, *, utilized in its dereferencing capacity, which I shall attempt to clarify its purpose in the following synopsis:

It often helps to interpret such nomenclature by reading them from right to left, a technique which I shall utilize below.

Code:
#define device *(( volatile unsigned long [COLOR="#FF0000"]*[/COLOR]) ([COLOR="#FF0000"]0x1000000[/COLOR]))

The value 0x1000000 is being cast as a pointer, through the use of the indirection operator, *.

Code:
#define device *(( volatile [COLOR="#FF0000"]unsigned long[/COLOR] *) (0x1000000))

To a C Type of unsigned long. The primary effect of this cast to a pointer to a type of unsigned long is to alert the compiler that the address, 0x1000000, points to the first byte of one or more bytes which contain the value of the C type unsigned long, the exact size of the type storage depends largely on the compiler and architecture of the processor. Let us assume the targets compiler defines the size of a C type of unsigned long to be 32-bits or 4 bytes, then the address/pointer, 0x1000000 contains/points to the first of these four bytes, address/pointer 0x1000001 would likewise contain/point to the second byte, address/pointer 0x1000002 the third byte and address/pointer 0x1000003 the fourth and final byte.

Code:
#define device *(( [COLOR="#FF0000"]volatile[/COLOR] unsigned long *) (0x1000000))

The unsigned long type contained at address/pointer 0x1000000 also happens to be classified as volatile as indicated by the preceding type qualifier volatile. A value/object classified/qualified to be volatile alerts the compiler that it should not allow the volatile value/object to participate in optimization schemes which assume no hidden side effects, i.e., the value/object could change without notice regardless of the current state of code execution or processor. In short, do not assume any cached or preceding reads of a value corresponds to the actual stored value/object at any one time. For example, microcontroller port values are often classified/qualified as volatile as they can change independent of code execution or processor state.

Code:
#define device *[COLOR="#FF0000"](( volatile unsigned long *) (0x1000000))[/COLOR]

In summary the part highlighted in RED could be interpreted as follows, reading from right to left:

The value 0x1000000 is a pointer, *,to a C type of unsigned long which is classified/qualified as volatile.

Code:
#define device [COLOR="#FF0000"]*[/COLOR](( volatile unsigned long *) (0x1000000))

Then finally the use of the indirection operator, *, dereferences the previously cast pointer, which essentially provides direct access, read/write capabilities, to the C type value/object to which the pointer points.

For example, it allows the value pointed to by pointer to be directly read, assuming an unsigned long size of 32-bits/4 bytes:

Code:
unsigned long tmp;

 tmp = *(( volatile unsigned long *) (0x1000000));

Or directly written:

Code:
unsigned long tmp = 0xFFFFFFFF;

*(( volatile unsigned long *) (0x1000000)) = tmp;

Or with the predefined macro:

Code:
#define device *(( volatile unsigned long *) (0x1000000))

unsigned long tmp;

 tmp = device;

And,

Code:
#define device *(( volatile unsigned long *) (0x1000000))

unsigned long tmp = 0xFFFFFFFF;

device = tmp;

Thus the predefined macro simply replaces the symbol device during precompilation phase with the appropriate dereferenced pointer to a type of unsigned long. Instead of device, the symbol to be replaced could be PORTA, PLLCONFIG, etc, which is exactly how many compilers dereference many ports, memory mapped registers, etc to common symbols, i.e., PORTA, utilized during coding by the programmer. A review of the header files utilized by various compilers which yield such examples, particular in a microcontroller such as an ARM architecture.

For example:


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
//******************************************************* **********************
//
// tm4c123gh6pm.h - TM4C123GH6PM Register Definitions
//
// Copyright (c) 2013 Texas Instruments Incorporated.  All rights reserved.
// Software License Agreement
// 
//   Redistribution and use in source and binary forms, with or without
//   modification, are permitted provided that the following conditions
//   are met:
// 
//   Redistributions of source code must retain the above copyright
//   notice, this list of conditions and the following disclaimer.
// 
//   Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in the
//   documentation and/or other materials provided with the  
//   distribution.
// 
//   Neither the name of Texas Instruments Incorporated nor the names of
//   its contributors may be used to endorse or promote products derived
//   from this software without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// 
// This is part of revision 1.0 of the Tiva Firmware Development Package.
//
//*****************************************************************************
 
#ifndef __TM4C123GH6PM_H__
#define __TM4C123GH6PM_H__
 
//*****************************************************************************
//
// Watchdog Timer registers (WATCHDOG0)
//
//*****************************************************************************
#define WATCHDOG0_LOAD_R        (*((volatile unsigned long *)0x40000000))
#define WATCHDOG0_VALUE_R       (*((volatile unsigned long *)0x40000004))
#define WATCHDOG0_CTL_R         (*((volatile unsigned long *)0x40000008))
#define WATCHDOG0_ICR_R         (*((volatile unsigned long *)0x4000000C))
#define WATCHDOG0_RIS_R         (*((volatile unsigned long *)0x40000010))
#define WATCHDOG0_MIS_R         (*((volatile unsigned long *)0x40000014))
#define WATCHDOG0_TEST_R        (*((volatile unsigned long *)0x40000418))
#define WATCHDOG0_LOCK_R        (*((volatile unsigned long *)0x40000C00))
 
//*****************************************************************************
//
// Watchdog Timer registers (WATCHDOG1)
//
//*****************************************************************************
#define WATCHDOG1_LOAD_R        (*((volatile unsigned long *)0x40001000))
#define WATCHDOG1_VALUE_R       (*((volatile unsigned long *)0x40001004))
#define WATCHDOG1_CTL_R         (*((volatile unsigned long *)0x40001008))
#define WATCHDOG1_ICR_R         (*((volatile unsigned long *)0x4000100C))
#define WATCHDOG1_RIS_R         (*((volatile unsigned long *)0x40001010))
#define WATCHDOG1_MIS_R         (*((volatile unsigned long *)0x40001014))
#define WATCHDOG1_TEST_R        (*((volatile unsigned long *)0x40001418))
#define WATCHDOG1_LOCK_R        (*((volatile unsigned long *)0x40001C00))
 
//*****************************************************************************
//
// GPIO registers (PORTA)
//
//*****************************************************************************
#define GPIO_PORTA_DATA_BITS_R  ((volatile unsigned long *)0x40004000)
#define GPIO_PORTA_DATA_R       (*((volatile unsigned long *)0x400043FC))
#define GPIO_PORTA_DIR_R        (*((volatile unsigned long *)0x40004400))
#define GPIO_PORTA_IS_R         (*((volatile unsigned long *)0x40004404))
#define GPIO_PORTA_IBE_R        (*((volatile unsigned long *)0x40004408))
#define GPIO_PORTA_IEV_R        (*((volatile unsigned long *)0x4000440C))
#define GPIO_PORTA_IM_R         (*((volatile unsigned long *)0x40004410))
#define GPIO_PORTA_RIS_R        (*((volatile unsigned long *)0x40004414))
#define GPIO_PORTA_MIS_R        (*((volatile unsigned long *)0x40004418))
#define GPIO_PORTA_ICR_R        (*((volatile unsigned long *)0x4000441C))
#define GPIO_PORTA_AFSEL_R      (*((volatile unsigned long *)0x40004420))
#define GPIO_PORTA_DR2R_R       (*((volatile unsigned long *)0x40004500))
#define GPIO_PORTA_DR4R_R       (*((volatile unsigned long *)0x40004504))
#define GPIO_PORTA_DR8R_R       (*((volatile unsigned long *)0x40004508))
#define GPIO_PORTA_ODR_R        (*((volatile unsigned long *)0x4000450C))
#define GPIO_PORTA_PUR_R        (*((volatile unsigned long *)0x40004510))
#define GPIO_PORTA_PDR_R        (*((volatile unsigned long *)0x40004514))
#define GPIO_PORTA_SLR_R        (*((volatile unsigned long *)0x40004518))
#define GPIO_PORTA_DEN_R        (*((volatile unsigned long *)0x4000451C))
#define GPIO_PORTA_LOCK_R       (*((volatile unsigned long *)0x40004520))
#define GPIO_PORTA_CR_R         (*((volatile unsigned long *)0x40004524))
#define GPIO_PORTA_AMSEL_R      (*((volatile unsigned long *)0x40004528))
#define GPIO_PORTA_PCTL_R       (*((volatile unsigned long *)0x4000452C))
#define GPIO_PORTA_ADCCTL_R     (*((volatile unsigned long *)0x40004530))
#define GPIO_PORTA_DMACTL_R     (*((volatile unsigned long *)0x40004534))
 
//*****************************************************************************
//
// GPIO registers (PORTB)
//
//*****************************************************************************
#define GPIO_PORTB_DATA_BITS_R  ((volatile unsigned long *)0x40005000)
#define GPIO_PORTB_DATA_R       (*((volatile unsigned long *)0x400053FC))
#define GPIO_PORTB_DIR_R        (*((volatile unsigned long *)0x40005400))
#define GPIO_PORTB_IS_R         (*((volatile unsigned long *)0x40005404))
#define GPIO_PORTB_IBE_R        (*((volatile unsigned long *)0x40005408))
#define GPIO_PORTB_IEV_R        (*((volatile unsigned long *)0x4000540C))
#define GPIO_PORTB_IM_R         (*((volatile unsigned long *)0x40005410))
#define GPIO_PORTB_RIS_R        (*((volatile unsigned long *)0x40005414))
#define GPIO_PORTB_MIS_R        (*((volatile unsigned long *)0x40005418))
#define GPIO_PORTB_ICR_R        (*((volatile unsigned long *)0x4000541C))
#define GPIO_PORTB_AFSEL_R      (*((volatile unsigned long *)0x40005420))
#define GPIO_PORTB_DR2R_R       (*((volatile unsigned long *)0x40005500))
#define GPIO_PORTB_DR4R_R       (*((volatile unsigned long *)0x40005504))
#define GPIO_PORTB_DR8R_R       (*((volatile unsigned long *)0x40005508))
#define GPIO_PORTB_ODR_R        (*((volatile unsigned long *)0x4000550C))
#define GPIO_PORTB_PUR_R        (*((volatile unsigned long *)0x40005510))
#define GPIO_PORTB_PDR_R        (*((volatile unsigned long *)0x40005514))
#define GPIO_PORTB_SLR_R        (*((volatile unsigned long *)0x40005518))
#define GPIO_PORTB_DEN_R        (*((volatile unsigned long *)0x4000551C))
#define GPIO_PORTB_LOCK_R       (*((volatile unsigned long *)0x40005520))
#define GPIO_PORTB_CR_R         (*((volatile unsigned long *)0x40005524))
#define GPIO_PORTB_AMSEL_R      (*((volatile unsigned long *)0x40005528))
#define GPIO_PORTB_PCTL_R       (*((volatile unsigned long *)0x4000552C))
#define GPIO_PORTB_ADCCTL_R     (*((volatile unsigned long *)0x40005530))
#define GPIO_PORTB_DMACTL_R     (*((volatile unsigned long *)0x40005534))



It should be noted the above examples actually enclose the entire definition in another set of parenthesis, unlike your example, which would be a highly recommended practice.

Code:
#define GPIO_PORTA_DATA_R       [COLOR="#FF0000"]([/COLOR]*((volatile unsigned long *)0x400043FC)[COLOR="#FF0000"])[/COLOR]

Another issue which should be mentioned, is the cast typically provides no indication of Endianness of the stored value, whether it be stored in a Little or Big Endian format, reference the following for a detailed explanation of this concept:




BigDog
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top