1. 程式人生 > >can 匯流排 intel、motorola資料填充演算法

can 匯流排 intel、motorola資料填充演算法

好久沒更新部落格了,上乾貨。

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>
各位看官有什麼好的演算法可以留言共同討論。