2011-11-21 86 views
1
i2c_receiveData(sDevice *psDevice, byte_t *pbBuffer, uint16_t *puiLen) 
{ 
. 
.  
//extract the packet data length 
unFrameLen = (*(pbBuffer+1) << 8) | *(pbBuffer + 2); 
if(unFrameLen > *puiLen) 
unFrameLen=*puiLen; 
. 
. 
} 

这里声明如何找到帧长?左移或

unFrameLen =(*(pbBuffer + 1)< < 8)| *(pbBuffer + 2);

这里pbBuffer是一个指向unsigned char数组的指针。

调用函数是,

i2c_receiveData(psDevice, prgDataRecv, &unRegLen); 

回答

4

在这种情况下,看起来“帧长度”存储在偏移量1到传递的缓冲区中。

它也看起来是一个16位整数。

为了得到一个可用的16位整数,你必须从缓冲区中解压缩。最好是使用htons/ntohs来代替,但我认为架构是众所周知的,可移植性不是问题。

有关,比如说,pbBuffer = {0, 1, 2}的输入端,该结束是:

(1 << 8) | 2; 

...其给出:

(00000001b << 8) | 00000010b 

...换档1b左8位给出:

100000000b 

...与10b和的OR-ing:

100000010b 

现在你必须从两个8位整数的16位整数pbBuffer[1..2]

100000010b = 0x102 
+0

+1,特别是对'htons()'引用。 – sarnold

+0

这意味着帧长度是258? – SHRI

+0

对于这些输入,是的。 –

2

显然,帧长度被在第二和第三字节的协议发送。该表达式从2个字节构建出16位整数。

*(pbBuffer+x)pbBuffer[x]相同,所以字节#1被左移8,并且字节#2被添加到它。

如果您收到您的pbBuffer,例如, { 0000 0000, 0101 0101, 1100 1100, ...}(二进制),提取的两个字节将是

*(pbBuffer+1) = 0101 0101 
*(pbBuffer+2) = 1100 1100 

计算将是

*(pbBuffer+1) << 8     = 0101 0101 0000 0000 
(*(pbBuffer+1) << 8) | *(pbBuffer+2) = 0101 0101 1100 1100 

的逐位或(|)是相同的这里的加成由于低8位(*(pbBuffer+1) << 8)都是0.

请注意,细节取决于平台上的一点。

+0

谢谢你的详细解答。以上的列位帮助我很好地理解了 – SHRI

1

除了把语句拆分成更小的碎片:

*(pbBuffer+1)  /* gets the byte_t value one beyond the pbBuffer pointer */ 
(*(pbBuffer+1) << 8) /* shifts that byte eight bits left -- in essence 
         xxxxxxxx00000000 -- where xxx comes from pbBuffer+1 */ 


*(pbBuffer+2)  /* gets the byte_t value two beyond the pbBuffer pointer */ 

(*(pbBuffer+1) << 8) | *(pbBuffer + 2) 
/* xxxxxxxx00000000 | yyyyyyyy */ 
    xxxxxxxxyyyyyyyy */ 

这将指定的两个字节重建为单个16位数据类型。这些 类型的操作在处理联网 代码时尤为常见,因为不同的机器有不同的byte orders。不同的订单意味着大于一个字节的数字不能在网络上轻松传递,而不使用network byte order 作为中间格式。 (有些电脑工作在网络字节 本地订购,而其他人必须始终执行转换。)