can 匯流排 intel、motorola資料填充演算法
阿新 • • 發佈:2019-02-10
好久沒更新部落格了,上乾貨。
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>
各位看官有什麼好的演算法可以留言共同討論。