逐行解释 int i,j; // 处理返回数据 if( len>0 ) { switch( funcNo ) { case ModbusFunc_ReadCoilStatus: case ModbusFunc_ReadInputStatus: if( buffer[0]!=(len-1) ) { // 返回数据长度错误 KFprintf("CmYd400vModR::procBackFrame[ back frame error: len field not correct. back=%d, should=%d ]\n",buffer[0],len-1); return -1; } // 读取遥信 for( i=1;i<len;i++ ) { // 按位计算地址并保存遥信 for( j=0;j<((len-1 == i && getYXCollNum()%8 != 0) ? getYXCollNum()%8 : 8);j++ ) { saveCollData(cmdPdu.func(),cmdPdu.getStartAddress()+(i-1)*8+j,(buffer[i]&(0x01<<j))?1:0); } } break; case ModbusFunc_ReadHoldReg: case ModbusFunc_ReadInputReg: { if( buffer[0]!=(len-1) ) { // 返回数据长度错误 KFprintf("CmYd400vModR::procBackFrame[ back frame error: len field not correct. back=%d, should=%d ]\n",buffer[0],len-1); return -1; } // 读取测量值 BYTE* pBuf = &buffer[1]; int32 num = 0; for( i=0;i<buffer[0]/2;i++ ) { if (num >= buffer[0]) { KFprintf("%s-%d buffer[0]=%d\n",__FILE__,__LINE__,buffer[0]); break; } int bnum = 1; GetBitNums(cmdPdu.func(),cmdPdu.getStartAddress()+i,2,0,&bnum); if (bnum == 0) { continue; } int m; uint32 ivalue = 0; ivalue = MAKEONEDWORD(pBuf[num],pBuf[num +1],pBuf[num+2],pBuf[num +3]); int32 svalue = *((uint32*)&ivalue); num +=4; saveCollData(cmdPdu.func(),cmdPdu.getStartAddress()+i,svalue); } } break; default: return -1; // 未处理 } } return 0; }
时间: 2024-04-19 15:28:12 浏览: 115
采用事件通知形式的重叠I/O操作模型
这段代码是在处理返回的数据。
逐行解释代码如下:
1. `int i,j;` - 声明两个整型变量`i`和`j`,用于后续的代码逻辑。
2. `if( len>0 )` - 如果接收到的数据长度大于0,则执行下面的逻辑。
3. `switch( funcNo )` - 根据功能码`funcNo`进行分支判断。
4. `case ModbusFunc_ReadCoilStatus:`和`case ModbusFunc_ReadInputStatus:` - 如果功能码是读线圈状态或读输入状态。
5. `if( buffer[0]!=(len-1) )` - 如果返回的数据长度不等于`(len-1)`,即数据长度错误。
6. `KFprintf("CmYd400vModR::procBackFrame[ back frame error: len field not correct. back=%d, should=%d ]\n",buffer[0],len-1);` - 输出错误信息,并返回-1。
7. `for( i=1;i<len;i++ )` - 遍历接收到的数据中的每个字节。
8. `for( j=0;j<((len-1 == i && getYXCollNum()%8 != 0) ? getYXCollNum()%8 : 8);j++ )` - 遍历每个字节中的每个位。
9. `saveCollData(cmdPdu.func(),cmdPdu.getStartAddress()+(i-1)*8+j,(buffer[i]&(0x01<<j))?1:0);` - 调用`saveCollData`函数保存遥信数据。
10. `break;` - 结束当前分支。
11. `case ModbusFunc_ReadHoldReg:`和`case ModbusFunc_ReadInputReg:` - 如果功能码是读保持寄存器或读输入寄存器。
12. `if( buffer[0]!=(len-1) )` - 如果返回的数据长度不等于`(len-1)`,即数据长度错误。
13. `BYTE* pBuf = &buffer[1];` - 声明一个指针`pBuf`指向数据中的第一个字节。
14. `int32 num = 0;` - 声明一个整型变量`num`初始化为0,用于记录当前处理到的数据字节位置。
15. `for( i=0;i<buffer[0]/2;i++ )` - 遍历每个寄存器。
16. `if (num >= buffer[0])` - 如果当前处理到的数据字节位置超过了数据长度,则跳出循环。
17. `int bnum = 1;GetBitNums(cmdPdu.func(),cmdPdu.getStartAddress()+i,2,0,&bnum);` - 调用`GetBitNums`函数获取每个寄存器中有效位的数量。
18. `if (bnum == 0)` - 如果有效位数量为0,则跳过当前寄存器的处理。
19. `uint32 ivalue = 0;ivalue = MAKEONEDWORD(pBuf[num],pBuf[num +1],pBuf[num+2],pBuf[num +3]);` - 将4个字节的数据合并为一个32位的无符号整数值。
20. `int32 svalue = *((uint32*)&ivalue);num +=4;saveCollData(cmdPdu.func(),cmdPdu.getStartAddress()+i,svalue);` - 将32位的无符号整数值转换为有符号整数值,并调用`saveCollData`函数保存测量值数据。
21. `break;` - 结束当前分支。
22. `default:` - 默认情况,如果功能码不是上述情况。
23. `return -1;` - 返回-1,表示未处理该功能码。
24. `return 0;` - 返回0,表示处理成功。
阅读全文