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;

 
  
 
  
上面转化为64bit整体操作

 
  


各位看官有什么好的算法可以留言共同讨论。


你可能感兴趣的:(DSP)