RMA
Member
Unlike my usual questions, I've not labelled this one as being S7, because I'm really after a generalised answer. I've only tried asychronous data transfers a few times and it allways finishes up a disaster. Usually I finish up piling one handshake on top of another to cover some problem and then the next problem pops up, until the whole thing collapses under it's own weight.
The problem I've got is that my FM352-5 program works fine (or at least, it appears to) in Debug mode where the program is actually running in an FB in the CPU and the only communication over the backplane is to transfer the state of the I/O - read the inputs and set the outputs to the required state, but not when the program is running in the FM. In the Debug mode case of course, the communication between the FCs which are controlling things and the FB is direct and not over the backplane. When the program is actually running in the FM, then the communication between the two is via two DBs, CPU_In and CPU_Out over the backplane. The program is in each case identical, it is simply recompiled to a form appropriate to the FM's FPGA processor.
I think the first question is, is handshaking the best way of realising this or would I be better off using a simple state machine, as I did for the FTP transfer between the PLC and a PC, which works fine.
However, I would still like to know how to build a bullet-proof asynchronous data transfer with Handshaking.
What I've got at present is the FC sets a New_Data Bit and sets the Data to be transferred in four Data_Bytes in the CPU_Out DB. In the FB (or FM) when this Bit is seen, the FM_Busy Bit is set in the CPU_In DB. The FB/FM program then checks the data for errors and if the data is OK, stores it and sets the OK flag in the CPU_In DB, otherwise the Error_Flag is set. The setting of the OK or Error flag in the FM program also clears the FM_Busy flag.
When the program is running in the FM this will all execute in one cycle, i.e. 1 µs, so that the chance of the FC program seeing the FM_Busy flag is miniscule (Because of the asychronous data transfer over the backplane to the CPU_In DB, it's not quite zero though). Obviuosly, when the program is running in Debug mode in the FB, it will execute very much more slowly and I would guess that the updating of the CPU_IN and CPU_Out DBs is probably no longer truly asynchronous.
The next time the FC is called, after checking the Busy Bit in the CPU_In DB (and exiting if set), it checks to see if the New_Data Bit in the CPU_Out DB AND either the OK Bit OR the Error Bit in the CPU_In DB are set. If not, then the program runs through the New_Data sequence again, and exits. If OK or Error is present, then the program jumps over the New_Data part and instead clears the New_Data Bit and sets the FM_Data_RECD Bit (both in the CPU_Out DB) and sets Merker Flags to tell the calling FC that the data transfer for that module has completed, and whether or not the transfer was OK.
What happens in practice is that in Normal mode, running in the FM, the program gets stuck in an error condition on the first transfer and stops after three retries. However, if I switch to Debug mode, then everything appears to work fine. I suspect a part of the problem might be that at start up in the FM some spurious data condition is causing an error which I am then not clearing properly, but everything I've tried sofar has degenerated into the debacle I mentioned above, with Handshakes on top Handshakes.
I can post the relevant FCs and the FB if necessary, but first off I'd just like to see a generalised (theoretical?) version of how to approach asynchronous data transfer. I'm sure there must be plenty others out there who've also had problems in this area.
The problem I've got is that my FM352-5 program works fine (or at least, it appears to) in Debug mode where the program is actually running in an FB in the CPU and the only communication over the backplane is to transfer the state of the I/O - read the inputs and set the outputs to the required state, but not when the program is running in the FM. In the Debug mode case of course, the communication between the FCs which are controlling things and the FB is direct and not over the backplane. When the program is actually running in the FM, then the communication between the two is via two DBs, CPU_In and CPU_Out over the backplane. The program is in each case identical, it is simply recompiled to a form appropriate to the FM's FPGA processor.
I think the first question is, is handshaking the best way of realising this or would I be better off using a simple state machine, as I did for the FTP transfer between the PLC and a PC, which works fine.
However, I would still like to know how to build a bullet-proof asynchronous data transfer with Handshaking.
What I've got at present is the FC sets a New_Data Bit and sets the Data to be transferred in four Data_Bytes in the CPU_Out DB. In the FB (or FM) when this Bit is seen, the FM_Busy Bit is set in the CPU_In DB. The FB/FM program then checks the data for errors and if the data is OK, stores it and sets the OK flag in the CPU_In DB, otherwise the Error_Flag is set. The setting of the OK or Error flag in the FM program also clears the FM_Busy flag.
When the program is running in the FM this will all execute in one cycle, i.e. 1 µs, so that the chance of the FC program seeing the FM_Busy flag is miniscule (Because of the asychronous data transfer over the backplane to the CPU_In DB, it's not quite zero though). Obviuosly, when the program is running in Debug mode in the FB, it will execute very much more slowly and I would guess that the updating of the CPU_IN and CPU_Out DBs is probably no longer truly asynchronous.
The next time the FC is called, after checking the Busy Bit in the CPU_In DB (and exiting if set), it checks to see if the New_Data Bit in the CPU_Out DB AND either the OK Bit OR the Error Bit in the CPU_In DB are set. If not, then the program runs through the New_Data sequence again, and exits. If OK or Error is present, then the program jumps over the New_Data part and instead clears the New_Data Bit and sets the FM_Data_RECD Bit (both in the CPU_Out DB) and sets Merker Flags to tell the calling FC that the data transfer for that module has completed, and whether or not the transfer was OK.
What happens in practice is that in Normal mode, running in the FM, the program gets stuck in an error condition on the first transfer and stops after three retries. However, if I switch to Debug mode, then everything appears to work fine. I suspect a part of the problem might be that at start up in the FM some spurious data condition is causing an error which I am then not clearing properly, but everything I've tried sofar has degenerated into the debacle I mentioned above, with Handshakes on top Handshakes.
I can post the relevant FCs and the FB if necessary, but first off I'd just like to see a generalised (theoretical?) version of how to approach asynchronous data transfer. I'm sure there must be plenty others out there who've also had problems in this area.