I want to write a kernel module which reads out a register, (return value is saved in an unsigned int) and then read the the bits 16 to 22 from this variable and the convert it to an integer number. The conversion is no problem. But getting the bits out in the first place is the problem.
As example I have this 2 values in hex:
0x88290000d
0x005a0a00d
and from this 2 values I want the bits 16 to 22 as integer, any ideas how I can implement that in my kernel module ?
Here is how you extract bits 16 through 22, inclusive (7 bits):
Read the number from the register into unsigned int reg = ...
Shift reg to the right by 16, so bit 16 is at the least significant position: reg >>= 16
Mask the number with 00000000011111112, which is 0x7F: reg &= 0x7F
Note: The above counts bits starting from zero (the traditional way of numbering bits).
You can define a mask that is active for only 7 bits(16 bit to 22 bit). So your mask will be defined as.
mask=0x007F0000 //Your mask
var2=0x00270f00 //Variable which you want to mask
result=mask & var2 // bitwise-and operation to mask the value
result>>=16 // right shift the value to get only this value.
Hope this helps :)
Related
Given the 16 bit address(memory address, not value) 0x1144, 16-bit is divided into Type bit 15- bit 16 , Module bit 9 to bit 14, group bit 1 to bit 8
Type = Bit 15 - Bit 16
Module = Bit 9 - Bit 14
Group = Bit 1 - Bit 8
Read and Print the Values in Following variables.
uint16_t Type;
uint16_t Module;
uint16_t Group;
How to read & print values using C.
I tried with
uint16_t *ptr = 0x1144;
Type = *ptr >> 14;
Module = *ptr << 2;
Module = Module >> 10;
Group = *ptr << 8;
Group = Group >> 8;
Is this the correct ?
You can use Bit fields in C which is quite commonly used while addressing individual bit positions in HW registers. Just model your bit positions in a struct by defining below (on my machine with little endian)
typedef struct {
uint16_t group:8;
uint16_t module:6;
uint16_t type:2;
}nwGroup ;
All you need to do is cast the address containing your 16 bit value to this struct type and you can access the fields individually after that.
uint16_t *val = (uint16_t *)0x1144;
nwGroup *ptr = (nwGroup*)(val);
printf("NW group: %d\n", ptr->group);
(Note: We usually number things starting from 0 in computer science, so I've interpreted your requirements from a zero-based mindset.)
Use a combination of masking and shifting. For example, if you want to be able to recover the NetworkModule value, create a mask that has 1-bits in the positions you want, and 0-bits everywhere else:
#define NetworkModuleMask 0x3E00 // that is, 0011 1110 0000 0000
Now you can use that to mask out the unwanted bits using bitwise AND:
int address = 0x1144;
int networkModule = address & NetworkModuleMask
Another way to do it, which is essentially equivalent, is to use division and modulo operators with powers of 2. For example, your NetworkGroup is the
Then, to interpret the value as a number, you'll want to shift it right by 9 bits:
#define NetworkModulePosition 9
networkModule = networkModule >> NetworkModulePosition
You can use a similar process to construct an address using component values: shift each part into position and then bitwise OR it into the address.
You can also approach the problem arithmetically, using division and modulo operators with powers of 2. Dividing an integer by a power of 2 is the same as shifting it to the right by some number of bits, and modulo by a power of 2 is the same as shifting some number of bits to the right and then clearing some number of bits on the left, so you end up doing pretty much what we did above. For example, your NetworkGroup value is the low 8 bits of the address, so you can recover it by taking the address mod 2^^8, or 256. The NetworkType is the highest 2 bits, and you can recover that by dividing the address by 2^^14, or 16384.
I am using C for developing my program and I found out from an example code
unHiByte = unVal >> 8;
What does this mean? If unVal = 250. What could be the value for unHiByte?
>> in programming is a bitwise operation. The operation >> means shift right operation.
So unVal >> 8 means shift right unVal by 8 bits. Shifting the bits to the right can be interpreted as dividing the value by 2.
Hence, unHiByte = unval >> 8 means unHiByte = unVal/(2^8) (divide unVal by 2 eight times)
Without going into the shift operator itself (since that is answered already), here the assumption is that unVal is a two byte variable with a high byte (the upper 8 bits) and a low byte (the lower 8 bits). The intent is to obtain the value produced by ONLY the upper 8 bits and discarding the lower bits.
The shift operator though should easily be learned via any book / tutorial and perhaps was the reason some one down voted the question.
The >> is a bitwise right shift.
It operates on bits. With unHiByte = unVal >> 8; When unVal=250.
Its binary form is 11111010
Right shift means to shift the bits to the right. So when you shift 1111 1010, 8 digits to right you get 0000 0000.
Note: You can easily determine the right shift operation result by dividing the number to the left of >> by 2^(number to right of >>)
So, 250/28= 0
For example: if you have a hex 0x2A63 and you want to take 2A or you want to take 63 out of it, then you will do this.
For example, if we convert 2A63 to binary which is: 0010101001100011. (that is 16 bits, first 8 bits are 2A and the second 8 bits are 63)
The issue is that binary always starts from right. So we have to push the first 8 bits (2A) to the right side to be able to get it.
uint16_t hex = 0x2A63;
uint8_t part2A = (uint8_t)(hex >> 8) // Pushed the first
// eight bits (2A) to right and (63) is gone out of the way. Now we have 0000000000101010
// Now Line 2 returns for us 0x2A which the last 8 bits (2A).
// To get 63 we will do simply:
uint8_t part63 = (uint8_t)hex; // As by default the 63 is on the right most side in the binary.
It is that simple.
Can someone please explain this function to me?
A mask with the least significant n bits set to 1.
Ex:
n = 6 --> 0x2F, n = 17 --> 0x1FFFF // I don't get these at all, especially how n = 6 --> 0x2F
Also, what is a mask?
The usual way is to take a 1, and shift it left n bits. That will give you something like: 00100000. Then subtract one from that, which will clear the bit that's set, and set all the less significant bits, so in this case we'd get: 00011111.
A mask is normally used with bitwise operations, especially and. You'd use the mask above to get the 5 least significant bits by themselves, isolated from anything else that might be present. This is especially common when dealing with hardware that will often have a single hardware register containing bits representing a number of entirely separate, unrelated quantities and/or flags.
A mask is a common term for an integer value that is bit-wise ANDed, ORed, XORed, etc with another integer value.
For example, if you want to extract the 8 least significant digits of an int variable, you do variable & 0xFF. 0xFF is a mask.
Likewise if you want to set bits 0 and 8, you do variable | 0x101, where 0x101 is a mask.
Or if you want to invert the same bits, you do variable ^ 0x101, where 0x101 is a mask.
To generate a mask for your case you should exploit the simple mathematical fact that if you add 1 to your mask (the mask having all its least significant bits set to 1 and the rest to 0), you get a value that is a power of 2.
So, if you generate the closest power of 2, then you can subtract 1 from it to get the mask.
Positive powers of 2 are easily generated with the left shift << operator in C.
Hence, 1 << n yields 2n. In binary it's 10...0 with n 0s.
(1 << n) - 1 will produce a mask with n lowest bits set to 1.
Now, you need to watch out for overflows in left shifts. In C (and in C++) you can't legally shift a variable left by as many bit positions as the variable has, so if ints are 32-bit, 1<<32 results in undefined behavior. Signed integer overflows should also be avoided, so you should use unsigned values, e.g. 1u << 31.
For both correctness and performance, the best way to accomplish this has changed since this question was asked back in 2012 due to the advent of BMI instructions in modern x86 processors, specifically BLSMSK.
Here's a good way of approaching this problem, while retaining backwards compatibility with older processors.
This method is correct, whereas the current top answers produce undefined behavior in edge cases.
Clang and GCC, when allowed to optimize using BMI instructions, will condense gen_mask() to just two ops. With supporting hardware, be sure to add compiler flags for BMI instructions:
-mbmi -mbmi2
#include <inttypes.h>
#include <stdio.h>
uint64_t gen_mask(const uint_fast8_t msb) {
const uint64_t src = (uint64_t)1 << msb;
return (src - 1) ^ src;
}
int main() {
uint_fast8_t msb;
for (msb = 0; msb < 64; ++msb) {
printf("%016" PRIx64 "\n", gen_mask(msb));
}
return 0;
}
First, for those who only want the code to create the mask:
uint64_t bits = 6;
uint64_t mask = ((uint64_t)1 << bits) - 1;
# Results in 0b111111 (or 0x03F)
Thanks to #Benni who asked about using bits = 64. If you need the code to support this value as well, you can use:
uint64_t bits = 6;
uint64_t mask = (bits < 64)
? ((uint64_t)1 << bits) - 1
: (uint64_t)0 - 1
For those who want to know what a mask is:
A mask is usually a name for value that we use to manipulate other values using bitwise operations such as AND, OR, XOR, etc.
Short masks are usually represented in binary, where we can explicitly see all the bits that are set to 1.
Longer masks are usually represented in hexadecimal, that is really easy to read once you get a hold of it.
You can read more about bitwise operations in C here.
I believe your first example should be 0x3f.
0x3f is hexadecimal notation for the number 63 which is 111111 in binary, so that last 6 bits (the least significant 6 bits) are set to 1.
The following little C program will calculate the correct mask:
#include <stdarg.h>
#include <stdio.h>
int mask_for_n_bits(int n)
{
int mask = 0;
for (int i = 0; i < n; ++i)
mask |= 1 << i;
return mask;
}
int main (int argc, char const *argv[])
{
printf("6: 0x%x\n17: 0x%x\n", mask_for_n_bits(6), mask_for_n_bits(17));
return 0;
}
0x2F is 0010 1111 in binary - this should be 0x3f, which is 0011 1111 in binary and which has the 6 least-significant bits set.
Similarly, 0x1FFFF is 0001 1111 1111 1111 1111 in binary, which has the 17 least-significant bits set.
A "mask" is a value that is intended to be combined with another value using a bitwise operator like &, | or ^ to individually set, unset, flip or leave unchanged the bits in that other value.
For example, if you combine the mask 0x2F with some value n using the & operator, the result will have zeroes in all but the 6 least significant bits, and those 6 bits will be copied unchanged from the value n.
In the case of an & mask, a binary 0 in the mask means "unconditionally set the result bit to 0" and a 1 means "set the result bit to the input value bit". For an | mask, an 0 in the mask sets the result bit to the input bit and a 1 unconditionally sets the result bit to 1, and for an ^ mask, an 0 sets the result bit to the input bit and a 1 sets the result bit to the complement of the input bit.
Lets say I have an int variable n = 8. On most machines this will be a 32 bit value. How can I only get the lower 8 bits (lowest byte) of this in binary? Also how can I access each bit to find out what it is?
unsigned n = 8;
unsigned low8bits = n & 0xFF;
Note a few things:
For bitwise operations, always use the unsigned types
Bits can be extracted from numbers using binary masking with the & operator
To access the low 8 bits the mask is 0xFF because in binary it has its low 8 bits turned on and the rest 0
The low 8 bits of the number 8 are... 8 (think about it for a moment)
To access a certain bit of a number, say the kth bit:
unsigned n = ...;
unsigned kthbit = (1 << k) & n;
Now, kthbit will be 0 if the kth bit of n is 0, and some positive number (2**k) if the kth bit of n is 1.
Use bitwise arithmetic to mask off the lowest 8 bits:
unsigned char c = (x & 0xFF);
To access the nth lowest bit, the equation is (x & (1 << n)) (n of zero indicates the least significant bit). A result of zero indicates the bit is clear, and non-zero indicates the bit is set.
The best way is to use the bit logical operator & with the proper value.
So for the lower 8 bits:
n & 0xFF; /* 0xFF == all the lower 8 bits set */
Or as a general rule:
n & ((1<<8)-1) /* generate 0x100 then subtract 1, thus 0xFF */
You can combine with the bit shift operator to get a specific bit:
(n & (1<<3))>>3;
/* will give the value of the 3rd bit - note the >>3 is just to make the value either 0, or 1, not 0 or non-0 */
You can test if a particular bit is set in a number using << and &, ie:
if (num & (1<<3)) ...
will test if the fourth bit is set or not.
Similarly, you can extract just the lowest 8 bits (as an integer) by using & with a number which only has the lowest 8 bits set, ie num & 255 or num & 0xFF (in hexadecimal).
Hey, in the Programming Pearls book, there is a source code for setting, clearing and testing a bit of the given index in an array of ints that is actually a set representation.
The code is the following:
#include<stdio.h>
#define BITSPERWORD 32
#define SHIFT 5
#define MASK 0x1F
#define N 10000000
int a[1+ N/BITSPERWORD];
void set(int i)
{
a[i>>SHIFT] |= (1<<(i & MASK));
}
void clr(int i)
{
a[i>>SHIFT] &= ~(1<<(i & MASK));
}
int test(int i)
{
a[i>>SHIFT] & (1<<(i & MASK));
}
Could somebody explain me the reason of the SHIFT and the MASK defines? And what are their purposes in the code?
I've already read the previous related question.
VonC posted a good answer about bitmasks in general. Here's some information that's more specific to the code you posted.
Given an integer representing a bit, we work out which member of the array holds that bit. That is: Bits 0 to 31 live in a[0], bits 32 to 63 live in a[1], etc. All that i>>SHIFT does is i / 32. This works out which member of a the bit lives in. With an optimising compiler, these are probably equivalent.
Obviously, now we've found out which member of a that bitflag lives in, we need to ensure that we set the correct bit in that integer. This is what 1 << i does. However, we need to ensure that we don't try to access the 33rd bit in a 32-bit integer, so the shift operation is constrained by using 1 << (i & 0x1F). The magic here is that 0x1F is 31, so we'll never left-shift the bit represented by i more than 31 places (otherwise it should have gone in the next member of a).
From Here (General answer to get this thread started)
A bit mask is a value (which may be stored in a variable) that enables you to isolate a specific set of bits within an integer type.
Normally the masked will have the bits you are interested in set to 1 and all the other bits set to 0. The mask then allows you to isolate the value of the bits, clear all the bits or set all the bits or set a new value to the bits.
Masks (particularly multi-bit ones) often have an associated shift value which is the amount the bits need shifting left so that the least significant masked bit is shifted to the least significant bit in the type.
For example using a 16 bit short data type suppose you wanted to be able to mask bits 3, 4 and 5 (LSB is number 0). You mask and shift would look something like
#define MASK 0x0038
#define SHIFT 3
Masks are often assigned in hexadecimal because it is easier to work with bits in the data type in that base as opposed to decimal. Historically octal has also been used for bit masks.
If I have a variable, var, that contains data that the mask is relevant to then I can isolate the bits like this
var & MASK
I can isolate all the other bits like this
var & ~MASK
I can clear the bits like this
var &= ~MASK;
I can clear all the other bits like this
var &= MASK;
I can set all the bits like this
var |= MASK;
I can set all the other bits like this
var |= ~MASK;
I can extract the decimal value of the bits like this
(var & MASK) >> SHIFT
I can assign a new value to the bits like this
var &= ~MASK;
var |= (newValue << SHIFT) & MASK;
When You want to set a bit inside the array, You have to
seek to the right array index and
set the appropriate bit inside this array item.
There are BITSPERWORD (=32) bits in one array item, which means that the index i has to be split into two parts:
rightmost 5 bits serve as an index in the array item and
the rest of the bits (leftmost 28) serve as an index into the array.
You get:
the leftmost 28 bits by discarding the rightmost five, which is exactly what i>>SHIFT does, and
the rightmost five bits by masking out anything but the rightmost five bits, which is what i & MASK does.
I guess You understand the rest.
Bitwise operation and the leading paragraphs of Mask are a concise explanation, and contain some pointers for further study.
Think of an 8-bit byte as a set of elements from an 8-member universe. A member is IN the set when the corresponding bit is set. Setting a bit more then once doesn't modify set membership (a bit can have only 2 states). The bitwise operators in C provide access to bits by masking and shifting.
The code is trying to store N bits by an array, where each element of the array contains BITSPERWORD (32) bits.
Thus if you're trying to access bit i, you need to calculate the index of the array element stores it (i/32), which is what i>>SHIFT does.
And then you need to access that bit in the array element we just got.
(i & MASK) gives the bit position at the array element (word).
(1<<(i & MASK)) makes the bit at that position to be set.
Now you can set/clear/test that bit in a[i>>SHIFT] by (1<<i & MASK)).
You may also think i is a 32 bits number, that bits 6~31 is the index of the array element stores it, bits 0~5 represents the bit position in the word.