好久没更新博客了,上干货。
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>