-
Posts
3,871 -
Joined
-
Last visited
-
Days Won
262
Content Type
Profiles
Forums
Downloads
Gallery
Everything posted by Rolf Kalbermatter
-
TCP Listener: can it fail?
Rolf Kalbermatter replied to drjdpowell's topic in Remote Control, Monitoring and the Internet
If the socket library or one of its TCP/IP provider sub components resets itself, for whatever reason, it is definitely possible that a listener could report an error. This could happen because the library detected an unrecoverable error (TCP/IP is considered such an essential service on modern platforms that a simple crash is absolutely not acceptable whenever it can be avoided somehow) or even when you or some system component reconfigures the TCP/IP configuration somehow. My TCP/IP listeners are actually a loop that sits there and waits on incoming connections as long as the wait returns only a timeout error. Any other error will close the listener refnum and loop back to the Create Listener before going again into the Wait Listener state. The Wait on Listener doesn't return an error cluster just to report that there is no new connection yet (timeout error 56) but effectively can return other errors from the socket library, even though that is rare. In case of any other errors than timeout, I immediately close the refnum, do a short delay to not let the loop monopolize the thread if the socket library should have another condition than a temporary hiccup, and then go back to Create Listener state until that succeeds. It's a fairly simple state machine but essential to continuous TCP/IP operation. Technical details: the Wait on Listener basically does a select() (or possibly poll()) on the underlaying listener socket and this is the function that can fail if the socket library gets into a hiccup. -
Not the VI itself but if you have enabled to separate compiled code from the VI and since it is at a different path location, it is considered different to the original VI as far as the compile cache is concerned. And therefore since there is no compile cache entry for that VI yet, LabVIEW will recompile the VI.
-
Basically all OpenG libraries before version 4.0 were LGPL licensed. With 4.0 the license for the VI part was changed to be BSD-3. The libraries which use a shared library/DLL have different licenses for the shared library and the VIs. The shared library remained LGPL which should not be a problem as long as you post a link to the OpenG project. For libraries version 4.0 and higher this is the git link mentioned by Jim, for older libraries this is the sourceforge link.
-
As mentioned. the library was a quick hack to another earlier library to add the bitwise operators. And it was likely a bit a to quick hack, messing up a few other things in the process. As you don't use bitwise operators I would recommend you to look at the original library, to which a link is included in that post.
- 172 replies
-
NI Linux RT Scheduler vs PharLap or Win10
Rolf Kalbermatter replied to Petr Mazůrek's topic in Linux
No flame from me for this. Under your constraint (only ever write from one place and never anywhere else) it is a valid use case. However beware of doing that for huge data. This will not just incur memory overhead but also performance, as the ENTIRE global is everytime copied even if you do right after an index array to read only one element from the huge array. -
Nope! You have to do it like in the lower picture. And while the order "should" not matter, it's after all the intend of using reference counts to not allow a client to dispose an object before all other clients have closed it too, I try to always first close the sub objects and then the owner of them (just as you did). There are assemblies and especially ActiveX automation servers out there who don't properly do ref counting and may spuriously crash if you don't do it in the right order.
-
I can't right now work on that. But I have plans to do that in the coming months. The story behind it is that I did a little more than just to make it 64-bits. - The file IO operations where all rewritten to be part of the library itself rather than relying on LabVIEW file IO. While LabVIEW 8.0 and newer supports reading and writing files that are bigger than 2GB, it still has the awful habit to use internally old OS file IOs that are naturally limited to only supporting characters in file names that are part of your current local and they also normally are limited to 260 character long path names. If your drive is formatted in FAT32, that is all the drive can do for you anyhow, but except for USB thumb drives, you would be hard pressured to find any FAT formatted drives anymore. So having these limitations in the library feels very bad. These two things are specially a problem on Windows. Mac is slightly less problematic and Linux has long ago pretty much solved it all internally in the kernel and surrounding system libraries. - Modern ZIP files support things like symbolic links and I wanted a way to support them. For Linux and Mac that is a piece of cake. For Windows I may for now not be able to seamlessly support that as creating symlinks under Windows is a privileged action, so the user has to either be elevated or you have to set an obscure Developer flag in Windows that allows all users to create symlinks. So in summary there was a lot of work to be done, most of it actually for Windows. Most of that is done but testing all that is a very frustrating job. And the non-Windows targets will then also take some more time for additional testing and making things that were modified for Windows compile again properly. So yes, it's still on my to-do list and I'm planning to work on it again, but right now I have another project that requires my attention. Because of the significant changes in the underlying shared library and internal organization of the VIs it will be almost certainly version 5.0. The official library API (those nice VIs with a green gift box in them) should remain compatible but if you want to make use of the new path name feature to fully support long path names with full character support, you may have to change to the new API, with the library specific path type, although if you use high level library functions, internal long path names will be ok, you just won't be able to access them with the normal LabVIEW file functions if they contain non local ANSI characters or are to long! It's the best I could come up with without the ability to actually changing the LabVIEW source code itself to add that feature into the internal Path Manager in LabVIEW. 😀 The according File Utilities Manager functions in the library will also be available for the user in a separate palette.
-
Lets suppose you create a .Net Image object. That image can potentially use many megabytes of memory. Any reference you obtain for that image will refer to the same image of course so references don't multiply the memory for your image, but LabVIEW will need to create a unique refnum object to hold on to that reference and that uses some memory, a few dozen bytes at most. However every such refnum holds a reference to the object and an object only is marked for garbage collection (for .Net) or self destructed (for ActiveX) once every single reference to it has been closed. So leaving a LabVIEW refnum to such an object open will keep that object in memory until LabVIEW itself terminates the VI hierarchy in which that refnum was created/obtained/opened, as LabVIEW does register every single refnum in respect to the top level VI in whose hierarchy the refnum was created and when that top level VI goes idle (terminates execution), the refnum is closed and the underlying reference is disposed. And to make matters even worse, if such an object somehow obtained a reference to one or more other objects, those objects will remain in memory too until the object holding those references is closed, and that can go over many hierarchy levels like this, so a single lower level object can potentially keep your entire object hierarchy in memory. If and how an object does that is however specific to that object and seldom properly disclosed in the documentation, so diligently closing every single refnum as soon as possible is the best way to make this manageable. Yes, aside for real UI programming I consider use of locals and globals a real sin! Ah oui carrément ! Vous n'utilisez jamais de variables globale ou local ? Vous faites que des FGV? In fact the only globals I allow in my programs nowadays are booleans to control the shutdown of an entire system or "constants" that are initialized once at startup from a configuration file for instance and NEVER after. The rest is handled with tasks (similar to actors) and data is generally transferred between them through messages (which can happen over queues, notifiers, or even network connections. Locals are often needed when programming UI components as you may have to update a control or indicator or read it outside of its specific event case, but replacing dataflow with access to locals in pure functional VIs is a sure way to get a harsh remark in any review I would do. And while I have been a strong supporter of FGVs in the past I do not recommend them anymore. They are better than globals if properly implemented (which means not just a get and set method, which is just as bad as a global, but NEVER EVER any read-modify cycle outside of the FGV.). But they get awkward once you do not just have one single set of data to manage but want to handle an array of such sets, which is quite often. Once you get there you want to have a more database like method to store them, rather than trying to prop them into an FGV.
-
The problem in this specific case is not about memory, although a refnum uses more than just a pointer, but not much more (the underlying object may however use tons of memory!). The problem is rather that it is very easy to lose the overview of which local (or global) is what and where it is initialized and where does it need to be deallocated. Yes, aside for real UI programming I consider use of locals and globals a real sin!
-
That's most likely because of this in the OpenSSL headers: # if OPENSSL_API_COMPAT < 0x10100000L These functions were required to be called in OpenSSL before 1.1.0but since 1.1.0 OpenSSL automatically initializes its engines on the first call of any function that creates a context of similar session. And since 1.1.0 is already EOL too and you should either use 1.1.1 or even better 3.0.x, it would be indeed strange if your OpenSSL library still included those APIs. I think the old libssleay.so still contained it in 1.0.1 but it was unnecessary to call that, but when changing the shared library names they also axed many of those compatibility hacks too. You should probably call OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS | OPENSSL_INIT_ADD_ALL_DIGESTS | OPENSSL_INIT_LOAD_CONFIG, NULL); and yes this means reading the headers to see what numeric values those constant defines have.
-
Yes, absolutely. Each property(or method) node returning a refnum will increment its object refcount. So if you have two properties "CameraInfo" they may reference the same object but are in fact different references to the same object instance. In fact they use double memory, once for the LabVIEW refnum itself to manage the reference (an int32 pus some extra information including the underlaying .Net or ActiveX reference pointer) and the actual object data space. That object will only go out of memory when ALL the references were closed and that means you have to close the according LabVIEW refnum so it can inform .Net or ActiveX that that reference is not needed anymore. There are other memory leaks actually in your code. First you assign the instance refnum for the originally opened Camera object to the NET Camera local control then you Open a new reference to a new camera object and assign it to the same local control, losing the original refnum object, so you can never again close it yourself (LabVIEW eventually will when your code hierarchy in which you executed the Constructor goes idle, but that is typically only when you finish your program. Generally using locals (or even worse globals, shudder) to store refnums is a very bad idea. It makes proper life time control of objects rather hard and error prone.
-
Please note that unless you use a very old LabVIEW version, there is actually no need to put the Close Reference node into a loop. It perfectly will accept an array of refnums too. As to worrying about if a Close Reference node is necessary or not during a code review, tell the reviewer that there are more important things to worry. 😃 If that are the only things he can complain about, he is either worthless as a code reviewer or your code is prime quality. 😀 For ActiveX (and .Net) refnums it absolutely and positively is important to avoid potentially huge memory hogs (not really memory leaks as LabVIEW still knows about the objects, they just never get disposed until you terminate your application). One of the VI reference close functions marked as questionable also is needed, the other not! ActiveX and .Net objects are refcounted and will often prevent not just themselves to be deallocated but also parent objects, depending if the child object has somehow acquired a reference to the parent for some reason. Any such object wanting to retain access to another object is required to obtain a reference to it which will increase the refcount and only once each reference to an object has been properly closed, will the object actually be released. LabVIEW as simply being another client of the ActiveX or .Net object needs to follow that rule too, so if you don't close the LabVIEW refnum, it won't release the underlying reference to the object and any objects that this object has referenced will also stay in memory. So rather than erring on the wrong side I prefer to err on the good side and simply put a Close Reference anywhere without even spending a Joule of energy to reason if it is really needed. That little extra muscle exercise in the fingers is not that bad. A Close Reference on a refnum that does not need to be closed is simply a NOP (No Operation) in LabVIEW (well factually it is checking a dynamic attribute of the refnum and skipping any attempt to close the refnum if it doesn't need to but that check is about as expensive as your "Not A Number, Path, Refnum" node). So from all the marked Close functions the ones being marked OK are indeed needed. From all the others only one can be definitely deleted (the array of control refnums obtained by the Control Reference Constants) . All the ActiveX closes are definitely needed and the refnum returned from the Controls[] property of the Cluster refnum might be maybe not required. But I wouldn't want to go and spend any energy to find out about that so I would leave it in, which would only make one Close being clearly useless (the uppermost).
-
Ack , need help with cRIO 9035 ASAP
Rolf Kalbermatter replied to Dan Bookwalter N8DCJ's topic in Real-Time
You can use the Scan Engine which by default has a scan interval of 10 ms if I"m not mistaken. It can go down to 1 ms but that should not be used unless you are knowing exactly what you are doing. However some of the C modules do not have Scan Engine support so you need to check that. -
Running zmq package on Linux Ubuntu20 (c library build)
Rolf Kalbermatter replied to Łukasz's topic in Linux
That's the other possibility. The LabVIEW wrapper is basically using futures (not like Java futures, which are more like an object callback, but more like Python __future__ which are features that are expected to be introduced with the next version as a stable function or interface or were discontinued). As to getting pre built binaries from a distribution like Ubuntu for such draft builts, that is very unlikely unless someone at Ubuntu had decided that it is a totally and completely unmissable feature for their platform, which I doubt the zmq draft items every could amount to. -
He looks cute to me. 😃
-
What is your question? 😀 Yes we do have customers wanting to have test software written in Python. Not just since this year. It is not my preferred development platform, despite having written LabPython only about 20 years ago. But I just recently did support for a project that is supposed to do image analysis in Python, but my task was to do the image analysis based on a Matlab script but implement it in C as a shared library to call from Python through ctypes, since the routines ported to Python were to slow for the desired test throughput.
-
How long a license is valid is actually part of the activation process. In the according license response there is either a "permanent", an explicit expiry date or "1-jan-1900" for an unactivated license. I believe that in intention most volume licenses were for a long time already meant to be a lease with explicit expiry date but the license servers from NI often issued a permanent license anyhow. If that was an oversight, a technical problem or some forced process because of compatibility problems I do not know. It was obviously not very clearly communicated in many cases. Not so for Alliance Member leases. That was pretty clear that it is a limited term license and would not let you run the software anymore once you stop paying. So in principle you would have to find the original paperwork, see what it stated back then and then analyse everything. It could be that you did in the past indeed receive a perpetual license with an academic volume license. But if it doesn't say so, you will have a tough stand. The fact that you still can use your old LabVIEW versions without having to reactivate them is not proof that you have actually a perpetual license. It could be also due to a failure or omission when configuring the license servers in the past. If you can proof that it was in the past really a perpetual license that your institution ordered and paid for, because it states so in the invoice or quotes you received then, you might have a chance to appeal the silent change to a lease. It would be a change of contract and NI would have had to clearly inform you about that and offer your institute the option to terminate the agreement. But without such proof, your chances to change anything now are pretty much non existent.
-
Running zmq package on Linux Ubuntu20 (c library build)
Rolf Kalbermatter replied to Łukasz's topic in Linux
Those implicit warnings could be actually due to version conflicts. Those libxxxxxx libraries are open source and tend to be developed over time. It is not very common that functions just disappear when a new version is released, usually there are at least macros to declare a mapping to a new function name, so that backwards compatibility can be offered. So if you get these errors and it is not because you simply have buggy headers, the most likely cause is that your source code was developed against a newer version of the library. Under Linux it is common that you install a library and its headers at the same time. Sometimes a package is divided into the library only part which contains all binary components and sometimes documentation, a development part which contains the headers and source code as well as tests for the library. Sometimes the headers are also installed by the binary package to allow developing depending code. So likely the problem is not that you do not have libzmq installed at all but instead you have an older version installed than what was used to develop the LabVIEW bindings. That means that zmq.h is present on your system and can be correctly included by the source code for the wrapper but it doesn't declare certain functions that are used by the LabVIEW wrapper and the according binary library doesn't contain those functions either of course. You have two solutions: 1) try to install a more up to date libzmq for your system. This simply solves all your problems but may be not always trivial. NI does not go and rebuild libraries for older NI Linux RT systems and unfortunately the nature of Linux makes it necessary to build the libraries and tools with the kernel headers that match the kernel version used for a particular Linux system. Since the NI Linux RT version is specifically tied to the used LabVIEW version, you can't just go and download a different NI Linux RT version for your target without also updating your LabVIEW version. And you can't simply take a shared library and header from a newer NI Linux RT system and copy it onto your system as that might simply move the symbol mixup one dependency level higher but not resolve it. So if you want to go this path without moving the a newer LabVIEW version you may actually have to download the sources for libzmq, copy them to your cRIO and compile them yourselves into the correct shared library and then install it together with the headers. With the typical make toolchain used for many libraries that is basically a move into the source directory for a library with "cd ........", then typing "./configure", "make", and "make install" on the command line, but in true Linux manner there are many other make toolchains a library developer can choose from (or none at all and just leave everything to the end user) and you will have to read the documentation for your library to see how you have to compile it from source. Of course you also have to make sure that the GNU C compiler tools are installed on your system. This is done on the command line by typing "opkg update", "opkg install packagegroup-core-buildessential" and of course your device needs to have a valid internet connection to be able to contact the NI package feeds. 2) Modify the LabVIEW shared library C wrapper code to make use of different library functions that your installed library provides. This might be straightforward or not, depending on the features used and functionality involved. It certainly requires you to look into the actual library functions, how they are meant to work and be used and get your hands dirty with real programming work. -
Technically you can do exactly the same as with the full license. If the support person told you otherwise they are fudding you. Legally however there is indeed a difference. The Deployment licenses are perpetual and let you run LabVIEW code in source code just as with the Development system and full licenses for Toolkits etc. They even let you modify the code and here is the legal gotcha. The Deployment license is NOT meant as a replacement for the Development license but as an add-on purchase. NI is fine about a user doing minor refinement on the source code such as when fixing bugs during debugging on the target machine. But if you start to do serious development with it you are definitely violating the license. Of course, where bug fixing ends and development starts exactly is of course a bit of an open question. As long as the Deployment license is not the only active license you own, NI is almost certainly not going to do anything about it. (Even if you do all the development on the machine with the Deployment license and let the Development license sleep on your laptop for reason of convenience, they won't bug you here). But if you only own the Deployment license anymore and do anything with it besides running your VIs in source code (Deployment) or doing minor debugging fixes (Debugging) then you are definitely violating the license. And of course the Deployment license is also a viable solution to look at your old VIs. As long as you don't modify them (much) or create executables from them, you are using the Deployment license for what it is meant. I still hope that NI decides to actually make the evaluation license turn into a viewer license after the evaluation period expired, instead of not letting LabVIEW startup anymore. In the Viewer mode all editing, recompiling and application building could be disabled but you still could load your existing VIs, look at them and create screenshots or print them out and maybe even run them. It should take not to much effort to make that change and would alleviate some of the complaints about the subscription model such as that you loose any and all access to your self written code once your subscription expires. Other CAD packages such as Altium do it in a similar way, there you can look at your schemata and PCB designs with a viewer license that can be requested at no cost from Altium after installing the software. If they don't do that, there will be various tools that can create such and also full licenses for free and the moral restraint to use them will be very low in view of such a hostile license policy.
-
Running zmq package on Linux Ubuntu20 (c library build)
Rolf Kalbermatter replied to Łukasz's topic in Linux
Your missing a few general differences between Windows PE files and Linux ELF format. That DLL you build is just a thin wrapper around libzmq.dll/so to help interface to it from LabVIEW. The LabVIEW Call Library Node is not a generic Interop replacement and has certain limitations that are mostly due to the fact that NI did not want to create a Call Library Node configuration for which a user first has to study rocket science, physics and philosophy together with math and astrophysics in order to be able to operate it. So they chose certain limitations in what you can configure for the various parameters. Some lower level C APIs like to expect certain things to be done with its parameters that are hard or even impossible to achieve with the possibilities of the Call Library Node alone. It can be often worked around by creating very convoluted code in the LabVIEW diagram to prepare the correct memory buffers with pointers at the right place etc. etc, but in order to be able to create such code you need to understand exactly how the C API works and has to be programmed and then even some more, such as how a C compiler aligns these elements in memory. People who have that knowledge will very quickly decide to write the according code in C(++) and let the C compiler fiddle with the details about memory layout etc, and then create around that a functional interface that limits itself to use LabVIEW friendly parameters so that the Call Library Node configuration gets straightforward and simple. This requires to write an extra shared library in C(++) and compile it with some compiler but if you don't have that knowledge anyways you are certainly doomed when trying to create the according C compiler like voodoo code on the LabVIEW diagram. And would be similarly doomed to know how to properly configure the parameter in the Call Library Configuration even if it allowed for such involved operations directly. Now on Windows when you incorporate some shared library (DLL) in your own DLL you usually link a so called import library with your project. This import library contains functional stubs that locate the specific DLL where the function is implemented and link to the according function. If the dependent DLL can be found on the target system when trying to load your own DLL, all is well, otherwise Windows will fail the load of your DLL (and LabVIEW tells you that Windows couldn't find the DLL or one of its dependencies, with most users overlooking the mentioning of "dependencies" and getting upset since the DLL is obviously in the location where they told LabVIEW it should be). Linux elf libraries are slightly different, there is no import library. The C linker will simply put all symbols it couldn't find in the source code for the current shared library into an external reference list. The elf loader when asked to load that shared library will go through this external reference list and try to resolve the symbols with any known shared library in its ld cache. And here you seem not to have installed libzmq on your system. But it is referenced by this custom wrapper shared library, not incorporated into it, so if the Linux elf loader can't find a shared library that exports these symbols it posts above message. -
Well I never have submitted anything to vipm.io and Github for such libraries feels more like a FINO (first in never out) than anything else. 🙂 May have to check the vipm.io submission procedure. After hacking above version I did look into it more and am considering to improve it to support some more operators and make it more C like in operator syntax (but no variable type support nor arrays or pointers). The main difference would be that the current exponent operator "^" would change to be the EXOR operator instead and for exponent one would need to call the according function.
- 172 replies
-
My guess is that the library name in the CLN itself should be slightly faster if they would implement it the way I would. For a passed in library name they do need to verify that the library name hasn't changed compared to the previous execution so there is some overhead to compare the new name with the old one. It shouldn't even be in the uSec range however as comparing paths is mainly just a MemCompare for most of it, although in a loop for each path element itself. if the paths are the same, it doesn't need to do anything more. If there is no path wired in, that check can be entirely skipped and LabVIEW nodes certainly have the option to check for that as it is an attribute of the node if it has the path input enabled. As to calculating the path dynamically: You do want to cache the path in a Feedback node and only calculate it on first call. Recalculating it each and every time should be only necessary with very strange external DLLs, but not for platform and bitness differences only.
- 172 replies
-
Try another USB port or a powered hub. It seems that something in the USB communication is getting messed up somehow. There are many possible reasons aside from actual firmware bugs in the Keysight device. - your USB bridge in the computer is messed up, faulty or has bad drivers - the USB port you have your device connected to is a low power USB connector and the Keysight likes to draw more power than your computer can provide. Many USB ports perform not as they should according to the specs (and so do devices, sometimes drawing high transient power surges that are not allowed according to the USB specs). - The device might have a firmware bug, try to find if Keysight has a newer firmware available and upgrade your device if that is possible. NI-VISA is one of the few software drivers that never was critical in having to match the LabVIEW version closely. I would be very surprised if that has anything to do with your problem.
-
Issues with PostgreSQL and packed libraries
Rolf Kalbermatter replied to Dpeter's topic in Database and File IO
Basically you should attempt to use each class that you wan't to use from another class NOT in the same PPL into its own PPL. Then relink the source code of each class lib to reference to the PPL version of the class. And be VERY, VERY strict about that. If you call VIs that are not already part of an existing PPL (or don't enable the Exclude dependent library/typedef etc build option), the PPL build will include those VIs in the PPL itself and that will be a completely different VI and class in terms of name space, since myGreatLib.lvlib:myGreaterClass.lvclass is NOT the same as myGreatLib.lvlibp:myGreaterClass.lvclass as far as LabVIEW is concerned. The library name gets part of the fully qualified class name and that p at the end of lvlibp is enough to make both classes completely different implementations.