好久没更新博客了,上干货。
CAN总线的数据填充问题我一直认为是一个很有意思的问题,怎么写出高效优雅的算法实现,很快我就相出了INTEl的算法问题,MOTOROLA的一直没有合理的代码实现,前几天有面临这个问题,灵机一动终于找到了完美的解决方案。
typedef struct
{
Uint64 BYTE0:8;
Uint64 BYTE1:8;
Uint64 BYTE2:8;
Uint64 BYTE3:8;
Uint64 BYTE4:8;
Uint64 BYTE5:8;
Uint64 BYTE6:8;
Uint64 BYTE7:8;
} _BYTES_DATA;
typedef union
{
Uint64 all;
_BYTES_DATA bit;
}_UINT64_DATA;
void FillFrameData(Uint16 frame_data[], Uint16 bit_start, Uint16 bit_len, Uint16 motorola, Uint32 value)
{
Uint32 index, mask;
_UINT64_DATA long_data;
if(motorola)
{
index = 56 + (bit_start%8) - (bit_start/8 * 8);
mask = (0x1ULL << bit_len)-1;
long_data.all = value & mask;
long_data.all <<= index;
frame_data[7] |= long_data.bit.BYTE0;
frame_data[6] |= long_data.bit.BYTE1;
frame_data[5] |= long_data.bit.BYTE2;
frame_data[4] |= long_data.bit.BYTE3;
frame_data[3] |= long_data.bit.BYTE4;
frame_data[2] |= long_data.bit.BYTE5;
frame_data[1] |= long_data.bit.BYTE6;
frame_data[0] |= long_data.bit.BYTE7;
}
else
{
index = bit_start;
mask = (0x1ULL << bit_len)-1;
long_data.all = value & mask;
long_data.all <<= index;
frame_data[0] |= long_data.bit.BYTE0;
frame_data[1] |= long_data.bit.BYTE1;
frame_data[2] |= long_data.bit.BYTE2;
frame_data[3] |= long_data.bit.BYTE3;
frame_data[4] |= long_data.bit.BYTE4;
frame_data[5] |= long_data.bit.BYTE5;
frame_data[6] |= long_data.bit.BYTE6;
frame_data[7] |= long_data.bit.BYTE7;
}
}
上面的程序可优化的地方
bit_start%8====》bit_start&7
bit_start/8 * 8 ====>> bit_start & 0xFFF8
frame_data[0] |= long_data.bit.BYTE0;
frame_data[1] |= long_data.bit.BYTE1;
frame_data[2] |= long_data.bit.BYTE2;
frame_data[3] |= long_data.bit.BYTE3;
frame_data[4] |= long_data.bit.BYTE4;
frame_data[5] |= long_data.bit.BYTE5;
frame_data[6] |= long_data.bit.BYTE6;
frame_data[7] |= long_data.bit.BYTE7;
</pre>上面转化为64bit整体操作<p></p><pre>