//The general form of the eGet function is:
//eGet (Handle, IOType, Channel, *Value, x1)
lngErrorcode = eGet (lngHandle, LJ_ioGET_AIN, 3, &dblValue, 0);
In the case of the UE9, the first example using add/go/get handles both the DAC command and AIN read in a single low-level call,
while in the second example using ePut/eGet two low-level commands are used. Examples in the following documentation will use
both the add/go/get method and the ePut/eGet method, and they are generally interchangeable. See Section 4.3 for more
pseudocode examples.
All the request and result functions always have 4 common parameters, and some of the functions have 2 extra parameters:
Handle
– This is an input to all request/result functions that tells the function what LabJack it is talking to. The handle is
obtained from the OpenLabJack function.
IOType
– This is an input to all request/result functions that specifies what type of action is being done.
Channel
– This is an input to all request/result functions that generally specifies which channel of I/O is being written/read,
although with the config IOTypes special constants are passed for channel to specify what is being configured.
Value
– This is an input or output to all request/result functions that is used to write or read the value for the item being
operated on.
x1
– This parameter is only used in some of the request/result functions, and is used when extra information is needed for
certain IOTypes.
UserData
– This parameter is only used in some of the request/result functions, and is data that is simply passed along with
the request, and returned unmodified by the result. Can be used to store any sort of information with the request, to allow a
generic parser to determine what should be done when the results are received.
4.1.1 - Function Flexibility
The driver is designed to be flexible so that it can work with various different LabJacks with different capabilities. It is also
designed to work with different development platforms with different capabilities. For this reason, many of the functions are
repeated with different forms of parameters, although their internal functionality remains mostly the same. In this documentation, a
group of functions will often be referred to by their shortest name. For example, a reference to Add or AddRequest most likely
refers to any of the three variations: AddRequest(), AddRequestS() or AddRequestSS().
In the sample code, alternate functions (S or SS versions) can generally be substituted as desired, changing the parameter types
accordingly. All samples here are written in pseudo-C.
Functions with an “S” or “SS” appended are provided for programming languages that can’t include the LabJackUD.h file and
therefore can’t use the constants included. It is generally poor programming form to hardcode numbers into function calls, if for no
other reason than it is hard to read. Functions with a single “S” replace the IOType parameter with a const char * which is a string.
A string can then be passed with the name of the desired constant. Functions with a double “SS” replace both the IOType and
Channel with strings. OpenLabJackS replaces both DeviceType and ConnectionType with strings since both take constants.
For example:
In C, where the LabJackUD.h file can be included and the constants used directly:
AddRequest(Handle, LJ_ioGET_CONFIG, LJ_chHARDWARE_VERSION,0,0,0);
The bad way (hard to read) when LabJackUD.h cannot be included:
AddRequest(Handle, 1001, 10, 0, 0, 0);
The better way when LabJackUD.h cannot be included, is to pass strings:
AddRequestSS(Handle, “LJ_ioGET_CONFIG”, “LJ_chHARDWARE_VERSION”,0,0,0);
Continuing on this vein, the function StringToConstant() is useful for error handling routines, or with the GetFirst/Next functions
which do not take strings. The StringToConstant() function takes a string and returns the numeric constant. So, for example:
LJ_ERROR err;
err = AddRequestSS(Handle, “LJ_ioGETCONFIG”, “LJ_chHARDWARE_VERSION”,0,0,0);
if (err == StringToConstant(“LJE_INVALID_DEVICE_TYPE”))
do some error handling..
Once again, this is much clearer than:
if (err == 2)
4.1.2 - Multi-Threaded Operation
This driver is completely thread safe. With some very minor exceptions, all these functions can be called from multiple threads at
the same time and the driver will keep everything straight. Because of this Add, Go, and Get must be called from the same thread
for a particular set of requests/results. Internally the list of requests and results are split by thread. This allows multiple threads to be
used to make requests without accidentally getting data from one thread into another. If requests are added, and then results return
LJE_NO_DATA_AVAILABLE
or a similar error, chances are the requests and results are in different threads.
The driver tracks which thread a request is made in by the thread ID. If a thread is killed and then a new one is created, it is
possible for the new thread to have the same ID. Its not really a problem if Add is called first, but if Get is called on a new thread
results could be returned from the thread that already ended.
As mentioned, the list of requests and results is kept on a thread-by-thread basis. Since the driver cannot tell when a thread has
ended, the results are kept in memory for that thread regardless. This is not a problem in general as the driver will clean it all up
when unloaded. When it can be a problem is in situations where threads are created and destroyed continuously. This will result in
the slow consumption of memory as requests on old threads are left behind. Since each request only uses 44 bytes, and as
mentioned the ID’s will eventually get recycled, it will not be a huge memory loss. In general, even without this issue, it is strongly
30
Summary of Contents for UE9
Page 84: ...84 ...