UL support on Linux
Closed this issue · 4 comments
It looks like MCC now supports their "Universal Library" on Linux, too. Can we then use libuldaq to back this in Linux, which should enable most of their hardware then?
The problem is that the UL API on Linux is not compatible with the UL API on Windows. That means that drvMultiFunction.cpp, etc. won't work on Linux.
Initially UL for Linux only supported their most recent hardware. I see that now it does support many more modules.
One possibility would be to replace the current low-level Linux library from Warren Jasper with UL for Linux. That would allow the API mapping, so that the Windows API can continue to be used at the high-level, but is mapped to the Linux UL API underneath. That would allows us to move to commercially supported software, rather than Warren Jasper's code. UL for Linux which is still open-source.
I have begun to develop this in the UL_For_Linux branch. It greatly simplifies things.
- It eliminates the Linux_Drivers directory that contains the drivers from Warren Jasper. This was 19,000 lines of code.
- It eliminates the board-specific code in cbw_linux/mcBoard_*. That was 2,900 lines of code.
- All of the code to convert from the Windows UL API (functions starting with cb*) to the Linux UL API (functions starting with ul*) is now in the existing files cbw_linux.cpp and mcBoard.cpp. These files have changed significantly, but have not gotten any larger.
The new version does not require any device-dependent (i.e. per-module) code, it is just the device-independent translation from the Windows API to the Linux API. It requires that the UL for Linux code from Measurement Computing be installed. That is easy to do with 3 familiar Linux commands:
- wget
- ./configure
- make
- make install
The current status is that I have tested the analog input and digital I/O functions on an E-1608 and they seem to work. The remaining tasks are to implement the fast I/O functions (AInScan, AoScan) and to test the temperature input, analog output, pulse output, and counter functions.
I now have the following modules working with UL for Linux:
- E-1608
- E-TC
- USB-2408-2AO (temperature input has some performance issues)
- USB-CTR (scaler mode appears to not be obeying NO_RECYCLE; MCS mode fails below 1 ms dwell time)
In the end I took a different approach than discussed above. The UL_for_Linux branch made a wrapper around the UL for Linux functions (e.g. ulAIn()) that used the UL for Windows API (e.g. cbAIn()).
I decided this was not the best approach, and instead I changed the high-level drivers (drvMultiFunction.cpp and drvUSBCTR.cpp) to use code like this:
#ifdef _WIN32
return cbPulseOutStop(boardNum_, 0);
#else
return ulTmrPulseOutStop(daqDeviceHandle_, 0);
#endif
This ends up being much less new code to write, and makes it clear what the differences are between the Windows and Linux calls. This code was developed on the UL_for_Linux_Direct branch, which has now been merged into master.