I stumbled on some code in the project I'm working on and I wanted to be sure to understand it correctly. So here it is:
uint16_t* tmp;
tmp = (uint16_t*) ((uint8_t*)getVariableAddress(variable) + offset);
tmp = (uint16_t*)((uint8_t*)tmp + otherOffset);
Set_Register((unsigned long) tmp[0]);
Set_OtherRegister((unsigned long) tmp[2]);
At first I got a bit lost between all the casts but the way I see it the uint8_t* are being used to move byte per byte and add the offset values to the base address we place in tmp, this was the first part that got me troubled. The second part was the use of [] on a uint16_t* , for this one I'm not sure at all on the result, anyone care to explain this in detail ?
Thanks
I think it is easier to see what happens if we rewrite the code a bit:
// We keep this as a `uint8_t *` so we can add offsets correctly.
uint8_t *base_address = (uint8_t *)getVariableAddress(variable);
// Add the offsets to the base address.
uint8_t *offsetted_address = base_address + offset + otherOffset;
// We want it as a uint16_t.
uint16_t *as_u16 = (uint16_t *)offsetted_address;
// We want to write the first register with the first `uint16_t` at `offsetted_address`, but `Set_Register` takes the value as `unsigned long`.
unsigned long first_u16 = as_u16[0];
Set_Register(first_u16);
// We want to write the other register with the third `uint16_t` at `offsetted_address`, but `Set_OtherRegister` takes the value as `unsigned long`.
unsigned long third_u16 = as_u16[2];
Set_OtherRegister(third_u16 );
We know that the values that interest us are at an offset relative to the address returned by getVariableAddress. In order to properly compute that address we cast the address to an uint8_t. If we keep as uint16_t our arithmetic would be wrong. Consider this:
uint8_t *p = (uint8_t *)0x100;
printf("%p\n", p + 1); // prints 0x101
uint16_t *q = (uint16_t *)0x200;
printf("%p\n", q + 1); // prints 0x202
We then want to read the first and third 16-bit unsigned integer from the address we just computed, so we cast it to an uint16_t * and get the first ([0]) and third ([2]) integers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With