Variable array size call to add-on instruction - A solution

Mr Modbus

Member
Join Date
Jan 2014
Location
Lincoln
Posts
24
I wanted to have a standard add-on instruction that would take and array (as an in_out parameter). However I wanted it to work with arrays of different sizes, so I could use the same common add-on instruction for processing any number of arrays of potentially different sizes.
After much experimentation I found an ingenious solution that seems to exploit a back door vunerability in the compiler. I thought that I would share it here in case anyone should find it interesting / useful. If any of the RSLogix developers see this then please do not block this method as I am using it!

You define the add-on instruction in_out parameter of array size 1. Actually this can be any size as long as it is not greater then the size of the source array being passed in. But a size of 1 means that it will work with any array size. The call to the add-on instrution has just the array name without a size specified.
Within the add-on instruction, you can now access array indices [2]+ without issue provided that you do not exceed the bounds of the passed-in source array (if you do then expect a major fault). Also, the array index used in the add-on instruction code has to be a variable and not a fixed number (to fool the compiler about the array size). To prevent exceeding the array bounds you have to limit the index to the bounds of the source array. You can use the size instruction (with dim_to_vary = 0) to detect the size of the passed in array and them ensure that your inex variable does not exceed this. The size instruction rather surprisingly gives the size of the passed in array and not the size of the in_out definition. I assume that this works as the add-on instruction has the address of the passed in array as in_out are passed ny refernce not value.
I am surprised that the whole scheme worked though, as I expected that the code would not compile as the index could actually outside of the range specified in the in_out parameter. It certainly will not work if a fixed number is used in place of a variable (e.g. my_arr[2]) as the compiler can check this at compile time. Obviously if a variable is used for the index this cannot be checked at compile time so is slips through the compiler checks.

Here is a worked example:-
Controller / program scope tag:-
BigArr : DINT[100]; // Source array to be accessed

Add-on instruction in_out definition:-
pArr : DINT[1]; // "Pointer" to source array

Add-on instruction local tags:-
ArraySize : DINT; // Sizeof the source array
Index : DINT; // Index into the source array
MyDint : DINT; // Loacl value for test purposes

Add-on instruction code:-
size(pArr,0,ArraySize); // Get actual size of passed in array
for Index := 0 to ArraySize do // For all array elements
MyDint := pArr[Index]; // Extract array element
end_for;
Index := 68;
MyDint := pArr[Index]; // Read specified array element
MyDint := 12345;
Index := 34;
pArr[Index] := MyDint; // Write specified array element

Add-on instruction call:-
MyAOI(AOITag,BigArr); // Call AOI passing in the source array - note no array size specified.
 
Mr Modbus,

While this may work in giving you a variable size, a question for you. What keeps the processor from using this memory array for something else since you did not define the array size?

regards,
james
 
The array size is defined in the passed in array, is it not? Remember in_outs are passed by reference (not by value), so the AOI will be accessing the memory of the source array not a local copy of the array. So it should work IMHO.
 
What makes you thinking that this is a hidden and/or undocumented feature?
This is well defined in AOI user manual.
http://literature.rockwellautomation.com/idc/groups/literature/documents/pm/1756-pm010_-en-p.pdf page 31:

The InOut parameter can be defined to be a single dimension array. When specifying the size of this array, consider that the user of your array can either:
•Pass an array tag that is the same size as your definition.
•Pass an array tag that is larger than your definition.
When developing your logic, use the Size instruction to determine the actual size of the referenced array to accommodate this flexibility.
So don't worry that it will be blocked in future:)
 
Ah, well I must have missed that in the manual. Thank you for pointing it out for me.
I only thought that it was an "undocumented feature" as the compiler deliberately blocked access beyond the local array definition dimensions for fixed address indices (e.g. pArr[2]). So I (quite wrongly) assumed that they didn't want / allow you to access data outside of the local array range. Me making it a variable circumvented this "block", hence why I thought I had found a "back door" route. Useful feature though. :)
 

Similar Topics

I looked into this a little bit a while back but now have an application where it would make life soooo much more simple if this is possible...
Replies
9
Views
3,851
Hello, I have a question, is it possible to display an editable table on an HMI interface? Basically I have a variable: "Dist_Control" with an...
Replies
3
Views
798
Having issues finding how to have a variable tag as an array offset, when that array is part of the FB STAT area and the array is being passed...
Replies
13
Views
2,332
micro 800 array variable subscript micro 800 PLC array subscript: the ladder code when it runs the array does update. first, i...
Replies
3
Views
2,355
hi everyone i have siemens cpu 1214 FW 4.1. i want to use fieldRead for reading 50 USint array variables. if i use 2Hz to enable fieldRead this is...
Replies
1
Views
1,550
Back
Top Bottom