Jump to content

Rolf Kalbermatter

Members
  • Posts

    3,778
  • Joined

  • Last visited

  • Days Won

    243

Everything posted by Rolf Kalbermatter

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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.
  6. 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.
  7. 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.
  8. 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.
  9. 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.
  10. Ahhh I misunderstood you. I thought you were referring to my own library that I had attached. But you are referring to the muParser library however. Can't help you with that one as I don't know the details of the actual muParser library that implements the logic in the background.
  11. Have you read the documentation text file included? There is a function rand() which calls the LabVIEW Random Number node and returns its values. Do not expect crypto quality randomness from this. The LabVIEW Random Number generator has been repeatedly investigated and found to have a reasonable randomness but with a limited interval. For most simple requirements that is quite enough, but if you need real crypto quality randomness there would need to be done a lot more serious work and then you quickly can forget to find this as a free library. As to now() that's a bit tricky. The entire formula parser only really operates on doubles internally and doesn't have any other types. The newly hacked in bitwise operators were simply added by converting the double to an U64 for doing the bitwise operation then store it back as a double on the value stack. That should do for most bitwise operations for up to 32- bit integers but can start to get inaccurate if you chain many bitwise operators in a formula. So what would you expect the now() to produces? A double representing the number of seconds since January 1, 1904 GMT, as the LabVIEW epoch is? Or rather since January 1, 1970 UTC as the Unix epoch is? Or maybe rather the number of days since January 0, 1900 as the Excel epoch, or would January 1, 1600 UTC be better as the Windows SYSTEMTIME is? You see lots of possibilities and all of them equally right or wrong, so avoiding that problem by not implementing it is simply the easiest solution. 😁
  12. And really a nitpick but your title is rather inaccurate :-). There is no opposite of MoveBlock(). The only opposite you can have is by swapping the source and target pointer here. Other than that I'm not sure what other opposite you could think off here.
  13. You may want to try with this library. No guarantees about its proper operation. It's a quickly hacked together version from this library that I posted earlier. It's not really tested for the extra bitwise operators and there is no provision for correct left and right association of these operators, so it might require explicit bracketing to work as expected unlike in other languages and formula parsers that tend to follow the mathematical and/or C style conventions. LabVIEW 2018 for now. ExprEval.zip
  14. That's either a very old DSNewPtr from NI (before LabVIEW 2009 which introduced support for 64-bit code and according pointer sized integers) or a non-official user created CLN. This should be a pointer sized integer since the definition for the size parameter changed with LabVIEW 2009 from an int32 to a size_t just as with the MoveBlock. It shouldn't really cause trouble though since that int32 is anyhow sign extended to a 64-bit stack parameter on 64-bit LabVIEW, and technically a LabVIEW pointer can't really span more than 2^32 bytes without causing other related problems deep down in the memory manager. The return value of the DSNewPtr() seems to be correctly configured as pointer sized integer and definitely needs to remain that way. It is not where you potentially have to use the conditional code structure. The value for the pointer size to allocate might however have to be adjusted. As long as the structure only contains the pointer you simply can allocate 8 bytes and treat it that way, effectively having the upper 4 bytes be unused in the 32-bit case. Once that structure gets more complex and/or the pointer offset is not at 0 however or there follows data in the structure beyond the pointer, you have to adjust the whole offset and size values according to the bitness, to not cause it to overwrite the wrong location. Basically when you configure a Call Library Node parameter to be a pointer sized variable, LabVIEW will treat it as 64-bit integer on the diagram but do the RIGHT thing depending on the bitness it is running on. It will use the entire 64-bit when it is running as 64-bit process, and the lower 32-bit when it is running as 32-bit process. And a returned value will be sign extended (if you use a signed pointer sized integer) when running on 32-bit and zero padded (if you use an unsigned pointer sized integer) on 32-bit. Nothing special needs to be done when running on 64-bit. This is because LabVIEW is a strictly typed compile time environment and the developers wanted to keep the flattened format consistent across platforms. If they would have chosen for a special pointer datatype that is to be sized according to the current environment, flattening such structures and variables would cause significant problems and the flattening of data is not only used when you explicitly add a Flatten or Unflatten node in your diagram but a very fundamental part in many locations in LabVIEW including the entire VI Server interface but also in some areas of handling the connector pane of VIs.
  15. No no! The pointer size depends on the application environment, not the kernel environment. As long as you stay in 32-bit LabVIEW, pointers will be 32-bit no matter what Windows version you are in. But!!!!! Be prepared! Windows is the only LabVIEW platform that is still 32-bit too. (Well ok LabVIEW RT on ARM is also 32-bit but that is an entirely different story). All other platforms (Mac and Linux) have NO 32-bit version of LabVIEW anymore since around LabVIEW 2017. And the LabVIEW for Windows 32-bit countdown has certainly started already. Once NI has fully ported every Toolkit to 64-bit (or discontinued it) expect the LabVIEW 32-bit version to be discontinued within a year or two at most. So if they manage to get the cRIO and myRIO support finally updated to 64-bit (it's about time since at least 5 years), and the Linx Toolkit is 64-bit too, it's bye bye 32-bit LabVIEW. The DSNewPtr() is the right approach to use. You are basically managing your own memory according to the requirements of the API that you call, since the LabVIEW management contract isn't compatible with it, and it couldn't be compatible with all the possible ways memory can be handled. .Net Interop has a whole slew of support functions to try to deal with such situations and even that isn't always sufficient to provide a solution for every possible situation without very involved and convoluted code constructs. It's the main crux of trying to marry different APIs together.
  16. This works but is bound with troubles. A LabVIEW array is dynamic as LabVIEW is a fully managed programming environment. No it is not .Net managed, at the time the LabVIEW developers designed the basics that are valid until today, .Net was not even an idea on earth, let's not talk about a fact. But it is managed and the LabVIEW runtime handles that all behind the curtains for you. This means that a LabVIEW variable, and especially a handle that arrays and strings are, is only guaranteed to be valid for the duration of the Call Library Node call itself. After that node returns, any passed in array, string or even scalar variable can at any point be resized, relocated or even simply get deallocated. So the pointer that you get in this way can very well get invalidated immediately after that Call Library Node returns. For performance reasons, LabVIEW tries to maintain arrays and strings for as long as possible when it can, but to decide if it can and if it propritizes this rule above other possible rules to improve performance is a tricky business and can even change between LabVIEW versions. It is pretty safe to assume that an array or string wire that you wire through a Call Library Node, doesn't branch into other nodes and is wired to the end of the current diagram structure, is left untouched for the duration of this diagram structure. But even that is not something the LabVIEW management contract guarantees. It's just the most prudent thing to do in almost any case to not sacrifice performance. Once you have a branch in the wire before or after the Call Library Node to retrieve the internal data pointer in the handle, or you do not wire the array data to the diagram structure border, all bets are open to if and when LabVIEW may decide to modify that handle (and consequently invalidate the data pointer you just got).
  17. Glad you found the solution. It definitely is THE right approach if you want to avoid going into C code yourself. Just watch out about bitness. This does not work without conditional compiled structure if you want to make it 32/64-bit compatible.
  18. It's probably my limited command of the English language, but for me this sounds about as intelligible as a dissertation about the n-th dimensional entanglement of virtual particles between different universes.
  19. 100% CPU load on the server would indicate some form of "greedy" loop. If you create a loop in LabVIEW that has no means of throttling its speed it will consume 100% of the CPU core it is assigned to, even if there is nothing in the loop and it does effectively do nothing very fast. More precisely, that loop will consume whatever is left over of that core after other VIs clumps had their chance to snoop some time of from that core.
  20. Definitely echo Hooovahh's remark. LabVIEW TCP Nodes may limit the effectively reachable throughput since they do their own intermediate buffering that adds some delays to the read and write operations, but they use select() calls to asynchronously control the socket, which should do a highly efficient yield on the CPU when there is nothing to do yet for a socket. And the buffer copies itself should not be able to max out your CPU, 2Gbps comes down to 250MBps, which even if you account for double buffereing once in LabVIEW and once in the socket, should not be causing a 100% CPU load. Or did you somehow force your TCP server and client VIs into the UI thread? That could have pretty adverse effects but would also be noticeable in that your LabVIEW GUI starts to get very sluggish.
  21. I haven't tried it but in your minimal C wrapper you should be able to install a SIGTERM handler in this way and in there you could call a second export in the shared library to inform your LabVIEW program that it needs to shut down now! #include <signal.h> #include "SharedLib.h" void handler(int signum) { SharedLibSignal(signum == SIGTERM); } int main() { struct sigaction action; memset(&action, 0, sizeof(action)); action.sa_handler = handler; if (sigaction(SIGTERM, &action, NULL) == -1) { perror("sigaction"); exit(EXIT_FAILURE); } return SharedLibEntryPoint(); }
  22. What code do you use? What device? Your address seems to indicate the Modbus decimal addressing scheme. Most LabVIEW ModBus libraries I know of use however the more computer savy hexedecimal naming scheme with explicit register mode selection. This means you need to remove the first digit from your address (the number 4) and decrement the remaining address by one to get a zero based address. However Modbus Function Code 4 is a (Read Input Registers) operation and there is no (Write Input Register operation as it would not make any sense to write to an input. Read Holding Register would be an address starting with 3 and Write Holding Register would start with 6. So when using the NI Modbus library for instance in order to read your Modbus address 40001 you would need to use the Read Modbus function, selecting the Input Register group and passing an address of 0. There is no possibility to write to the input registers. For Holding Registers the Modbus address would be 30001 for reading and 60001 for writing. And when using the LabVIEW Modbus library you would select the Read and Write function respectively, selecting the Holding register and passing an address of 0.
  23. i'm not going to fight anyone. I simply don't use LGPL software. 😁
  24. I would think a link to the original projects website that has the downloads available could also suffice. Of course that leaves you in a bit of a bind if the original developer site goes down or is otherwise made unavailable.
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.