Why you should be using Git submodules

When working on software projects, specifically in LabVIEW, I have never liked the way reuse libraries and custom instrument driver libraries are source controlled or included in projects. I’ve tried multiple solutions, and each have their own ‘dirty’ feel about them.

Disclaimer:

I’m still trying to figure this out and learning more about submodules every day

The command line must be embraced as git submodules are not supported in many GUI tools.

Using vi.lib or instr.lib

Placing common libraries in either vi.lib or instr.lib is a good method of sharing the same version of library between projects. Typically, a vi package is created and then installed into the LabVIEW directory. The packages, as well as the library source code can be source controlled.

The disadvantage of this method, in my opinion, is when you want different versions of a specific library used across different projects. (I’m not a VIPM user so this might be possible)

Copy and paste the library into your project

Another method for including common libraries into a project is to copy and paste the source code into the project. This makes moving a project easy as all the dependencies are contained within the project, however it does break clean source code control and creates duplicate code.

The problem comes in when you want to make a change to the common library within a project but also want that change applied to other projects. The updated common library then needs to be copied to the other projects manually.

But what if only some projects need updating or you want to quickly and efficiently share the common changes between developers?

Say hello to Git submodules

Git submodules are reference pointers to other Git repositories. This means once a project is cloned from a repository, additional repositories can be added (cloned) into the existing project folder. Git submodule also supports recursion; however this is disabled by default.

As an example, I have two library repositories already created and stored on Bitbucket. The following will be a step-by-step of how to create a project and add the libraries as submodules.

Create a local bare repository

mkdir git-submodule.git
cd git-submodule.git/
git init --bare

Clone the main project repository

git clone "C:\git-demo\git-submodule.git" "git-submodule"

Once cloned, create and save a LabVIEW project, then commit it to the repository.

git add .
git commit -m "Add empty LabVIEW project for submodule example"
git push origin master

The files on disk should look as follows:

git submodule labview

Now we want to add your common libraries, which are in their own repositories, to our project. The two common libraries I will add is a simple dialog library and math library.

git submodule add git@bitbucket.org:Labvolution/driver_math.git
git submodule add git@bitbucket.org:Labvolution/driver_dialogs.git

Once the submodules have been added, a new file, .gitmodules, is created with the reference to the submodules.

git submodule labview

[submodule "reuse-libs/driver_dialogs"]
    path = reuse-libs/driver_dialogs
    url = git@bitbucket.org:Labvolution/driver_dialogs.git
[submodule "reuse-libs/driver_math"]
   path = reuse-libs/driver_math
   url = git@bitbucket.org:Labvolution/driver_math.git

The reuse-libs folder now contains the submodule libraries.

git submodule labview

A git status on the main project repository will show the changes. These are automatically staged when the submodules are added.

git submodule labview

The changes need to be committed.

git commit -m "Add common libraries as submodules"

The common libraries, each in their own repositories, are now part of the main LabVIEW project which is itself in a repository.

git submodule labview

A main vi can then be created to test the libraries.

git submodule labview

These changes can be added and committed to the main project.

If a library is modified (by adding a new vi), committing the changes will be a two-stage process, the first being commit the changes to the library, and then committing the new submodule reference to the main repository. This tells the main repository which version (commit hash) to use.

git submodule labview

To use a previous version of the library, checkout a specific hash or branch of the submodule. Then git add it to the main repository.

git submodule labview

Notice that the “two button dialog.vi” is no longer available.

git submodule labview

A git status on the main repository will show a change in the submodule.

git submodule labview

Having to add a specific submodule reference to a main repository, allows you to use different ‘versions’ of the submodule in different projects.

LabVIEW Project

When there are git submodules within a project, it is always a clever idea to know what they are, even though they are tracked from the main repository.

By using a post build vi, a log file can be added to the output build directory which shows what submodules are included, as well as what hash reference is used.

git submodule labview

The main part is the submodule information, as this can vary from project to project. To get the submodule status, execute

git submodule status

which will return

36054d63f5d22284e2b5d7e40798af0fbbda14e0 reuse-libs/driver_dialogs (heads/development/2016)
b2089a11fb281ebf5eebb29f9f9080d81ec66933 reuse-libs/driver_math (heads/development/2016)

Conclusion

I have started using Git submodules in new projects as well as refactoring old projects when needed. I see a huge benefit in using them as they encourage

  • multiple smaller repositories for common libraries
  • low coupling as common libraries should be stand-alone
  • multiple projects can share a common library, but not be forced to use the same version
  • a submodule can have its own submodule

There is a learning curve that needs to be climbed when starting out using Git submodules, however seeing what they provide in the long run, it’s well worth it.


References:

https://torbjoernk.github.io/article/2013/04/03/struggling-with-git-submodules-and-mercurial-subrepositories/

https://git-scm.com/docs/git-submodule

Adding C# Class Libraries into LabVIEW Applications

Knowing how to include C# libraries into a LabVIEW project can be a very useful tool. There are many reasons why you would want to include C# dll’s into a LabVIEW project but the two that come up most often for me is reusing legacy code that was initially written in C# and writing a C# wrapper when wanting to use a third party driver or library.

Sometimes it’s easier to write the wrapper in C# and then implement the library directly in LabVIEW. When interfacing directly to a third party driver/library, the LabVIEW code to accomplish a relatively simple task can be very messy and cumbersome to read; hence the C# wrapper with simple implementation in LabVIEW is my preferred method. This is how I made my LabSSH and LabSFTP libraries.

This post is going to cover the process of creating a C# Class Library, creating a C# Form Application to test the library and then finally how to bring it in to LabVIEW. The example that I have used is a very simple counter class. This class will either count up or count down between an upper and a lower limit. The delay between counts can also be set.

When the counter increments or decrements, the current value will be passed to the calling application (Form Application or later LabVIEW Application) using a callback event.

For each section I have created a walk through video instead of a formal tutorial. I find videos easier to follow and you can see the steps to follow a bit easier.

Creating the C# class library

First we need to cover some definitions:

  • Delegate – A delegate is a type that represents references to methods with a particular parameter list and return type. (Read the full definition here)
  • Event – Events enable a class or object to notify other classes or objects when something of interest occurs. (Read the full definition here)

Creating a C# Form Application to test the library

Adding a form application to your solution allows you to test the library in the environment that it was written. I prefer this to testing directly in LabVIEW as each time a new version of the dll is compiled, LabVIEW needs to be restarted.

By testing the dll in C#, you can get immediate feedback to your dll development. If there are problems with the dll when you move to LabVIEW, you know that the functionality is working so the problem is more than likely in the LabVIEW implementation.

C# LabVIEW Form Application

Implementing the library in LabVIEW

The .NET objects can be found in the Connectivity section of the functions palette.

LabVIEW .NET methods

C# LabVIEW Form Application 2

A common bug in LabVIEW is that the callback vi remains reserved for execution even once the references are closed, the event has been unregistered and the application has been stopped.

C# LabVIEW Callback Event Remains Reserved

A way to get around this is to include an invoke node once all the references have been closed. Right click on the invoke node and select the following: Select Class >> .NET >> Browse >> mscorlib (4.0.0.0) >> System >> GC >> [S]Collect()

As soon as this method is placed on the block diagram, the callback event vi will no longer be reserved for execution.

C# LabVIEW Callback Event Cleared Reserve

In summary, this is a very simple implementation of creating a C# Class Library, testing it using a C# Form Application and then using the Class Library in a LabVIEW project.

You can download the C# and LabVIEW source below and as always if you have any questions, please get in touch.

Download LabVIEW and C# Class Library

Greg

SFTP File Transfer for LabVIEW

Leading on from the LabSSH Library that I shared a while back, I have also created a LabSFTP LabVIEW library.

From Wikipedia, SFTP can be described as follows:

In computing, the SSH File Transfer Protocol (also Secure File Transfer Protocol, or SFTP) is a network protocol that provides file access, file transfer, and file management over any reliable data stream.

As with LabSSH, LabSFTP uses a custom .net class that incorporates some of the features of the RENCI SSH library.

LabSFTP offers the following features:

  • Password authentication to a remote host
  • Private/Public key authentication using the openssh key format
  • The ability to get a list of files or folders from a specified location on a remote host
  • The ability to upload files
  • The ability to download files
  • A public method to check the connection status
  • A public method that will send a stay-awake signal at a specified interval

The video below shows the library being used in an application. The LabVIEW application is communicating with a LinuxLite installation running on a virtual machine.

To get up and running, open the library and start by running the test vi. This will create a connection, get a list of files from a specified location, upload a file and download a file. Make sure that your paths are correct. It has been left to the developer to make sure that files and paths are correct before executing the the specific methods.

As with all my posts, you can download the LabVIEW code below. If you have any feedback, please feel free to contact me on Google+ or send me an email. The LabVIEW application has been tested using LinuxLite and on the latest Raspbian Jessie image running on a Raspberry Pi3.

Download LabVIEW LabSSH & LabSFTP Library

Greg

LabVIEW: Discovering New and Old Functions

I have been using LabVIEW Quick Drop for the last few years and find it really useful. I almost never open the functions palette anymore. The one problem I find with Quick Drop (not really a problem with Quick Drop) is that I end up using the same functions over and over again, without discovering new, different or more efficient methods of doing things. By opening the functions palette every now and then, you can quite quickly and easily notice new or unused functions.

This happened to me a few months ago when I stumbled upon the In Range and Coerce function.

LabVIEW In Range and Coerce Comparison pallette

With writing a lot of test software, I am always comparing measured values to target values. When there is an upper and lower limit, I used to use greater than, AND and less than function. This works but I always thought it looked a bit clumsy.

LabVIEW In Greater AND Less than target

Using Quick Drop, and what I thought to be a good search term to find the function that does this in one step proved unsuccessful.

LabVIEW Quick Drop greater and less

Then one day I decided to go looking through the Comparison functions palette and came across the In Range and Coerce function. This did everything I needed and more and I have used it ever since.

LabVIEW Quick Drop In Range and Coerce block diagram

Knowing what the function does and how it works, it’s obvious why it has the name that it does. This does however make it a bit tricky to look for functions without knowing the name of something and just knowing what you want it to do. Sometimes you find what you need and others you don’t.

LabVIEW Quick Drop In Range and Coerce

With the In Range and Coerce function, you can also very easily include or exclude the limits from the comparison.

LabVIEW Quick Drop In Range and Coerce block diagram include limits

I think Quick Drop is brilliant and significantly increases productivity; however I also think it’s a good idea to every now and then just browse through the functions palette to see the many, sometimes unused functions that are available.

LabVIEW Functions palette

Happy programming and enjoy looking for and using those sometimes unused, new or forgotten functions.

Greg

myRIO: FPGA SPI Communications

I have had a National Instruments myRIO for a few months but have not had a chance to use it yet. I bought it so that I can get some experience working in LabVIEW Real Time and with the LabVIEW FPGA.

I started off using the default FPGA build and express vi’s but quickly ran into a problem when I tried to use the SPI express vi. Each time I tried to configure the express vi, LabVIEW crashed. After a while this got extremely irritating so I started looking at the myRIO Custom FPGA Project.

myRIO Custom FPGA Project

To use digital IO this project worked really well. Again the problem came when I wanted to interface to an SPI device. I have used SPI a lot in previous projects so understand the concept and how it works. Despite being a project template, with a documentation folder, nowhere does it explain how to use and implement the custom FPGA build. If there is further documentation, please let me know so I can go through it to get a better understanding of the project.

One more small rant before I get on to a solution you can use, is the SPI naming used in the myRIO Custom FPGA Project does not conform to the norm. Again, if I have read and understood it incorrectly, please let  me know.

myRIO SPI Naming Convention

While looking for some documentation on the myRIO project, I came across this example which explains a bit about how to write an SPI driver and also has an example. This example is written for the sbRIO but can be very easily modified to run on the myRIO and also has a nice, simple API. The last section of the NI article outlines in a few lines how to recompile for a different FPGA target. Here is a more detailed description with a few extras that I have added. Firstly, download the example project here.

myRIO SPI Sample project

These are the steps that I followed to to get it working on a myRIO. I’m sure the steps will be very similar when moving to any other FPGA target.

Add your target to the project.

myRIO SPI Add new FPGA target

myRIO SPI Add new FPGA target 2

Once you have the myRIO target added to the project, copy the FIFO‘s and Example_Host SPI Dual Port.vi from the sbRIO FPGA Target to the myRIO FPGA Target. Make sure to copy them to the FPGA Target and not the RT Target. Then copy Example_Host SPI Dual Port.vi and FPGA Reference.ctl from the sbRIO RT Target to the myRIO RT Target.

For my project I decided to use Connector B. Rename the IO that you are going to use for the SPI communications. Your project should now look like this.

myRIO SPI new FPGA Target

Next we have to edit the FPGA code to work with the new references set on the myRIO FPGA. Open Example_Host SPI Dual Port.vi. I have deleted one of the SPI ports as I only need one.

Open FPGA SPI_SPI Port.vi and change the references in the FPGA IO cluster to point to the IO we configured in the previous step. Right click on each reference and select Conifigure IO Type…

myRIO SPI configure new IO references

Select the corresponding reference and then Replace All.

myRIO SPI configure new IO references 2

Do this for each reference. You will notice that when you change the CS reference, the vi breaks. We will fix this next. The reason the vi breaks is that the CS line on the original sbRIO FPGA code was set to a line and not a port. When changing form a line to a port, the element is now boolean and not U8.

The two changes that need to be made to FPGA SPI_SPI Port.vi are removing the Index Array in the Reset CS case and add a Number to Boolean Array and Index Array to the Set CS case. This will test the state of the LSB which will be the CS state.

myRIO SPI configure FPGA CS

myRIO SPI configure FPGA CS 2

Save and close the vi. In Example_Host SPI Dual Port.vi delete the FPGA IO cluster and then add it again by adding a constant to the subvi. This will update the references that have been changed. Save and close all open vi’s. Remove the original sbRIO Target and save the project.

myRIO SPI Removing sbRIO Target

You are now ready to compile your myRIO SPI project. Right click on FPGA SPI_FPGA Top Level.vi and select Create Build Specification. When compiling there are a few choices for where you want to compilation to take place. To compile this locally it took me around 50 min, compared to compiling on the NI Cloud Portal which took less than 10 min.

myRIO SPI NI Cloud Compiler

To access the NI Cloud Portal, you need to register an account as your normal community account does not work here. Once registered you will need to verify your account through an email confirmation. You also need to enter a Product Activation Code. This is not the code that you use as your LabVIEW license. I had to call NI and get them to generate a 20 character code that I entered. You will need an active SSP to get a code generated. The time it takes to call NI and get the code is less than one compilation so is totally worth it.

Once the FPGA compilation is complete, open Example_Host SPI Dual Port.vi. You will notice that the run arrow is broken. To fix this we need to link Open FPGA VI Reference to the correct bitfile. Right click on Open FPGA VI Reference and select Configure Open FPGA VI Reference…

myRIO SPI Configure FPGA VI Reference

Select the Build Specification and then select Overwrite in the dialog that pops up. The vi should now be executable.

Run the vi, select your slave device SPI settings and mode and then press the Write button. You will notice data will be read back.I have a LM74 temperature sensor connected which uses 16 bits SPI mode 0.

myRIO SPI RT Running

There you have it. SPI running on a myRIO FPGA with an API which can be used on an RT host.

As usual, if you have an questions or advice, please feel free to get in touch.

Download myRIO SPI Example Code

Greg