I'm working on code that was transported from a Siemens S5 PLC to S7. The code works with an old FC(FC2 in the example) that uses a WORD-input called "BNR" to load/save data. When block FC2 is called, the BNR-input is simply given a value such as "DBW0", but without an open DB-connection. There's no value in DBW0, so it seems to act as a pointer in the block FC2 where it is used as such:
// Read data from DB to MW250 OPN DB10 L #BNR T MW250 // Execute program and change corresponding bits in MW250 // Write data back to DB OPN DB10 L MW250 T #BNR
In reality more DB's and MW's are used but you get the point. However, I would like to "mask" the FC by creating a new FC(FC300 in the example) that simulates all the unneccesary I/O and simply passes on all the parameters we still need to the old FC2. The BNR-input is renamed to "data" in FC300 for clarity.
The problem is that we cannot pass our "DBW0" 2 levels deep. It works in the first block call for FC300, but when sending #data to the BNR-input, it is interpreted as the value in the opened DB. So BNR loads the value in "DB10.DBW0", wich is a useless value. BNR needs to point to "DBW0" I have tried thinking of a way to turn the whole thing into a pointer but BNR in FC2 is a word which is only 2 bytes.
Even if I could remove the DB-call in FC300 it doesn't solve the problem because this throws a "Area length error when reading" in the diagnostic buffer because the PLC is trying to access #data(in this case DBW0) without a DB open. It's confusing because it does work in OB1 even though no DB is opened.
Simulation of the problem:
OB1 calls FC300(mask) wich calls FC2(old/original FC).
FC300 => data is used as pointer to adress in DB => read/write to DB
I understand "masking" the old FC is probably strange and bad practice, it is also not my desired solution. But some people are so afraid to change code that works(despite it being from 1982) in our company that I'm trying to offer an alternative solution.