Hobbyist Toolkit

Showing results for 
Search instead for 
Did you mean: 

Communicating with SPI on BBB through LINX

Go to solution

I am having trouble communicating with the SPI channel 0 over BBB with the LINX functions. I am receiving an error 5000:


Error 5000 occurred at :

Possible reason(s):

An unknown error occured in LINX LinxSpiOpenMaster.


I am specifically trying to test communicating with the SPI channel through the LINX SPI loopback Benchmark example. Within this example, I seem to successfully call the linx library as it receives as input the integer 0 (for channel 0) and outputs 128. This 128 and the function name (LinxSpiOpenMaster) are passed through the error handling vi and returns the Error 5000.


I would appreciate any advice on how to proceed as I've been on this failure for a while. My alternative is to modify an existing library designed for BBB communication (https://www.element14.com/community/community/designcenter/single-board-computers/next-genbeaglebone...), but my lack of knowledge with C programming may be a problem. Making that code outputs a .a file. As I need a shared library to call from within LabVIEW, I extracted the .o files from the .a file, and then used gcc to create a shared library. Pointing to this library (which I copied to the chroot /usr/lib directory) from LINX with the Call Library Node leads to a failure during deployment.


I see that this LINX example I am working with is pointing towards the liblinxdevice.dll file on my windows machine, rather than the liblinxdevice_BBB.so library on the BBB itself. I think this indicates that I need to build the .so library on both the windows machine and on the BBB to use that shared library through LINX, but I can't tell. I very much appreciate any pointers! Please let me know if I can elaborate.

0 Kudos
Message 1 of 10

Sorry I can't help you with your specific BBB problem at the moment but wanted to clarify a more generic error you are making:


@arcraik wrote:


I see that this LINX example I am working with is pointing towards the liblinxdevice.dll file on my windows machine, rather than the liblinxdevice_BBB.so library on the BBB itself. I think this indicates that I need to build the .so library on both the windows machine and on the BBB to use that shared library through LINX, but I can't tell. I very much appreciate any pointers! Please let me know if I can elaborate.

That liblinxdevice_BBB.so is build with that name since there is also a linblinxdevice_RPI.so for the Raspberry Pi (and a dummy liblinxdevice.dll for Windows which really does nothing except allow the Linx VIs to be loaded in your Windows development system without causing a broken arrow).


The LabVIEW VIs should interface to liblinxdevice.* in all Call Library Nodes and there should be a symlink on your BBB with te name liblinxdevice.so that points to the liblinxdevice_BBB.so. It may all look like magic but the LabVIEW Call Library Node replaces the * character after the point with whatever extension a shared library is supposed to have for the current platform. That is .DLL while the VI executes on your Windows host system and .so as soon as the VI is deployed to your BBB board. The symlink makes sure the path LabVIEW is looking for is redirected to the correct shared library. You could also rename liblinxdevice_BBB.so to liblinxdevice.so instead but that is in terms of build script handling more cumbersome and the symlinks are a great Unix feature that has worked perfectly for almost as long as Unix systems have a filesystem. 

Rolf Kalbermatter
My Blog
Message 2 of 10

Thanks for that clarification! So, if I only ever intend to run a VI on the BBB as an embedded UI, I only need to have the .so built on the BBB? I don't, for example, need to build a library on both the BBB and the windows machine (if never directly executing on the windows machine)? 


For this project, we've built an EEG amplifier as a cape for the BBB and I'm not sure how to proceed with debugging since this failure is popping up with the open SPI function. I'm technically not even sure that I should be worried about this error as I don't have electrodes coming in. I suppose the "unknown" aspect of the error is causing quite a lot of anxiety. Anyways, thanks for the info!

0 Kudos
Message 3 of 10



Please can you post a screenshot or the vi for the loop-back test you are running?


What version of LabVIEW are you using?


What version of Debian are you using on the BBB?


Have you been able to access the SPI device from a C or Python test program?

Message 4 of 10

Hello Andy,


Thanks  for your questions:


1. I have attached a screenshot of the vi, the vi itself, and a screenshot of the value directly following the call to the LINX openSPImaster (with accompanying errors following error handling VI).

2. Labview 2020

3. cat /etc/issue: Debian GNU/Linux 9 \n \l

                           BeagleBoard.org Debian Stretch LXQt Image 2020-07-06
4. We have made a small test program with the third party BBB control C program mentioned above. This compiles and works as expected when made outside of the chroot (so yes i am able to connect to the SPI device). If I copy that .so to the chroot directory, labview fails to deploy the vi (a simple call library script) with a deployment error. I believe this was expected and that (as the labview tutorial describes) I need to build the .so from within chroot.


Do you (or anyone) have advice on how exactly to do that? The library has several dependencies that don't exist within the chroot (i.e. stdio.h, stdarg.h, etc.) so I can't immediately build the library from the chroot. Is the idea to copy all dependencies over to the chroot, modify all dependency paths, and build the shared library from chroot? I'm assuming that the deployment error is due to the shared library missing dependencies, but I'm not really sure how to collect them all. I don't have a problem collecting all dependencies, but I imagine there must be a cleaner way to do this (though I am moving forward in modifying and collecting all paths and dependencies so as not to waste time).


Thanks for your advice on the test C program.... I have slightly more confidence that I'll be able to eventually work with SPI in labview now that I know the shared library (outside of chroot) works fine.

0 Kudos
Message 5 of 10

I see that people were running into a similar problem here: https://www.labviewmakerhub.com/forums/viewtopic.php?f=12&t=2145&hilit=.so+to+chroot


Seems like I may need to build the library on windows machine per: https://www.labviewmakerhub.com/forums/viewtopic.php?f=12&t=1864&start=10 and then transfer to the chroot directory. Maybe someone knows how those people moved forward? I'm a bit worried that maybe labview 2020 doesn't allow for what I'm attempting (build so, transfer to chroot, => deployment error) (per some of the responses in the original question)

0 Kudos
Message 6 of 10

The Windows DLL should not be necessary really. There is a lot of half truth out there about Linx by people who try all kinds of things without understanding what they are doing.


Linx as it is now, is built in a specific way. When deployed to the embedded targets, its functions directly call the shared library which accesses the hardware resources. When executed on Windows the Linx VIs either communicate through VISA/RS-232 or TCP/IP with LabVIEW native functions to the liblinxdevice.so library on the target which then interfaces the hardware there and relays back any information to through the communication link.


The Linx VIs do not really call a liblinxdevice.dll under Windows ever. There is a dummy liblinxdevice.dll somewhere but that one does nothing. It only contains empty functions and only serves as a place holder that you can develop the low level Linx VIs itself on Windows without having the according VIs always broken. But if you run them under Windows they do absolutely nothing, since there is no I2C, SPI, AIO and DIO under the Windows system to directly work with.


You need to understand that Linx is a distributed architecture. Depending on how you open the Linx device resource, it interfaces directly to the local hardware (not an option under Windows), through RS-232 or TCP/IP. In the case of the two last one, the parameters are put on the wire and send to the remote liblinxdevice.so which then sends a response.


For Beaglebone Black and Raspberry Pi you have also the local execution option. But that is if you DEPLOY your VIs to those boards. The code is send down to the target and executes there. In that case if you open Linx for local, the VIs access directly the built in liblinxdevice.so and access hardware in that way.


Each liblinxdevice.so is specifically built for the target it is supposed to run on and supports only the resources that it is prepared to handle. For the Beaglebone Black this for instance means that only SPI channel 0 to device "/dev/spidev1.1" and I2C channel 2 to "/dev/i2c-1" is supported.


You should go into the chroot on the command line and try to enter:


ls /dev/spi*


to see what spi devices your board has enabled.

Rolf Kalbermatter
My Blog
Message 7 of 10

Thank you very much for clearing that up for me. I appreciate the info!


From within chroot, ls /dev/spi* returns:


/dev/spidev1.0 /dev/spidev1.1 /dev/spidev2.0 /dev/spidev2.1

0.0 0.1 1.0 1.1


Does that return imply that I should be able to communicate with the SPI channels?


For those that have run into the same problem with getting a shared library working within chroot, I followed this NI cross-compiling tutorial, which is pretty helpful:


During that experience, I ran into 2 problems.

1. Getting eclipse to work

I had a java 13 error. To fix, I had to install Java for 32-bit in addition to Java for 64-bit


2. Small mistake in tutorial

They mention that you have to add a -sysroot flag for the Cross GCC compiler, Cross G++ compiler, and Cross G++ Linker, but forgot to include that you need to add the flag for the Cross GCC Linker as well. (and you don't actually have to do the G++ flags for C code) Pretty obvious, but thought I'd add it.


This allowed me to get a simple addition shared library working through chroot.

0 Kudos
Message 8 of 10
Accepted by topic author arcraik



liblinxdevice_bbb.so was modified last year because the device paths of the SPI devices had changed in Debian 9.x

See https://github.com/MakerHub/LINX/commit/6c188f6b730eeb9462d8c333f8b32494de8f5d18 for more information.

liblinxdevice_bbb.so uses /dev/spidev0.0 on Debian 9.x


The original SPI device paths have been restored in later versions of Debian 9.x.


The SPI open status value you get could be because your kernel does not have the /dev/spidev0.0 device.

You can check this by creating a symbolic link for /dev/spidev0.0 to /dev/spidev1.1

The following command creates an udev rules file for the symbolic link.


sudo sh -c 'echo KERNEL==\"spidev1.1\", SYMLINK+=\"spidev0.0\" > /etc/udev/rules.d/99_linx_spi.rules'


You will need to reboot the BBB.


The LINX file LinxBeagleBoneBlack.cpp could be changed to use the SPI entries in /dev/spi/. The symbolic links will be updated in later versions of Debian.

Message 9 of 10

OK! Well that worked! No more 5000 error and the SPI Loopback Benchmark vi is working correctly! (as a side not to future readers, after creating the symbolic link and restarting the beaglebone, I had to run it twice before moving past that 5000 error. Not sure why, but just letting people know to avoid frustration). Thanks so much for the detailed responses throughout and the specific symbolic linking code from Andy! Jeeze what a relief. 



As a side note, I was able to get a more complicated shared library accepted by beaglebone. My main problem there was having to point to the right header files within eclipse. I think there was a  better way to do it, but I add this comment to provide hope for future readers. 


0 Kudos
Message 10 of 10