12-06-2010 12:01 PM
My code WORKS PERFECTLY under LabVIEW 8.6 (and LVRT 8.6).
It fails under LabVIEW 2010 (with LVRT 2010).
Here's what I'm trying to do:
My program uses "plug-ins" - stand-alone VIs to do some calculation during data acquisition.
For example, there is a measured SPEED channel and a measured TORQUE channel.
A plug-in VI called POWER calculates speed * torque / 5252.1 and produces POWER.
This is then treated just like it was another measured channel, they can record it, plot it, set alarms on it, anything they can do with a real measured channel, they can do with this artificial channel.
I'm sampling at 10 Hz, each sample causes a run of the plug-in and produces a new POWER sample.
The plugins use a TYPEDEF (called "Units") that has various units defined ("Hp", "kW", "Lb/hr", "ppm", etc).
They might use a subVI or two. I've made sure those are in the compiled executable.
The Real-Time program (called RTEC) does all the sampling, from various PXI boards and UDP sources. The HOST program calls for a channel called POWER, and provides a "signature" (hash value) for the VI that is on the host machine. RTEC compares the signature sent with it's own signature on file and decides if the version is the same. If not, it asks the host to send the whole VI (which is does, as a text block), and stores the VI file locally, along with the signature.
RTEC does the sampling and sends the data to the host. The host records it into a disk file. Along with the data itself, a header (containing setup information) is part of the data file, and also a copy of the plug-in VIs themselves. I do this to guarantee that the calculation used to produce the data is preserved as it is.
When reviewing the file, the user can edit some things (scale factors for instance) and re-process the data, that means re-running the plugins on the host.
The critical point here is that these are plug-ins - I do not want the user to have to open the main project and insert some vI into the project and build a source distribution.
The way it works now is that the user can create his subVI from a template. The template has the workings except for the calculation itself. ALl he has to do is specify that he wants "Engine Speed" in RPM and "Engine Torque" in Ft-lb, and it produces results in "Hp". He then does the multiplication, saves the VI, drops it into a specific folder on the host, and all else is automatic.
ALL THIS WORKS PERFECTLY in LV 8.6.
However, in LV2010, I get an error -1003 in a compiled RTEXE. If I run the RTEC program from the host environment (just clicking on the RUN arrow on the host), all is well. But we need to run compiled, as every host will not have a DevSys.
I have boiled it down to a simple test case - see attached pic.
If I OPEN the VI REF without a TYPE specifier, it works in either case (compiled or RTEXE), but I cannot later run the reference since it's not STRICT.
I tried both a GENERIC and a TEMPLATE reference, since I was first thinking that one was working and not the other, but they seem identical now.
The program works fine in the DevSys, but compile it to an RTEXE and I get error 1003 for the latter two cases.
I have read <a href="http://digital.ni.com/public.nsf/allkb/10F1D411ACBAD3D9862572FF0064C801">this</a>, <href="http://digital.ni.com/public.nsf/allkb/410F2EC66F60F9B0862569EE006F4FA0">this</a> , and <a href="http://digital.ni.com/public.nsf/allkb/0537EAF7F167718386256A96005D1DBC">this</a>.
What I get out of those is that maybe this is a "security" enhancement: it's no longer legal for a plug-in to call code or use typedefs from a compiled master app, whereas it was before.
QUESTION 1: Is that a fair interpretation?
I am guessing that the DevSys is handling this for me, but the RTEXE is unable to (since there is no compiler).
So, if I define ahead of time which TYPEDEFs and subVIs are permitted to be called from my plug-ins, and store a separate copy of those, I have to duplicate that relative path on the RTEXE. If I don't, the signature process will fail (if the path is changed, the signature of the VI will change).
QUESTION 2: Is that a reasonable statement?
And I have to duplicate the same folder of dependent stuff at REVIEWING time, since the exact same VI, extracted from the data file, must be executed by the reviewer on the host.
QUESTION 3: Is that a true statement?
QUESTION 4: Is there a better way? Right now (8.6) the fact that the VI wants to load a TYPEDEF from C:\Users\Steve|Projects\HDT\Libraries\HDT Units.llb\HDT Units.ctl and instead finds it in C:HDT\RTEC.rtexe\HDT Units.ctl (on the PXI box) , or in C:\Whatever\HDT Reviewer.exe (at REVIEWING time) is all automatic, invisible, and not a problem.
Apparently that's not so easy anymore.
Blog for (mostly LabVIEW) programmers: Tips And Tricks
12-10-2010 12:02 PM
OK, NI Tech Support has been completely useless on this one, and nobody in the forum had ideas, so I had to work all week on it, but I have figured out the root problem. Here it is for anyone who's interested.
It definitely IS still legal to call INTO an executable, my conjecture that it was no longer legal was wrong.
I stumbled across the solution when I discovered that the setting DISCONNECT TYPEDEFS in the BUILD SPEC made a difference. If I tuned OFF the DISCONNECT switch, everything started working. The RTEXE size went from 2.2 Meg to 3.4 Meg, but at least it worked.
Not willing to live with that bloat, I kept chasing the real problem, now knowing that it was NOT a un-findable subVI, but a TYPEDEF that was the problem.
I turned the DISCONNECT TYPEDEF switch back ON, and stripped ALL the code from my plugin. Problem remains.
That suggests that it was with a TYPEDEF, not a subVI.
Two of the terminals of my plugins are TYPEDEFs.
I disconnected one (UNITS.ctl ) on a plugin, and got no change.
I disconnected the other (Channel Preqrequisite.ctl), and got no change.
But the Channel Prerequisite is a cluster, which contains a UNITS.ctl.
When I disconnected THAT, then it started working.
That confirms that it's a TYPEDEF problem (as suggested by the DISCONNECT TYPEDEFS fixing it).
What I had thought (and maybe it was true in LV 8.6) was that having an INSTANCE of a typedef'ed control in the MAIN was sufficient to make the plugins happy.
That is NOT the case. I suspect that this is a change in LV2009/2010 behavior, as I didn't have this problem in 8.6.
I knew that there were instances of the TYPEDEF'ed controls elsewhere in the MAIN, but, since we're DISCONNECTING TYPEDEFS, then the actual definition is not there.
To fix the problem, while still keeping DISCONNECT TYPEDEFS set to ON, I placed a STATIC VI REFERENCE in the main program, pointing to each DEFINITION (one to UNITS.ctl, one to CHANNEL PREREQUISITE.ctl), and it all works.
It works whether 8.X Layout is ON or OFF.
It works whether I run from an RTEXE or from the DevSys.
It works with the DISCONNECT TYPEDEFS setting ON (or off).
Whew!
Blog for (mostly LabVIEW) programmers: Tips And Tricks
12-10-2010 12:28 PM
i have been on the road Steve so late to the game...
I believe there is also an option realted to the file system included in the build that lets you use the old file format when building. Not sure if it would have helped you but it has haled in some of my upgraded builds.
Regardless, THank YOU for that post. It may be of use when I cross that bridge myself.
Ben
12-10-2010 01:12 PM
there is also an option realted to the file system included in the build that lets you use the old file format when building
Yes. Tech support pushed that, but it turns out to have no effect in my case. The real issue was that the TYPEDEF was being stripped (by virtue of the DISCONNECT TYPEDEFS switch). Since the plugin (not compiled with that option) called for a TYPEDEF, and since there wasn't a TYPEDEF available, it was unhappy.
Too bad the ERROR 1003 couldn't say something like "ABC.vi is not executable because it couldn't find XYZ.ctl"; then it would have saved me oodles of time.
Blog for (mostly LabVIEW) programmers: Tips And Tricks