LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Linux select() LabVIEW vi?

Hi all,

 

I am a long-time Linux developer using LabVIEW RT.  I need to IPC with some other Linux userspace apps.  I would like to use named pipes for this.  I would also like to have multiple file descriptors for the IPC (so that I can easily section out the data types).  In doing this, I would need to use the same type of code that Linux's select(2) does.  I see that, through the use of the IPC add-on package, there is an implimentation of epoll.  I cannot seem to figure out how to link the named pipe fd to the epoll set.  Then, in another post about 1024 TCP connections, I see that the use of select(2) is favored over epoll (as it is in the Linux community at large).

 

What is the correct way to wait on multiple file descriptors in LabVIEW?  And, would you please point me to the correct VIs for this implementation?

 

Thank you in advance for any help you are willing to provide.

 

Andy

0 Kudos
Message 1 of 10
(1,584 Views)

I don't know if this is the "right" solution, but we did find a solution.  Within the VI for the named pipe (the output of which is some other data structure pointer), we found the FD we're needing to connect into the epol group.  With that, we're able to connect multiple of these files together into a single wait group.

 

If this is the WRONG way, or if there is a better way (the NI "right" way), please let me know.

 

Thanks!

Andy

0 Kudos
Message 2 of 10
(1,571 Views)

@MAKennedy wrote:

I don't know if this is the "right" solution, but we did find a solution.  Within the VI for the named pipe (the output of which is some other data structure pointer), we found the FD we're needing to connect into the epol group.  With that, we're able to connect multiple of these files together into a single wait group.

 

If this is the WRONG way, or if there is a better way (the NI "right" way), please let me know.

 

Thanks!

Andy



I think there is no right or wrong here. What you try to do is highly non-standard and usually not even attempted since 99% of users use LabVIEW because they specifically do not want to get bothered by having to call platform APIs.

 

In the end LabVIEW has to do exactly this of course as it can not invent its own OS. It just generally hides this complexity. I haven’t looked at the LabVIEW Pipe functions on Linux in a long time so it may or may not interface directly to OS functions through the Call Library Node. If it does you can find what element is supposed to be the fd behind the Pipe “refnum” and use it. This is what you seem to have done. In that respect it is not wrong. It even seems to work! However you should note that the Call Library Node is an advanced feature. There is no safety net and fire brigade making sure you did not make any error in the configuration of this node. If that configuration doesn’t match the actual function implementation in exactly, your code will likely corrupt memory in some way or in certain cases behave wrong. The difficulty here is that even if it doesn’t crash and seems to work correctly it still may be not fully correct and show problems under different conditions.

 

As seasoned C programmer you have of course a good chance to have gotten the Call Library configuration correctly but it is something you should be aware of. Rather check the configuration 3 times to much than later having to hunt nasty crashes and weird application behavior!

 

And those diagrams in those shipping LabVIEW VIs may be unlocked but you still need to consider its contents private implementation details. A future LabViEW version may decide to implement the whole Pipe functionality in a different way. If they ever go to the trouble of adding Pipe functionality for Windows too, those VIs could completely change. The calling interface will stay compatible but the diagram implementation may simply call a LabVIEW specific shared library or actually build in LabVIEW nodes (those light yellow icons that you can not open) and your fd access may get impossible then.

Rolf Kalbermatter
My Blog
0 Kudos
Message 3 of 10
(1,546 Views)

Thanks for that, rolfk!  Yes, I expect that the implementation of the underlying library calls could change (we have that possibility in most any library we ever use, though the base level of the SYSV seems to be rather stable with open, close, read, write).  As for epoll, not sure why this was exposed by the NI developers over select(), but I suppose they have their reasons.

 

Your warnings are duly noted.  I don't know of a time when, in embedded/system developement, I've ever used an API the "way it was intended" by the developers of said API. 😉

 

But, again, thank you for your time in considering my question and formulating a response.  The frustrating part of this is knowing that, since I have Linux under the hood, I know what I CAN do on the system, but through the iconic programming interface, I cannot find HOW to do it...  That is, I suppose, one drawback of using LabVIEW coming from a strong C background.  The mapping is not 100% to the system.  And as far as named pipes on Winders:  I didn't know that was a thing.  I looked it up.  Sure enough, it exists.  The part that interests me most there is that, in Linux, there are special files called nodes.  These nodes are actually links into kernel drivers.  So, these named pipes in Windows must be syscalls to the OS without generating an actual file.  I dunno, though, as I'm not really an Windows developer.

 

Andy

0 Kudos
Message 4 of 10
(1,529 Views)

Pipes are under Windows simply another kind of kernel objects. And just as under Linux/Unix they can be named or unnamed. Basically a lot of the Windows NT kernel was at some point trying to implement as much as possible about the Posix standard as that was considered the IT standard of everything. Pipes was one part of this. The exact workings underneath are of course different. Windows does not use inodes for instance but as mentioned uses basically kernel objects for all possible resources.

 

The semantics of Windows pipes is however very much Posix like, although there can be subtle differences sometimes. And there is always the chance that it is actually fully Posix compatible but simply a slightly different interpretation of that standard which still is fully within the standard description.

 

I did create an OpenG project to work with pipes and made it multi platform to offer the same interface under Linux and Windows. It looks very similar to the LabVIEW Pipe VIs but has its own name space and a few extra features. The beef of the implementation is inside a shared library that is called by the VIs through Call Library Nodes. I chose for this for a few reason:

 

1) Back when I started that project, the multi platform support in LabVIEW was not as fully fledged as it is nowadays. You did not have conditional compile structures to easily separate completely different code paths for different platforms. The LabVIEW Call Library Node had several limitations to easily deal with different calling modes and parameter types.

 

2) Trying to do Windows API calls in pure LabVIEW code through Call Library Nodes is quite an effort. Trying to do the same for Unix APIs is at least one magnitude more effort. And trying to that also for the MacOS platform used to be (and even in MacOS X nowadays) is yet another magnitude more complicated. It's a lot easier to keep all that sheenigan in the C source code and simply provide a common calling API for LabVIEW that is on all platforms exactly the same.

 

I did never release that OpenG Pipe library since my testing showed that there are still subtle problems with the code. For instance under certain not very clear conditions the creation of pipes could fail under Windows or the first Read would timeout without any clear reason. There was incidental interest in that library but nobody who could provide clear feedback as to when things went wrong and why. For what I used the library, it seemed to work but for others there could be problems.

 

But the code is still out there on the Sourceforge OpenG Toolkit repository. Yes, it's that old, when Sourceforge was actually still a viable source code control site, before Slashdot Media took it over and made an advertisement site out of it.

 

Rolf Kalbermatter
My Blog
Message 5 of 10
(1,516 Views)

OH!  So are you the developer of the IPC that I'm using!?!?!?!?  -- that is what I got from your post.

 

And, you are giving me new information that I didn't know.  What I heard:  I can use standard libc calls within LabVIEW by creating VI implentations of the libc functions.  Is there an example laying around of how to do this?  I'm apparently too new to LabVIEW to know the correct terms to search for the correct how-tos.  A lmgtfy.com link would not be offensive at this time ;).

 

If I have that ability, this greatly simplifies my life.  I would the be able to write "C" code in LabVIEW.  Yes, I know this is definiately off the beaten path, but this is where I need to be.  I have two problems:  the C-API from NI for the cards that I'm using doesn't exists.  I have other external Linux APIs that I'm adding to the system that don't exist in LabVIEW (nor are they likely to EVER be needed by anyone else, thus, NI would never port those over).  So, I'm stuck in the middle.  My intent is to develope the LabVIEW code as a user-space driver in Linux (using the named pipes as the IPC), then interfacing the TCP connections I need from the Linux stack.

 

This way, I get the LabVIEW driver resources I need and the Linux resources I need all in one.  BUT, if I have a way to expose .so function calls in LabVIEW, that may be a game changer.


Andy

0 Kudos
Message 6 of 10
(1,510 Views)

I'm working with someone else here on this... He's been working with LabVIEW for a few months.  I think he may have shown me the way.

 

What I'm seeing:  there is an object "LabVIEW" that appears to be the final linkage between LabVIEW and the LVRT app.  Within this is the .sos that are linked to the final application.  I can specify any function within this by using the function definition block -- I haven't yet tried to define a new one, but I'm seeing this within some of these VIs.  Using this knowledge, we're about to venture into the dark with wrappering the C library calls using our own VIs.

 

Within the IPC we have, we've noted that epoll is used everywhere (to make sure that nothing blocks).  This is exactly opposite of what we want to do.  We want every function call to block until data is present.  There is nothing that should happen within our LVRT without it being triggered from the external environment.

 

I think you have unlocked my LabVIEW world and have made me dangerous.  Thank you SOOOOOO much for that!

 

Andy

0 Kudos
Message 7 of 10
(1,498 Views)

... I keep posting my own stuff (sorry all).

 

I'm confused about the path constant I'm seeing inside all of these function definitions.  It has "LabVIEW".  I'm sure this has a special meaning...  what is it?

 

My conjecture is that the meaning is to "Use the settings within the project" OR to use the default LabVIEW settings... though, this is baseless.

 

At the moment, all of the calls I'm attempting to reproduce are from the standard C library (libc.so).  So, I'm hoping that the path "LabVIEW" will just be the right thing.

 

Andy

0 Kudos
Message 8 of 10
(1,468 Views)

LabVIEW is the special keyword that tells the Call Library Node to refer to the LabVIEW exported manager functions. LabVIEW itself exports more than 1000 funcfions, some of them are needed by the LabVIEW execution system itself and some are documented in the LabVIEW External Code manual. Most of the documented functions are related to memory management, file handling and path handling.

 

Depending on if the VI code executes in the IDE or in a build executable this keyword will cause the Call Library Node to refer to LabVIEW.exe or lvrt.dll on Windows and the according LabVIEW. shared library executable image on other platforms. So all these Call Library Nodes with the LabVIEW name as library name simply call back into LabVIEW functions. But you also can enter libc.so in there and then call functions from that shared library. Sometimes NI exports thin wrappers around platform APIs under the exact same or similar name. The reason likely is that different Unix platforms have different function names or semantics and rather than trying to solve that on diagram level with constant conditional code structures they simply do it in the LabVIEW C source code, which has zillions of such conditional compile code sections already.

 

And no, the VIs you work with are almost certainly not from me. NI released a Pipe library with earlier Unix variants of LabVIEW (for Sun Solaris and HP Unix) and when they finally released LabVIEW for Linux in the early 2000ers, they also shipped LabVIEW for Linux with that Pipe library.

 

I was trying to use Pipes under Windows and developed my own version. The VIs were designed to look similar than the NI ones but the implementation was quite different. I wrote a C code library that exported a platform independent interface to LabVIEW but used the platform specific APIs through conditional C preprocessor statements. This was then compiled into the platform specific  shared library format (DLL for Windows, ELF shared library for Linux) and accessed through the Call Library Node in LabVIEW.

Rolf Kalbermatter
My Blog
0 Kudos
Message 9 of 10
(1,458 Views)

If you feel really adventurous, you may want to check out this library here. It is however very old and the package building predates VIPM by a very long time.

 

https://sourceforge.net/p/opengtoolkit/svn/HEAD/tree/trunk/lvpipe/

Rolf Kalbermatter
My Blog
0 Kudos
Message 10 of 10
(1,452 Views)