Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Declaring volatile pointer to a pointer which points to non-volatile data

When accessing a hardware register in C/C++, I usually create #defines like this:

#define HW_REGISTER ((volatile uint16_t  *)0xFFFF8A00)

I.e. 0xFFFF8A00 is a pointer to a volatile uint16_t value and this value may be changed from outside so any access to *HW_REGISTER must not be cached.

However what if the value written to the hardware register is actually a pointer? Naively we could just replace uint16_t with uint16_t *:

#define HW_REGISTER ((volatile uint16_t * *)0xFFFF8A00)

but I don't think that's correct. It reads 0xFFFF8A00 is a pointer to a pointer which points to volatile uint16_t data.

The correct way could be:

#define HW_REGISTER ((uint16_t *volatile *)0xFFFF8A00)

i.e. 0xFFFF8A00 is a pointer to a volatile pointer which points to non-volatile uint16_t data.

If I'm correct here, does this mean that if I want to look my #defines consistent, I'm forced to use the swapped syntax, i.e.

#define HW_REGISTER ((uint16_t volatile  *)0xFFFF8A00)

and

#define HW_REGISTER ((uint16_t *volatile *)0xFFFF8A00)

?

like image 695
Miro Kropacek Avatar asked Dec 02 '25 21:12

Miro Kropacek


2 Answers

It's

#define HW_REGISTER ( *( uint16_t * volatile * )0xFFFF8A00 )

We read it using the spiral rule:

It's a pointer to a volatile pointer to a uint16_t.


If you're unsure, build up the type.

typedef uint16_t *HW_REGISTER_TYPE;

#define HW_REGISTER_PTR ( ( volatile HW_REGISTER_TYPE * )0xFFFF8A00 )

#define HW_REGISTER ( *HW_REGISTER_PTR )
like image 123
ikegami Avatar answered Dec 05 '25 13:12

ikegami


If you want the source code to clearly express that the contents of the hardware register are volatile, you can use a typedef to separate the basic type of the data from the volatile qualifier:

typedef uint16_t TInteger;
#define HW_REGISTER_Integer ((volatile TInteger *) 0xFFFF8A0000)

typedef uint16_t *TPointer;
#define HW_REGISTER_Pointer ((volatile TPointer *) 0xFFFF8A0000)

With C 2024, you can do this inline with the typeof operator:

#define HW_REGISTER_Integer ((volatile typeof(uint16_t) *) 0xFFFF8A0000)

#define HW_REGISTER_Pointer ((volatile typeof(uint16_t *) *) 0xFFFF8A0000)
like image 27
Eric Postpischil Avatar answered Dec 05 '25 13:12

Eric Postpischil



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!