slave=0 adr=192.168.1.99 type=S7_1200 fetch_write=0 function=1 rack_slot=0
在pvbrowser里设置与PLC连接的时候有一项fetch_write,下面具体看一下这一项
446 if((plc_type == S5 || plc_type == S7_300 || plc_type == S7_400) && fetch_write == 1)
447 {
448 length = sizeof(ih) + sizeof(fh);
449 ih.version = 3;
450 ih.reserved = 0;
451 ih.length_high = length / 256;
452 ih.length_low = length & 0x0ff;
453 fh.ident[0] = 'S';
454 fh.ident[1] = '5';
455 fh.header_len = 16;
456 fh.ident_op_code = 1;
457 fh.op_code_len = 3;
458 fh.op_code = 5;
459 fh.ident_org_block = 3;
460 fh.len_org_block = 8;
461 fh.org_block = (unsigned char) org;
462 fh.dbnr = (unsigned char) dbnr;
463 fh.start_adr[0] = (unsigned char) start_adr / 256;
464 fh.start_adr[1] = (unsigned char) start_adr & 0x0ff;;
465 fh.len[0] = (unsigned char) len / 256;
466 fh.len[1] = (unsigned char) len & 0x0ff;;
467 fh.spare1 = 0x0ff;
468 fh.spare1_len = 2;
469 unsigned char total_buf[sizeof(ih)+sizeof(fh)];
470 memcpy(total_buf, &ih, sizeof(ih));
471 memcpy(total_buf+sizeof(ih), &fh, sizeof(fh));
472 ret = rlSocket::write(total_buf, sizeof(ih)+sizeof(fh));
473 rlDebugPrintf("fetch write ih ret=%d\n",ret);
474 if(ret < 0) return ret;
475 /*
476 ret = rlSocket::write(&ih,sizeof(ih));
477 rlDebugPrintf("fetch write ih ret=%d\n",ret);
478 if(ret < 0) return ret;
479 ret = rlSocket::write(&fh,sizeof(fh));
480 rlDebugPrintf("fetch write fh ret=%d\n",ret);
481 if(ret < 0) return ret;
482 */
483 ret = rlSocket::read(&ih,sizeof(ih),TIMEOUT);
484 rlDebugPrintf("fetch read ih ret=%d\n",ret);
485 if(ret <= 0) return ret;
486 ret = rlSocket::read(&fa,sizeof(fa),TIMEOUT);
487 rlDebugPrintf("fetch read fa ret=%d\n",ret);
488 if(ret <= 0) return ret;
489 if(fa.error_block != 0) return -1;
490 ret = rlSocket::read(buf,len_byte,TIMEOUT);
491 rlDebugPrintf("fetch read buf ret=%d\n",ret);
492 if(ret <= 0) return ret;
493 }
if((plc_type == S5 || plc_type == S7_300 || plc_type == S7_400) && fetch_write == 1)
首先判断PLC是不是S5,300和400系列。Fetch/Write只支持这些系列,对于像1200,200smart这些是不支持的。
并且,在300和400系列中,对于CP343-1,CP443-1是支持Fetch/Write的,对于内嵌Ethernet的CPU需要配置一下。如何配置请查看西门子官方文档《FETCH/WRITE service in an S7-300/400 CPU via the integrated Ethernet interface》.
如果不是这些系列的PLC或者fetch_write=0时,则是S7通讯.
In today’s automation technology old systems are upgraded step by step from SIMATIC S5 to SIMATIC S7. However, the interfaces for the data exchange on the peer (for example, existing HMI systems) are to be kept. The FETCH/WRITE service is still very frequently used for the communication via Industrial Ethernet. The communication processors (CP343-1/CP443-1) of SIMATIC S7 support the services FETCH and WRITE for data exchange on the following protocols:
- TCP
- ISO-on-TCP
- ISO transport
However, CPUs with integrated Industrial Ethernet interface are increasingly used in S7-300 and S7-400 stations to connect these to the Industrial Ethernet network and to exchange data with other nodes in the network. The FETCH/WRITE services have not been implemented here.
The SIMATIC S7 supports the FETCH and WRITE services only passive via the TCP native and ISO-on-TCP protocol. Furthermore, the SIMATIC S7 CPUs with integrated Industrial Ethernet interface do not support the S5 compatible communication.
rlSiemensTcp有四个结构体WH,WA,IH,IA
182 typedef struct
183 {
184 unsigned char ident[2];
185 unsigned char header_len;
186 unsigned char ident_op_code;
187 unsigned char op_code_len;
188 unsigned char op_code;
189 unsigned char ident_org_block;
190 unsigned char len_org_block;
191 unsigned char org_block;
192 unsigned char dbnr;
193 unsigned char start_adr[2];
194 unsigned char len[2];
195 unsigned char spare1;
196 unsigned char spare1_len;
197 }WH; // write header
198 typedef struct
199 {
200 unsigned char ident[2];
201 unsigned char header_len;
202 unsigned char ident_op_code;
203 unsigned char op_code_len;
204 unsigned char op_code;
205 unsigned char ack_block;
206 unsigned char ack_block_len;
207 unsigned char error_block;
208 unsigned char spare1;
209 unsigned char spare1_len;
210 unsigned char spare2[5];
211 }WA; // write ack
212 typedef struct
213 {
214 unsigned char ident[2];
215 unsigned char header_len;
216 unsigned char ident_op_code;
217 unsigned char op_code_len;
218 unsigned char op_code;
219 unsigned char ident_org_block;
220 unsigned char len_org_block;
221 unsigned char org_block;
222 unsigned char dbnr;
223 unsigned char start_adr[2];
224 unsigned char len[2];
225 unsigned char spare1;
226 unsigned char spare1_len;
227 }FH; // fetch header
453 fh.ident[0] = 'S';
454 fh.ident[1] = '5';
455 fh.header_len = 16;
456 fh.ident_op_code = 1;
457 fh.op_code_len = 3;
458 fh.op_code = 5;
459 fh.ident_org_block = 3;
460 fh.len_org_block = 8;
461 fh.org_block = (unsigned char) org;
462 fh.dbnr = (unsigned char) dbnr;
463 fh.start_adr[0] = (unsigned char) start_adr / 256;
464 fh.start_adr[1] = (unsigned char) start_adr & 0x0ff;;
465 fh.len[0] = (unsigned char) len / 256;
466 fh.len[1] = (unsigned char) len & 0x0ff;;
467 fh.spare1 = 0x0ff;
468 fh.spare1_len = 2;
这是rlSiemensTcp::fetch的部分内容,符合上图,这里构造好报头以后就可以通过Socket通讯连接了.
228 typedef struct
229 {
230 unsigned char ident[2];
231 unsigned char header_len;
232 unsigned char ident_op_code;
233 unsigned char op_code_len;
234 unsigned char op_code;
235 unsigned char ack_block;
236 unsigned char ack_block_len;
237 unsigned char error_block;
238 unsigned char spare1;
239 unsigned char spare1_len;
240 unsigned char spare2[5];
241 }FA; // fetch ack
The FETCH and WRITE services are used for the data exchange by means of the following protocols:
- TCP
- ISO-on-TCP (TCP with RFC1006)
- ISO Transport protocol
The SIMATIC S7 CPUs with integrated Industrial Ethernet interface do not support the ISO transport protocol. Here the FETCH and WRITE services for the data exchange are only supported via TCP and ISO-on-TCP protocol.
The FETCH/WRITE client actively establishes the communication
connection. It requests the data from the FETCH/WRITE server by means of a FETCH request. The server responds with a positive acknowledgement of the FETCH request and sends the requested data. Otherwise, the acknowledgement of the FETCH response is negative.
The FETCH/WRITE client sends a WRITE request with the data required in the FETCH/WRITE server. If the data has been successfully transmitted, the FETCH/WRITE server responds with a positive acknowledgement. Otherwise, the acknowledgement of the WRITE request is negative.