Using CAN communications with a DBC as database, there are two different ways of encoding integer signals to the 64bit (8 byte) message data: Intel and Motorola.
To convert the 8 byte of message data to the distinct signals, I first want to use a bitmask to "scope" only the interesting bits and afterwards do some shift operations to get the number the signal is representing.
Here I am only interested in the bitmask generation:
Intel (also known as little-endian) is pretty straight forward: you take the startbit and iterate up to startBit + length
setting every bit in your 64bit mask to 1 that you come by:
uint64_t generateBitmask(Signal* signal) {
uint64_t bitmask = 0;
uint64_t one = 1;
int startBit = signal->startbit;
int endBit = startBit + signal->length;
if(signal->byteOrder == INTEL) {
for(int i = startBit; i < endBit; ++i)
{
bitmask |= (one << i);
}
}
return bitmask;
}
With motorola (big-endian) based numbers it is a bit more complicated:
since the byteorder (NOT the bitorder) is swapped, the (according to the index) lowest byte might contain "gaps" on the upper bits while the highest (indexed) byte might have a "gaps" on the lower end of the byte (see signal MOTO_20 in image; bits 22/23 and 32/33 are not part of the signal although they are sourrounded by bits that are).
I am searching for a way to calculate this bitmask based on start bit and length of the respective signal. Please find two examples for motorola-based signals layed out in a CAN frame in the image below. Start bits and lengths are given under the image.
The bitmask is supposed to be corresponding to what a CAN bus message layout using a dbc would look like (image as example): every bit of a signal that is marked in the image is supposed to be 1:
example MOTO_20: 00000000 00000000 00000000 11111000 11111111 01111111 00000000 00000000
example MOTO_16: 00000000 00000000 00000000 00000000 00000000 00000000 11111111 11111111
The signal MOTO_20 has startbit 34 and length 20
The signal MOTO_16 has startbit 8 and length 16