Pointing the pointer to the width of the pointer and the width of the data

I want to access the 32-bit data specified at the address in the hardware register (which is 64 bits, only with 40 LSb set). So I:

paddr_t address = read_hw(); // paddr_t is unsigned long long
unsigned int value  = *(unsigned int*) address; // error: cast to pointer from integer of different size
unsigned int value2 = (unsigned int) *((paddr_t*) address); // error: cast to pointer from integer of different size

What would be the correct way to do this without a compiler error (I use -Werror)?

+3
source share
4 answers

Nominally with C99, the first option is closest to the correct one,

uint32_t value = *(uint32_t*)address;

However, you can also use other pointer / integer helpers,

uintptr_t address = read_hw();
uint32_t value = *(uint32_t*)address;
+1
source

check the real sizes for your pointers and paddr_t type:

printf("paddr_t size: %d, pointer size: %d\n",
       sizeof(paddr_t), sizeof(unsigned int *));

what are you getting?

update:

ARM is a 32-bit architecture, so you are trying to convert from a 64-bit integer to a 32-bit pointer that he does not like your compiler!

, paddr_t 32 , int:

unsigned int *p = (unsigned int *)(int)addrs;
0

, .

" 32- , ( 64 , 40 LSb).

, 64 , 40 , 32 ?

uint32_t* pointer = (*(uint64_t *) register_address) & (~0 >> 24)
uint32_t value = *pointer

>> .

, , ,

  • " -, printf", , , , ?
  • , 40 ?!
0

, , 64 , 40 , 32 .

, , 40- 32- .

, , - 40 64- , 64- , , , ( ) .

- ( 64 , , ):

address = address & 0x????????????????; // use the ?s to mask off the bits you
                                        // want to ignore
value64 = *address; // value64 is 64 bits

value32 = (int)(value64 & 0x00000000ffffffff); // if the data is in the lower
                                               // half of value64
or
value32 = (int)((value64 & 0xffffffff00000000) > 32); // if the data is in the
                                                      // higher half of value64

? ( , ).

You probably also need to change the (int) matching (you want to apply it instead to any 32-bit data type that the data represents, i.e., to the value type32).

0
source

Source: https://habr.com/ru/post/1779352/


All Articles