I am new to LabVIEW and I do not fully undestand what it takes to support LabVIEW under Linux for DAQ cards in general and that's what I am trying to understand here.
We have an LPC bus based ADC and DAC card for an x86 board. We would like to support LabVIEW under Linux for these cards, however, we do not have kernel I/O driver for these cards and it is my understanding that in order to support LabVIEW, we first need to write these I/O drivers.
1.Does NI provide any tools that enable us to write these Linux I/O drivers (.ko) for 3rd party DAQ cards such as ours. I read about NI-VISA product but I am not sure how that fits into the overall picture.
2. Let's assume after the I/O drivers are available, what is the next step in order to make LabVIEW development environment support these DAQ cards? Is there another layer of drivers,"LabVIEW drivers", that sits on top of the OS I/O driver that we further need to develop?
Any help/information on this topic is greatly appreciated. Thanks.
Well, depending on the interface your hardware uses, there are various options. If it is a hardware board directly plugged into the PC, I believe you will have to provide some sort of kernel driver, as there is no way to access hardware directly from user space in a feasible way. If this hardware is however connected to the computer through a standard interface such as USB you can quite likely get away with accessing the according user space API to communicate through that interface.
As to your other questions:
1) No NI won't tell you how to create kernel device drivers. You can download DAQmx Base and get an idea what they did but you will have to come up with your own solution. NI is not in the business of teaching about kernel device drivers in general, and on Linux for sure. Their Linux support until now is a very delicate balance between protecting their own IP and complying with strict and continously increasing open source requirements from the Linux kernel developers. And kernel driver development, while not exactly magic, is a very specific technical ability that only a few people really can master. Last but not least it is not in their interest to support a competitor to their own hardware.
In the case of Linux kernel device drivers, the most easy path is to look at various types of the already present device drivers. Almost anything that gets distributed and residing inside the Linux kernel has to be more or less open source nowadays. So there are a lot of fully functional device drivers to look at and get an idea how they work. Writing your own still is a project that you should not take lightly. It costs a lot of time, coffee and nerves to get a kernel driver right, because every time something goes wrong, you are likely having to restart the whole system from scratch to be sure that you don't have corrupted kernel tables and what else messing with your whole system.
For Windows you would have to look at the DDKs, although the example drivers there, while they show how things are supposed to work, are usually very far from fully working drivers and other sources than the DDK are sparse and far in between.
2) Yes a kernel device driver while technically usually the hardest part to get really right (just working 99% of the time is really not enough for something that has the potential to take down your whole system very hard), is just the first step in the whole picture. After that you usually need a user space shared library that communicates with the kernel driver and provides an easy API for the applications to use your hardware. This API is what any application including LabVIEW written applications will use. Once you have the user space API you want to create a LabVIEW VI library that accesses this API through the Call Library Node. This is the only real LabVIEW specific part of the whole picture. All the rest up to this is simply necessary infrastructure to access hardware in a modern OS, be it from a C application, Python, or LabVIEW. And this applies to any modern OS, including Linux, Mac OS X, and Windows.
Rolfk, That's a great answer!!! Probably the best explain than any of the resources that I have been able to find. I have one follow-up question regarding the "user space shared library":
1. Should these libraries be written keeping LabVIEW in mind? In other words, does LabVIEW requires certain specific API calls to be present in that shared user space library?
The reason I am asking this is that we would like to avoid a situation where we write kernel I/O drivers and the user space shared library and then find out that the target application (LabVIEW in this case) will not work because certain functions/calls are missing in the user space shared library.
To summarize, should these I/O drivers and API be agnostic to LabVIEW?
Yes and no! The kernel driver is whatever works best for you. The shared library will translate between the kernel driver interface and whatever makes most sense to your user space API.
The user space API does not require specific functions to be present for LabVIEW. But you should take care to design the API in such a way that it accepts simple datatypes. The LabVIEW Call Library Node does not support function pointers, nor does it lend itself to supporting parameters consisting of structures containing non flat data (embedded array or string pointers).
Ahh..I see. Is there a list of data types that LabVIEW recommends? I found the following link but not sure if what's that you are referring to:
Also, on NI's LabVIEW Linux support pages, I see a lot of mention regarding NI-KAL. Is that the user space API that you are talking about that support all of NI's DAQ cards?
NI-KAL is a kernel-mode component on top of which NI builds its drivers.
A typical pattern for developing drivers for LabVIEW is to build a C API and then build a LabVIEW-specific DLL on top of that API for better integration with LabVIEW. For instance, if your driver returns an array then it would integrate better with LabVIEW if you use the LabVIEW memory management APIs to work directly into a LabVIEW array handle. You don't want that code in your standard driver, though, so you would build a layer that sits between LabVIEW and your regular driver. This is what DAQ does, for instance.
No these are the various datatypes that LabVIEW supports internally. Some of them are not useful for the Call Library Interface.
Basically you can use all kinds of C scalar datatypes such as single, double, char, short, int, and long and their unsigned types directly as parameter, either by value or by reference, arrays of these scalars, and structures that contain any combination of these scalars. In addition you can pass ASCII Null terminated strings as a parameter. Anything else is asking for trouble.
Absolutely unsupportable without specific LabVIEW wrapper library that translates between your C API and a more suitable LabVIEW type are function pointers, such as callbacks (need to be translated in the wrapper into LabVIEW occurrences or user events), and structures containing any type of pointer.
Also keep in mind that LabVIEW uses non-default alignment for structures on 32-bit Windows. If your driver is Linux only then you don't have to worry about that, but if you want it to be cross platform then even structures will require a special LabVIEW wrapper (unless you want to impose LabVIEW's alignment on your C clients as well).
Guys, all this is great info! So just to be clear:
NI-KAL is a kernel mode componenet/framework on top of which NI builds their DAQmx kernel drivers for their cards. Also, where can I find the corresponding user-space C API that sits between the DAQmx driver and the Linux equivalent of LabVIEW Windows DLL.
Lastly, can somebody point me out to some set of basic example code (or a HOWTO) showing the entire process of supporting LabVIEW under Linux?
The DAQmx driver is not open source. We don't ship the C code.
As for documentation showing the "process of supporting LabVIEW under Linux", assuming you mean supporting drivers on Linux, I'm not aware of any documentation specifically about that. We have some general guidelines for writing drivers for LabVIEW at ni.com/idnet, but those tend to focus on writing drivers using VISA or IVI. A lot of the general concepts in the guidelines still apply, at least in terms of how to write your LabVIEW API, but that won't help you figure out how to write the C glue code that sits between LabVIEW and your underlying driver. For that you mostly just need to understand how to call C code from LabVIEW. We have some documentation for calling external code from LabVIEW, which includes information about the data types and memory management functions (look for "calling external code" in the help). That's the kind of stuff you need to understand so that you can do any necessary translation between the LabVIEW side and the C side.