Programming Languages

32-bit and 64-bit Architectures

The FrontPanel API is distributed for 32-bit and 64-bit architectures on Windows and Linux.  If you have a 32-bit version of Windows installed, you will only need the 32-bit API since Windows/32 cannot run applications build for 64-bit architectures.

If you have a 64-bit version of Windows installed, the OS can run both 32-bit and 64-bit applications.  The FrontPanel API you choose should match the architecture of the application you are using.  Typically, 32-bit applications are installed in “Program Files (x86)” and 64-bit applications are installed in “Program Files”.

WINDOWS (32-BIT)WINDOWS (64-BIT)
32-bit Application32-bit API32-bit API
64-bit Application64-bit API

Windows DLL Usage

The Microsoft Visual C++ Redistributable is required to use the FrontPanel DLL and the wrapped APIs because the DLLs are compiled against Microsoft libraries.  Your software installation package should install the appropriate redistributable (32-bit and 64-bit versions are available).  The redistributable package is available for free from Microsoft’s website.

Note that the redistributable for the corresponding architecture of the DLL needs to be installed, regardless of the Windows OS architecture. Therefore, if you’re using the 32-bit version of Python on a 64-bit version of the Windows OS, you will need to have the 32-bit version of the redistributable installed.

API Version Compatibility

As much as we try to keep the API interfaces stable and compatible across versions, we may occasionally need to introduce changes that break compatibility with previous versions of the DLL (including the wrapped API DLLs). In most cases, these changes are mentioned in the Release Notes. With any update to the DLL(s) for a new FrontPanel release, you should assume that your application will need to be compiled again.

Query API Version

The FrontPanel API version is described by 3 components, “major”, “minor” and “micro”. The major version changes either when significant new features are added or if the API changes in an incompatible way. The “minor” version is incremented for every new release containing more than just bug fixes, and the “micro” version is incremented for bug-fix-only releases.

Note that for an application compiled with FrontPanel API there are two different version values: one is compile-time and corresponds to the version of the API the application was compiled with, while the other one is run-time and corresponds to the version of the library actually being used. The latter may be strictly greater than the former if a newer (but compatible) version of the library is used.

Compile-time version information is represented by preprocessor constants OK_API_VERSION_MAJOROK_API_VERSION_MINOR and OK_API_VERSION_MICRO as well as OK_API_VERSION_STRING containing all three version components separated by dots. Additionally, OK_CHECK_API_VERSION macro can be used to check if the currently used version is greater than or equal than the given one, e.g.:

#if OK_CHECK_API_VERSION(6, 0, 0) // some code using FrontPanel v6-only API #endif
Code language: PHP (php)

Run-time version information can be queried using GetAPIVersionMajor()GetAPIVersionMinor() and GetAPIVersionMicro() functions returning integers or GetAPIVersionString() returning the full, dot-separated, version string. The CheckAPIVersion() function can be used to check the version at run-time, e.g.:

if ( !OpalKelly::CheckAPIVersion(6, 0, 0) ) { // error: FrontPanel v6 is required to run this code }
Code language: PHP (php)

Compile-time version information is available in the C/C++ API only. All languages have access to run-time version information using the same functions.

Wrapped APIs

The FrontPanel API is available in C#, Java, Ruby, and Python.  These APIs are similar to the native (C/C++) API, but have a few peculiarities.  The best place to start is our DESTester sample that is available on in all of the wrapped APIs.

Getters and Setters

Getters and Setters are the methods used to access member variables in a structure (such as okTDeviceInfo).  Differences exist depending on the specific language conventions.  Below are some examples of the getters and setters.  In particular, the Java API uses functions to access member variables that are prefixed with “get” or “set”.

// C/C++ printf(devInfo.serialNumber); regEntry.address = 0x00001234; // C# System.Console.Write(devInfo.serialNumber); regEntry.address = 0x00001234; // Java System.out.println(devInfo.getSerialNumber()); regEntry.setAddress = 0x00001234; # Python print(devInfo.serialNumber) regEntry.address = 0x00001234 # Ruby puts devInfo.serialNumber regEntry.address = 0x00001234
Code language: PHP (php)

Data Types

Whenever possible, the corresponding data types in the language have been mapped transparently to the native API.  There are a few exceptions to this that should be noted, however.

Java : Long Instead of Unsigned Int

The Java language does not have unsigned types.  Therefore, when using the 32-bit unsigned int for methods such as GetWireOutValue and SetWireInValue, it is best to use Java longs.  Otherwise, the most significant bit will map and sign-extend incorrectly.

Byte Arrays

Byte arrays are used when bulk data is handed to or received from the API.  Examples include the Pipe transfer APIs and the Flash memory read/write APIs.  Byte arrays are handled differently in different languages.

Python API

The Python API is built as an import library to be used with the Python interpreted programming language.  Python is a powerful extensible language with a clear syntax, making it ripe for the FrontPanel API add-on.  The Python API is built using the C++ API as a foundation, so the similarities are pervasive.

The Python API is compiled for each supported platform into a shared object file (DLL under Windows or .so under Linux) and distributed along with a couple Python files that define the package.  The Python interpreter can access the API methods through this shared object and Python package.

Required Files

The Python API distribution includes the files listed below:

  • ok.py
  • _ok.pyd – Windows, architecture-specific for 32-bit/64-bit
  • _ok.so – Linux, Mac OS, architecture-specific for 32-bit/64-bit
  • okFrontPanel.dll – Windows, architecture-specific for 32-bit/64-bit
  • libokFrontPanel.so – Linux, Mac OS, architecture-specific for 32-bit/64-bit
  • okimpl_fpoip.dll – (optional) Windows, architecture-specifc DLL used to provide FPoIP functionality
  • okimpl_fpoip.so – (optional) Linux, architecture-specifc DLL used to provide FPoIP functionality

The applicable files need to be in the current working directory where Python is started.  Alternatively, they may be added to the Python site-packages directory within your Python distribution.  Refer to the Python manual to see how this is done.

Environment Setup

Assuming FrontPanel distribution was unpacked under FP_ROOT directory (this is the directory called FrontPanel-Ubuntu20.04-x86_64 or similar and containing ReleaseNotes.txt file), the following environment variables need to be set to allow using FrontPanel API from Python:

(note: if you are using Python 2.7, replace Python3 with Python)

  • PYTHONPATH must be set to include $FP_ROOT/API/Python3
  • LD_LIBRARY_PATH (DYLD_LIBRARY_PATH for macOS) must be set to include both $FP_ROOT/API/Python3 and $FP_ROOT/API directories.

To do this, execute the following commands:

$ export PYTHONPATH=$FP_ROOT/API/Python3:$PYTHONPATH $ export LD_LIBRARY_PATH=$FP_ROOT/API/Python3:$FP_ROOT/API:$LD_LIBRARY_PATH # Linux $ export DYLD_LIBRARY_PATH=$FP_ROOT/API/Python3:$FP_ROOT/API:$DYLD_LIBRARY_PATH # macOS
Code language: PHP (php)

Example Usage

Using the API from Python is quite easy and can be done scripted or interactively.  Below is an example interaction with the Counters sample project.

>>> import ok >>> dev = ok.okCFrontPanel() >>> pll = ok.okCPLL22150() >>> dev.GetEepromPLL22150Configuration(pll) 1 >>> dev.SetPLL22150Configuration(pll) 1 >>> pll.GetOutputFrequency(0) 100.0 >>> dev.ConfigureFPGA('c:\counters.bit') 1 >>> dev.ActivateTriggerIn(0x40,0) 1
Code language: JavaScript (javascript)

Ruby API

The FrontPanel Ruby API is provided in the form of a Ruby gem to allow for simple installation. In order to use this extension, you must have the Opal Kelly FrontPanel SDK installed.

Installation

Ensure that the FrontPanel SDK is installed and the okFP_SDK environment variable is defined to point to the location of the API subdirectory of the SDK installation.

You must also have a working C++ compiler in order to build the native extension which is part of this gem. Under Microsoft Windows systems, you need to install RubyInstaller to compile Ruby extensions. Note that when selecting the file to download, you should choose a version with the development kit (i.e. with Ruby+DevKit in its name).

If the requirements are satisfied the Opal Kelly ruby extension can be installed using the following command:

gem install OpalKelly

If this command reports errors about missing headers or libraries, please check that the okFP_SDK environment variable is defined correctly. If you have the okFrontPanel.h header or library in some non-default location, you may also set the okFP_SDK_INCLUDE and okFP_SDK_LIBS environment variables to point to them directly as necessary. Finally, you can also specify their locations directly on the gem install command line:

gem install OpalKelly -- --with-frontpanel-include=C:/location/of/frontpanel/header --with-frontpanel-lib=c:/location/of/frontpanel/library
Code language: JavaScript (javascript)

Use

The FrontPanel Ruby API parallels the FrontPanel C++ API. Please refer to the FrontPanel API documentation in this space along with the API reference for more information.

The following trivial example can be used to check that the gem is installed correctly:

require 'OpalKelly' puts "Using OpalKelly SDK #{OpalKelly::GetAPIVersionString()}"
Code language: JavaScript (javascript)

Please note that Ruby programs using this gem must be able to load the FrontPanel SDK shared library at run-time, this may require the following additional setup:

Under Microsoft Windows systems, you need to set the special RUBY_DLL_PATH environment variable to the directory containing okFrontPanel.dll to allow recent Ruby versions to find this DLL. Please note that having this DLL in one of the directories included in the usual PATH variable is not sufficient.

Under Unix-like systems, you can simply copy the shared libokFrontPanel.so library to one of the directories searched by default (e.g. /usr/local/lib) or add $okFP_SDK to the standard environment variable containing the list of directories to search (i.e. DYLD_LIBRARY_PATH under MacOS or LD_LIBRARY_PATH elsewhere).

Java API

The Java API is built as an extension library to be used with Sun’s compiled Java language.  It it built on top of the JNI (Java Native Interface).  The API is distributed as a shared library and a Java archive (JAR file).

Required Files

There are a few required files for the Java API: the shared libraries and the Java archive:

  • okjFrontPanel.dll – Windows, architecture-specific for 32-bit/64-bit
  • okFrontPanel.dll – Windows, architecture-specific for 32-bit/64-bit
  • okimpl_fpoip.dll – (optional) Windows, architecture-specifc DLL used to provide FPoIP functionality
  • okjFrontPanel.so – Linux, Mac OS,  architecture-specific for 32-bit/64-bit
  • okimpl_fpoip.so – (optional) Linux, architecture-specifc DLL used to provide FPoIP functionality
  • libokjFrontPanel.jnilib (Mac OS)
  • okjFrontPanel.jar

Under Windows, you can keep the DLLs in the directory where you run java.  Under Linux, the shared object should be placed within your java.class.path.  For example, under the SuSE 9.2 Linux distribution, you would copy the file to: /usr/lib/jre/lib/i386.

Example Usage

Within a Java source that uses the Java FrontPanel API, you need to import the FrontPanel classes using the following line:

import com.opalkelly.frontpanel.*;
Code language: CSS (css)

To actually load the FrontPanel library into Java, you will also need to make the following System call before using any FrontPanel API objects:

Notes:

-With FrontPanel versions 5.2.4 and later this is no longer required.

-Jshell support is added in FrontPanel versions 5.2.4 and later. Jshell uses a different class loader when calling System.loadLibrary(), so you mustn’t make a call to System.loadLibrary() when using jshell. 

System.loadLibrary("okjFrontPanel");
Code language: JavaScript (javascript)

Compiling a Java application for use with the Java API can be done on the command line using javac with the -classpath argument to specify the Java API JAR as shown below.

javac -classpath okjFrontPanel.jar MyClass.java
Code language: CSS (css)

Likewise, when running the application, you need to add the Java API JAR to the classpath:

java -classpath .;okjFrontPanel.jar MyClass # Windows java -classpath .:okjFrontPanel.jar MyClass # Mac & Linux
Code language: CSS (css)

A thorough example of the Java API is included in the DESTester application.  Shown below is the Python example above transformed into Java.

import com.opalkelly.frontpanel.*; public class JavaAPITest { public void TestMethod() { dev = new okCFrontPanel(); pll = new okCPLL22150(); dev.GetEepromPLL22150Configuration(pll); dev.SetPLL22150Configuration(pll); System.out.println("PLL Output: " + pll.GetOutputFrequency(0) + " MHz"); dev.ConfigureFPGA("c:/counters.bit"); dev.ActivateTriggerIn((short)0x40, (short)0); } }
Code language: JavaScript (javascript)

C# API

The C# API is built as an extension library using the Platform Invoke (PInvoke) capability of .NET.

Required Files

The following files are required to use the C# API:

  • libFrontPanel-pinv.dll – Shared library, architecture-specific for 32-bit/64-bit
  • libFrontPanel-csharp.dll – C# library
  • okFrontPanel.dll – Primary FrontPanel API DLL
  • okimpl_fpoip.dll – (optional) DLL used to provide FPoIP functionality

The C# library must be added to your C# project as a Reference.  The shared library must be placed in the runtime directory of your application.

Example Usage

Within your C# source, you will need to specify the namespace for the FrontPanel API:

using OpalKelly.FrontPanel;
Code language: CSS (css)

At runtime, the FrontPanel API classes will automatically load the shared library as necessary.

A good example of the C# API is included in the DESTester application.  Shown below is a brief code snippet:

using OpalKelly.FrontPanel; class CsharpAPITest { public void TestMethod() { dev = new okCFrontPanel(); dev.OpenBySerial(""); dev.LoadDefaultPLLConfiguration(); dev.ConfigureFPGA("c:/counters.bit"); dev.ActivateTriggerIn((short)0x40, (short)0); } }
Code language: JavaScript (javascript)

FrontPanel DLL

On the Windows platform, a dynamically-linked library (DLL) is available.  On other platforms (Linux, Mac OS X, and QNX), this library is known as a shared-object.  We will use the terms DLL and shared-object to mean the same.  This DLL makes it possible to call the FrontPanel API from other programming languages (such as C, C++, VisualBasic) as well as from many third-party software applications such as LabVIEW and Matlab.  It also means that you don’t need to have a precompiled API library specific to your compiler.

The FrontPanel DLL is provided as three files listed in the table below:

FILENAMEDESCRIPTION
okFrontPanel.dll
libokFrontPanel.so
libokFrontPanel.dylib 
The FrontPanel DLL binary (Windows, Linux, Mac, respectively).  This file needs to be located with your application executable or, for third-party software, in the appropriate DLL location.
okFrontPanel.libReferred to as an “import library,” this file contains references necessary to call the functions in the DLL.  This is typically required only for C and C++ applications linked with MSVC.
okFrontPanelDLL.hThis header file contains the FrontPanel DLL entrypoints corresponding to the functions in the import library.

In most cases, each class method has a corresponding DLL entrypoint.  This makes it easy to refer to the standard API documentation for calling information.  One notable difference is that most DLL entrypoints require a pointer argument.  This pointer is actually the pointer to the allocated C++ class object.  Note, however, that this object is allocated and deallocated using DLL entrypoints and therefore the DLL does NOT require C++ and can be used in any C application.

QNX Usage

QNX is a real-time operating system that runs on a number of architectures, including Intel x86.  From a build environment perspective, it is very similar to Linux and other UNIX-like operating systems.  Our samples should build and run under QNX without modification.  The typical application startup procedure is to create a new QNX project from within the Momentix IDE using QNX templates, then copy the source files from one of the samples into that project.  You will also need to include the shared object file with your compiled binary.

Under the build settings (Makefile), you will need to change the LDFLAGS setting to include the QNX USB library as shown below.

Memory Allocation

Due to the way the QNX USB stack operates, you must allocate memory differently if it is going to be used for any FrontPanel Pipe transfers.  See the code example below as reference.  Note that this only applies to buffers used for pipe transfers.

#include <sys/usbdi.h> pBuffer = new unsigned char[65536]; // Typical C++ allocation pBuffer = (unsigned char *)usbd_alloc(65536); // QNX pipe buffer allocation   delete [] pBuffer; // Typical C++ deallocation of a buffer usbd_free(pBuffer); // QNX deallocation of pipe buffers
Code language: PHP (php)

Example Usage (C/C++)

When using the DLL in a compiled C/C++ application, you will need to link the okFrontPanel.lib file with your application.  This file contains references necessary to call the functions in the DLL.  You will also need to include the file okFrontPanelDLL.h in each source file that calls the DLL.

Constructing and Destructing Objects

The FrontPanel API is an object-oriented library but the DLL is strictly C-style.  Therefore, methods have been provided in the DLL for creating and destroying the objects such as okCPLL22150 and okCFrontPanel.  An object must be created before its methods can be called.  An object should also be destructed when you are done using it.

okFrontPanelDevices_HANDLE devices; okFrontPanel_HANDLE dev; devices = okFrontPanelDevices_Construct(); dev = okFrontPanelDevices_Open(devices, NULL); // Opens the first device okFrontPanel_ConfigureFPGA(dev, "bitfile.bit"); // Configure the FPGA with the specified bitfile ... // Continue using the 'dev' object. ... okFrontPanel_Destruct(dev);
Code language: PHP (php)

Calling Methods

Each DLL method that acts on an object has an additional required argument that indicates which object is being acted upon.  In C++, this additional argument is implied by the object-oriented nature of the language.  In the DLL this argument must be explicitly provided.

C++ Wrapper

Also included in the okFrontPanel.h file is a C++ wrapper for the DLL.  This provides a full C++ object class so that you do not have to call the C-style DLL methods from your C++ application.  Most of the samples are written using this C++ wrapper.

OpalKelly::FrontPanelPtr dev = OpalKelly::FrontPanelDevices().Open(); // Opens the first device dev->ConfigureFPGA("bitfile.bit"); // Configure the FPGA with the specified bitfile ... // Continue using the `dev` object, the device will be closed when it // goes out of scope ...
Code language: PHP (php)

Error Handling

Most functions in the FrontPanel library indicate errors by returning a value of the type ok_ErrorCode in C, or okCFrontPanel::ErrorCode in C++. Both types are enums and the value ok_NoError (or okCFrontPanel::NoError), which has the value of 0, indicates success while a negative return value corresponds to an error. It is strongly advised to check the return value of all functions returning the error code as continuing to use the device after an error has occurred will almost certainly fail to work correctly and result in hard to debug errors that could be avoided by detecting the error as early as possible.

A few other C functions return richer error information by providing not just an error code, but an error message, possibly containing more details about the error. These functions require passing them a pointer to an okError* and fill it with a pointer to the actual error object on error:

okCFrontPanelDevices_HANDLE hFPDevices; okError* err; hFPDevices = okFrontPanelDevices_Construct("", &err); if (!hFPDevices) { fprintf(stderr, "Failed to initialize FrontPanel: %s\n", okError_GetMessage(err)); okError_Free(err); return; } ... continue using the library ... okFrontPanelDevices_Destruct(hFPDevices);
Code language: PHP (php)

When using the C++ API, an okError object is not used and the functions throw an std::runtime_error-derived exception instead:

try { OpalKelly::FrontPanelDevices devices; ... continue using the library ... } catch (std::exception& e) { std::cerr << "Failed to initialize FrontPanel: " << e.what() << "\n"; }
Code language: PHP (php)

Example Usage (Matlab)

Please note that the Matlab API is not officially supported by Opal Kelly.  While it is not officially supported, we would like to keep it up-to-date.  Please contact us via email if you have any suggested changes to the Matlab API.

Matlab provides a convenient way to extend its own capabilities by calling user-provided DLL functions.  This is done using a few native Matlab calls: loadlibrary, calllib, libisloaded, libfunctions, libfunctionsview.

For example, to load the FrontPanel DLL into Matlab for use, the following syntax can be used:

if ~libisloaded('okFrontPanel') loadlibrary('okFrontPanel', 'okFrontPanelDLL.h'); end
Code language: JavaScript (javascript)

You can view the calling conventions and conversions Matlab has applied to the DLL methods by calling the command “libfunctionsview(‘okFrontPanel’)”.  An example way to call the DLL:

Matlab API

While the above example shows how to use the FrontPanel DLL from within Matlab, we have already provided a more thorough version of this API for your usage.  It is provided as a fully-functioning sample of the DLL usage from within Matlab and utilizes Matlab’s object-oriented structure to provide an API that is very similar to the C++ API in usage.

DLL Header File

Due to a bug in Matlab’s DLL usage, a slightly modified DLL header file must be used when accessing the API through Matlab.  This revised header defines the HANDLE objects as unsigned long rather than void *.  If the revised header file is not used, memory leaks will occur in Matlab.