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)&lt;&lt; 8)| *(pbBuffer + 2);
这里 pbBuffer 是指向unsigned char数组的指针。
调用函数是,
i2c_receiveData(psDevice, prgDataRecv, &unRegLen);
答案 0 :(得分:4)
在这种情况下,似乎“帧长度”存储在偏移1处,并传递给传递的缓冲区。
它似乎也是一个16位整数。
要获得可用的16位整数,必须从缓冲区中解压缩。最好转换并使用htons
/ ntohs
,但我认为架构是众所周知的,并且可移植性不是问题。
对于pbBuffer = {0, 1, 2}
的输入,最终是:
(1 << 8) | 2;
...给出:
(00000001b << 8) | 00000010b
...将1b
左移8位给出:
100000000b
...和OR {与10b
:
100000010b
现在,pbBuffer[1..2]
中的两个8位整数有一个16位整数:
100000010b = 0x102
答案 1 :(得分:2)
显然,帧长度在第2和第3字节的协议中发送。该表达式构建了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
逐位或(|
)与此处的加法相同,因为(*(pbBuffer+1) << 8)
的低8位全部为0。
请注意,细节略微取决于平台。
答案 2 :(得分: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的情况下在网络上轻松传播 作为中介格式。 (有些计算机在网络字节中工作 本地订购,而其他人必须始终执行转换。)