I’d like to print both MSB and LSB of a u16 variable, here is my code:
__u16 reg = 0x10A0; /* Device register to access */ __s32 res; char buf[10]; buf[0] = reg; printf("0x%Xn", buf[0]);
This code just print the LSB part in hexa format, but can you tell me how do I print the MSB part?
Advertisement
Answer
This code just print the LSB part
Well of course, buf[0] = reg;
only copies 8 bits.
And what result you get isn’t well-defined, because char
cannot reliably store raw binary. It might be signed on your systems and then you can get all kinds of subtle bugs because of it.
Step 1 is to fix your types. Get rid of char
as well as the home-made, garage standard integer types, in favour for standard C types:
#include <stdint.h> uint16_t reg = 0x10A0u; uint8_t buf [10];
Then decide the byte order of your array. Assuming that you want index 0 to be the most significant byte, then the quick & dirty version looks like this:
buf[0] = reg >> 8; buf[1] = reg;
This will work in this specific case. However, good compilers will moan about implicit promotions and similar. Strictly speaking, you should make a habit of always casting to uint32_t
before doing any kind of shifting (assuming >=32 bit system). We can make the code more rugged and silence warnings like this:
buf[0] = ((uint32_t)reg >> 8) & 0xFFu; buf[1] = ((uint32_t)reg >> 0) & 0xFFu;
This method safely scales to larger types as well.
Also, be vary of various quack solutions on SO and elsewhere telling you to use union
or character pointers for this. Such solutions make the code needlessly endianess dependent for nothing gained. The shift version is 100% portable even across different endianess CPUs.
Then finally, printing with printf
. You can get the correct format specifier for any uintn_t automatically from the header inttypes.h
. It provides PRIx8
for lower case hex and PRIX8
for upper case hex.
Complete program:
#include <stdint.h> #include <inttypes.h> #include <stdio.h> int main (void) { uint16_t reg = 0x10A0u; uint8_t buf[10]; buf[0] = ((uint32_t)reg >> 8) & 0xFFu; buf[1] = ((uint32_t)reg >> 0) & 0xFFu; printf("0x%"PRIX8 "%"PRIX8 "n", buf[0], buf[1]); }