From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

Hobbyist Toolkit

cancel
Showing results for 
Search instead for 
Did you mean: 

Developing shared library for custom hardware cape with LINX shared library functions

We are trying to build a shared library for a custom hardware cape and we would like to use the LINX shared library functions. Is there documentation for the functions contained within the liblinxdevice.so?

0 Kudos
Message 1 of 7
(2,414 Views)

@arcraik wrote:

We are trying to build a shared library for a custom hardware cape and we would like to use the LINX shared library functions. Is there documentation for the functions contained within the liblinxdevice.so?


Go to the source, Luke! https://github.com/MakerHub/LINX/tree/master/LabVIEW/vi.lib/MakerHub/LINX/Firmware

That's all there is in terms of documentation. The public API of that shared library is in https://github.com/MakerHub/LINX/tree/master/LabVIEW/vi.lib/MakerHub/LINX/Firmware/Source/core/examp...

 

That said, I'm not sure that interfacing to that shared library is the best way to go really. You would more likely want to plugin support for your hardware in the according device implementation which for the Raspberry Pi would be in https://github.com/MakerHub/LINX/blob/master/LabVIEW/vi.lib/MakerHub/LINX/Firmware/Source/core/devic...

in LinxRaspberryPi.cpp and LinxRaspberryPi.h, respectively in LinxRaspberryPi2B.cpp and LinxRaspberryPi2B.h one level higher. But the current design of the liblinxdevice shared library is not really suited for any extensibility with non-standard hardware components for the respective platform. And before you moan about that fact, the whole Linx platform is a really nice project for something that was mostly a one man project. While some of the time that went into this was sponsored by NI, it was still for a large part personal effort that made this possible and it was never planned as a commercial product.

 

But the advantage of using liblinxdevice.so is that there are VIs that interface to it and that you can then use to interface to your custom hardware directly from a LabVIEW program. Wrapping this with yet another shared library would require you to develop your own LabVIEW VI library for that shared library and pretty much void any advantage you get from using liblinxdevice.so. If you are going to write your own shared library anyhow I would instead make it interface to the native system functions directly.

Rolf Kalbermatter
My Blog
Message 2 of 7
(2,359 Views)

Thanks for the info rolfk.  Are you suggesting we modify the LinxBeagleBoneBlack.cpp/.h to include functionality for our hardware? Then recompile liblinxdevice_bbb.so and replace on the BBB?

Or are you saying use the functionality outlined in LinxBeagleBoneBlack.cpp and LibLinxDevice.cpp to create a separate shared library (and a separate LV wrapper) to use as a replacement for LINX (for our hardware communication)?

 

I'm not as familiar with C/C++ (I'm not lead on developing firmware for the custom hardware) and it took me a while to implement cross-compiling for relatively simple shared libraries for BBB Labview (couldn't get it correctly compiled from within the chroot env and LV2020). I've now gotten shared libraries correctly cross compiled, but cross-compiling the entire LINX library from source has been a struggle. Thanks!

0 Kudos
Message 3 of 7
(2,320 Views)

Hi,

There is an archive of the LINX VI reference here

 

http://web.archive.org/web/20200925143051/https://www.labviewmakerhub.com/doku.php?id=learn:librarie...

 

You may find there are VI's that handle the BBB interfaces you need.

 

0 Kudos
Message 4 of 7
(2,308 Views)

@arcraik wrote:

Thanks for the info rolfk.  Are you suggesting we modify the LinxBeagleBoneBlack.cpp/.h to include functionality for our hardware? Then recompile liblinxdevice_bbb.so and replace on the BBB?

Or are you saying use the functionality outlined in LinxBeagleBoneBlack.cpp and LibLinxDevice.cpp to create a separate shared library (and a separate LV wrapper) to use as a replacement for LINX (for our hardware communication)?

 

I'm not as familiar with C/C++ (I'm not lead on developing firmware for the custom hardware) and it took me a while to implement cross-compiling for relatively simple shared libraries for BBB Labview (couldn't get it correctly compiled from within the chroot env and LV2020). I've now gotten shared libraries correctly cross compiled, but cross-compiling the entire LINX library from source has been a struggle. Thanks!


Well, no not really. I only described what I understand from what you were trying to do. The liblinxdevice shared library exist to give a uniform API to LabVIEW to address the different resources on a device. It is more like an umbrella around the various resources that a Linx device provides, to provide a simple API that can be accessed through LabVIEW VIs. Accessing that shared library through yet another shared library gives you absolutely no advantage to developing your driver entirely in LabVIEW and using the Linx VIs that access the liblinxdevice shared library.

 

But plugging in your hardware into liblinxdevice is also not an easy feat, depending on what functionality it provides. If your device fully fits into the resources that Linx provides, such as a generic SPI, I2C, or serial port, or an analog or digital pin, then it is doable. But if your device provides other functionality, extending liblinxdevice with that additional functionality is going to be a major project and then you do also have to develop the VIs to access that extra functionality.

 

Unless your requirements are very special, the most practical approach is likely to simply develop your own shared library that accesses all the necessary system APIs, and provide a VI library for this so that LabVIEW users can use your device. liblinxdevice is not going to solve any of these problems or give you a shortcut, unless you can access your hardware through the functions of liblinxdevice. But if that is the case, why do you even want to bother with developing another shared library on top of it? Instead just develop your driver in LabVIEW on top of the Linx VIs! The only reason I could think of why someone wants to do that in a shared library instead of with the Linx VIs is a badly understood attempt at secrecy. If that is the reason, then don't. It is already hard enough to get your hardware used by other people at all. Trying to hide your secrets in such ways is a sure way to make it a project that will collect dust in some attic and never get used by anyone.

 

Summary: If Linx gives you the means to access your hardware, then use the Linx VIs, otherwise develop your own shared library and VI wrappers for that.

 

As to developing on Linx, my workflow is a bit different. My main development environment is currently Windows, with a Visual C project to compile the shared library into a Windows DLL. This is however only for developing and compiling. There is not a lot I can test in this way at the moment since the Windows DLL does for obvious reasons not support I2C, SPI, analog and digital functionality. The only thing it can do is provide the generic functions such as device identification, UART serial port functionality and once everything is finished also TCP/IP remoting. I choose to integrate the serial port and TCP/IP remote access from the Linx VIs directly in the shared library for a cleaner LabVIEW interface.This also optionally allows to startup the liblinxdevice shared library as a server, that can relay Linx commands to the local hardware or some other remote device. Once the shared library compiles I transfer the source code to the Raspberry Pi and compile and debug the device specific functions there. Installing the gcc development environment on the Raspberry Pi was pretty simple with something like: 

 

opkg update

opkg install packagegroup-core-buildessential

 

Next in my plans is to get the Beaglebone Black compilation working.

Rolf Kalbermatter
My Blog
0 Kudos
Message 5 of 7
(2,256 Views)

Thanks again for the info Rolfk.

 

I apologize for coming across as hesitant to reveal details. We are an academic team working on a Brain Computer Interface, and one aspect is the development of a custom hardware voltage amplifier for a BeagleBone that receives commands over CS channel 63 and returns EEG voltage values with SPI (the circuit itself has been designed already). The LINX library should contain all the functionality we need. Our problem now is that we see CS channel 63 is reserved and we can't use it through LINX. This is an academic project, so our resources and experiences for building a firmware library from scratch is rather limited. We hope that we can get around this CS reservation. I see you mention that, if we can connect with our hardware through LINX, we should use LINX. Is it possible to overcome the above reservation problem? Modifying and building from source? Possible simlink between the real 63 channel and an unused port?

 

If we can't figure out how to connect through LINX, we will try to write a custom shared library, but it is possible that I will instead have to re-write the entire project in Python, which would be a frustrating waste of a year. I'm leading the software development of this project and I wouldn't have started this whole thing in labview anyways, but hey grad students don't call the shots. Thanks very much for any ideas you have!

 

 

 

0 Kudos
Message 6 of 7
(1,937 Views)

Where did you deduce that this CS pin is reserved and for what is it reserved according to you? How did you happen to come to this number 63?

 

Edit: Ahh I see that you use the Linx pin numbering scheme which numbers the pins starting at P8 and then moves on with P9-pin1 as pin 47. Here your pin number 63 happens to be P9-pin17 and then you should be fine with the Linx default configuration as explained below! Yes that pin is reserved: as CS0 signal for the SPI channel that Linx accesses as SPI channel 0. Linx expects you to specify a CS channel anyways and does attempt to do custom handshaking. Unfortunately it is in the current version of Linx not possible to specify that this custom CS handshaking should not be done, so select a DIO pin that is unused and unconnected. The underlying device driver will do proper handshaking over the SPI0_CS0 signal anyways.

 

If I look at the Beaglebone Black pinout I see that SPI0_CS0 is on P9-pin17 which happens to be GPIO_4. SPI1_CS0 is on P9-pin28 which corresponds to GPIO_123. However you have to take these with a grain of salt as it can depend on your board revision.

 

Linx supports the Linux device /dev/spidev1.1, which is connected to the device tree entry BB_SPIDEV0. This device tree entry by default uses 

 

"P9.17",	/* P9_17 (A16) spi0_cs0.spi0_cs0 */
"P9.18",	/* P9_18 (B16) spi0_d1.spi0_di */
"P9.21",	/* P9_21 (B17) spi0_d0.spi0_do */
"P9.22",	/* P9_22 (A17) spi0_sclk.spi0_sclk */

 

This SPI port is made available as SPI channel 0. So it would seem that by using SPI channel 0 in Linx would actually connect to your SPI channel using SPI0_CS0 as CS signal.

Rolf Kalbermatter
My Blog
0 Kudos
Message 7 of 7
(1,930 Views)