Library Overview

The Library provides full programmed access to the BitScope Capture Engine. It is implemented using a small set of portable functions. Programming BitScope to capture waveforms and logic is simply a matter of calling the correct sequence of these functions from your program. There are no complicated data structures, parameter lists or callbacks.

BitScope Programming

The library must first be (1) initialized and one or more devices opened. For each open device the required capture conditions must be (2) set up before a (3) trace is initiated to capture or generate the signals. When the trace completes the data may be (4) acquired to the host computer for display and analysis. Initialization and setup is normally only done once but the trace and acquire steps may be repeated as often as required. When finished the devices should be (5) closed which releases the resources allocated to them.

(1) Library and Device Initialization

Before use, the library must be initialized and one or more devices opened:

With the exception of BL_Count (see below), these functions are necessary only for reporting information to the application and identifying the device.

(2) Device Programming and Setup

After one or more devices have been opened they must be set up for use. This is the most detailed programming step but it is only needed once after opening the device unless recovering from an error. The first thing your program needs to know is how many devices, channels, ranges and other properties are available (they may not all be the same). The number of open devices may be obtained via BL_Count.

BL_Count is also used to report the number of analog channels, logic channels and analog input ranges (on each analog channel). Which entity it reports depends on its argument andwhich device, channel or source is selected a the time it is called. The device, channel and source are selected using BL_Select:

It must be called after selecting the device but before selecting the channel. This is important because the number of channels available may be fewer than the physical number the device supports in some modes. For example, to select the BNC source on channel 1 on device 0:

This must be done first to establish the core trace settings. Choose values to ensure the duration required will be captured given the selected sample rate. Some modes use finite (device) buffers so your choice may be constrained. An alternative is to assign the duration directly:

This function accepts two arguments specifying the trigger level (which is applied to the currently selected channel) and the type of trigger. If signals are to be captured before the trigger, or a delay is required after the trigger, these parameters are specified next using two functions:

Both functions are optional (not required when tracing untriggered). At this point the device is ready to capture waveforms and logic data. All the preceding steps need not be repeated if the parameters for a series of captures remain unchanged. To commence the trace and capture signals call:

This function is the one that actually talks to BitScope and captures waveforms. This function may take an arbitrarily long time to complete. Indeed it may never complete, so to avoid locking your program, it may be called asynchronously or it may be called with a specified timeout. When called asynchronouslyBL_Tracealways returns immediately, even if the trace has not yet completed. In this case call:

periodically after BL_Trace to monitor progress of the trace. BL_State returns a token reporting trace in progress, trace complete, timeout or an error code. When an asynchronous trace is in progress it may be manually stopped with:

An alternative is to call BL_Trace synchronously with a specified timeout. In this case BL_Trace is guaranteed to return within the time specified but the trace may or may not have completed in that time; it returns TRUE if it has, FALSE otherwise.

(4) Acquiring Data from the Device

BL_Acquire uploads data from the device one channel at a time. Before it is called each time, select the channel (and optionally the device) to be acquired with BL_Select. If acquiring from other than the first sample, the starting index may be specified:

If BL_Index is used it must be called before BL_Trace. In any case, the return value of BL_Acquire specifies how many sample are actually acquired. The return value will not be greater than the number requested but it may be fewer:

If the number of samples captured is fewer than the number requested,

If the trace was terminated early, a timeout or error occured, or

A programming error (such as forgetting to enable the channel).

Typically one executes BL_Trace and cycles through a sequence of BL_Acquire, one for each channel (on each device), before executing the next BL_Trace.

(5) Closing Devices and the Library

When you’re finished with the library, call BL_Close. This closes all open devices (it’s not possible to close only one). If you wish to close one of several devices, close them all and reopen those you wish to continue using.

Probe Files and Link Specifications

The Probe File is a configuration file on the host computer. It tells the Library where it can find the BitScopes and how to connect with them. The Probe File is a text file containing a list of Link Specifications defining connection protocols used via RS-232, USB or IP networks. It is also used by BitScope applications and is automatically created by these applications if it does not already exist. The Probe file may also be created manually with a text editor but it if does not exist when the library is used, built-in defaults are used instead.

Probe File Locations

There are two probe files on the host, one global and the other local. Both global and local Probe Files are named BitScope.prb (or bitscope.prb). The global probe file establishes system defaults and should not be modified. The local probe file is automatically created (from the global file, if the local file does not exist) and it may be manually or automatically modified, as required.

The global probe file will not exist if you have not installed the packaged version of the library but defaults apply in this case. On Linux and Mac systems, the probe file can also be located at:

~/.bitscope/config/bitscope.prb

but this location is depreciated and used for backward compatibility only.

Link Specification Syntax

Each line in the probe file is either blank, a comment or a link specification. A link specification defines a connection with a BitScope and has the same syntax when used directly with BL_Open as it does when it appears in a probe file. The following is an example probe file for a Linux system:

Windows systems are the same except the names used for serial and USB ports are COM1, COM2 … COM instead of /dev/ttyS0 or /dev/ttyUSB0 etc.

Probe File Defaults

If neither the local or global both probe files exist, built-in defaults are used. The library attempts to locate available BitScopes automatically in this case using an internal algorithm. Alternatively an explicit link specification can be provide to BL_Open when called (in which case the probe file is ignored). Defaults are also provided by the global probe file, if it exists. On Windows typical defaults are:

When using BL_Open with a probe file, links are probed in the order they appear in the local file, then the global file and finally the defaults are used. This is why the library can “magically open a BitScope”, only to find it’s not the BitScope you intended. Use BL_Open with an explicit link specification if you do not want this to happen.

Device Simulations

There two special types of device supported by the library: NIL and SIM.

A NIL device is a minimal device simulation sufficient to open and configure but not synthesize capture data. It is useful when developing software with library for use with BitScope devices you may not have available because it allows you to use the Library API to test that your code works with any supported model. A NIL device link specification looks like:

A SIM device is a more sophisticated device simulation that simulates the operation of some model BitScopes. In addition to a NIL device is synthesizes data as if captured by a real BitScope. It is available in some developer editions of the library only.

Diagnostics

You may be interested to know what the library is doing as your program runs. The BL_Log function is available to provide access to this information. It tells you what the library does and how long execution takes in response to your API function calls. Example output of BL_Log looks like this:

A detailed description of these diagnostics is beyond the scope of this manual but several general points to note are the:

first columm reports command (C), reply (R) or state (S) execution

second reports how many milliseconds between each command

third reports RPC (CALL), messaging (SEND) or execution (EXEC)

remaining lines indicate what actions are taken and vary per log entry

The BL_Log function may not be enabled in all editions of the library. For example, in optimized production releases it is usually disabled for performance reasons. By contrast, in developer editions more detailed diagnostics may available for specialized purposes. However using these generally requires a more advanced knowledge of the BitScope Capture Engine and its Virtual Machine Architecture. More information is available for OEM developers upon request.

Error Recovery

In the real world, errors happen.

For example, the power can fail or network connections can drop out.

The Library handles many errors automatically, for example by reinitiating a device request. However, some errors are too significant to recover this way in which case the client program must take additional steps to recover normal operation.

Take care with the third mechanism, BL_Acquire may return fewer samples than requested if you’ve made a set up programming error too!

In general, error recovery simply requires that you reprogram the BitScope the same way you did when you first opened it. That is, if an error is detected, re-execute your setup code before continuing as normal. If the error persists, one of the three error reporting mechanisms above will persist in which case you may wish to use BL_Error to determine the nature of the error (e.g. link down, power failure etc) and report it to the user to take appropriate action.

Most importantly, error detection and recovery is easy:

Minor errors (e.g. dropped packets) are handled automatically,

Major errors (e.g power failure) are recovered automatically (when restored)

Troubleshooting

The Library can’t find my BitScope!

Does the serial or USB port for the BitScope exist on your system when the BitScope is connected? Does your login name have permission to access it? If using a Network BitScope is the network address routable (does it “ping“) from your system?

Is your BitScope powered on and does it have a good quality power supply? Are the USB or Network and power cables you are using okay? Is your USB port working? Have you tried a different PC? Does other BitScope software connect okay?

Drop us a line any time at support@bitscope.com if you still have problems!

Which BitScope am I really connected to?

Sometimes when opening a BitScope you get what looks like the wrong one. It probably is. This is likely due to the use of probe file defaults. Call BL_Open with an explicit link specification for the BitScope you want to avoid this possibility.

Why does it take so long to connect?

If the probe file specifies a lot of links which are invalid or the devices they refer to are not available, BL_Open may take a long time to work through them all (in the order they appear in the probe file) until it reaches the one that ultimate connects. Note: using probe file that has no correct value can result in the same thing due to defaults.

If this is the case, simply comment out (preceed with #) each link you don’t need (or delete them entirely) or use an explicit link description instead of the probe file when calling BL_Open.

What parameter values does the library actually use?

For all such parameters you must check the return value of the parameter when you assign a new value because the return value is what the library will actually use.

Usually the requested and returned value will be the same but if you run up against the device constraints they may be different. Further, there are situations where changing one parameter (e.g. channel enable or trace mode) can alter the constraints that apply to others (e.g. sample rate or trace size).

Can I use the library in a multi-threaded environment?

Yes, but you need to know what you’re doing!

Access to the library functions is thread-safe but you need to be aware that many functions rely on the device, channel or input source being preselected by BL_Select and this can lead to a race condition in your code if you’re not careful.

To the extent we recommend you use multi-threaded programming we advise that all access to the library be confined to one thread with the call to the business end of the library (BL_Trace and BL_State) being available for use in another thread.

It’s safe to call BL_Trace synchronously in another thread and use BL_State in the main thread (or any other multi-threaded synchronization mechanism) to tell the main thread when the trace has completed.

However in general you don’t need to do this; instead, call BL_Trace asynchronously from the main thread and poll (e.g. in a timer handler) BL_State to check progress.

BL_Acquire - dump data from the device

Call BL_Acquire to dump data from a channel to the host (Acquire) after the data has been captured by the device (BL_Trace). Data is dumped from the selected channel on the selected device (BL_Select). To dump data from multiple channels, possibly on multiple devices, loop through and select each channel on each device and call BL_Acquire at each iteration.

Acquired data is written to the array in memory pointed to by AData. The number of samples acquired is ASize. The size of the array provided must be at leastASize. The dump commences at the first sample in the channel buffer unless a different (positive) starting index is specified (BL_Index). The sum of the dump size and start index must be less than or equal to the total trace size (BL_Size).

The return value is the number of samples acquired. It equals the number of samples requested (ASize) unless:

If 3 occurs you may need to take steps to recover the error. Like BL_Trace (when called synchronously) this function may take a while to complete. How long it takes depends on the speed of the link between the host and the device.

BL_Count - count devices, channels, or ranges

When one or more devices have been opened (BL_Open) one usually needs to know how many opened successfully. For each device one may also need to know many channels and how many analog ranges are available.

BL_Count returns a count based on its AType argument:

BL_COUNT_DEVICE - successfully opened devices

BL_COUNT_ANALOG - analog channels on the selected device

BL_COUNT_LOGIC - logic channels on the selected device

BL_COUNT_RANGE - number of analog ranges on the selected channel

When counting channels or ranges a device must first be selected (BL_Select).

BL_Coupling returns the newly selected couplingif successful or the prevailing coupling otherwise, so check the return value to determine if the requested coupling is available. Use BL_ASK to enquire the prevailing coupling without changing it.

BL_Enable - change channel enable status

Use BL_Enable to enable or disable the selected channel on the selected device from particpating in a trace. It’s generally good idea to disable channels you are not using because it frees up device buffers and other resources for the other channels.

BL_Error - return most recent error (if any)

In normal operation errors can occur. In general you don’t need to know what caused the error beyond whether it’s SNAFU or FUBAR and this level of detail is reported by BL_State.

However, when encountering a FUBAR class error you may need to report to the user an error code which will tell them what to fix to recover from it (e.g. restore device power). In this case the return value of BL_Error provides this information.

BL_Halt - all any pending or prevailing device activity

Call BL_Halt to terminate any pending or prevailing device activity. Returns TRUE if successful, FALSE otherwise. BL_Halt returns FALSE only if an error occured when talking to the device; in this case you may need to recover the error. BL_Halt does not need to be called if the capture engine state is not BL_STATE_ACTIVE but it is safe to call it at any time.

BL_ID - return the selected device ID

This information is useful to record with captured data so as to keep a record of which device produced that data. It may also be used in a link specification to ensure one connects to a uniquely identified device.

BL_Intro - assign the pre-trigger size (intro region)

BitScopes offer a facility to capture before the trigger (in most trace modes). BL_Intro establishes this pre-trigger capture duration (APreTrigger, in seconds). It returns the same value if the device can support it, otherwise the nearest value is returned.

Always check the return value because it is the value that is actually used.

To specify that no pre-trigger capture should be used, specify BL_ZERO.

BL_Log - dump the pending log

In developer editions of the library the internal operation of the library is logged. BL_Log returns a dump of this information to assist with program development using the library. See Diagnostics for more information.

BL_Mode - select and trace mode

All BitScope models offer a range of trace modes. Trace modes define how the device captures the input signals:

BL_MODE_FAST - analog capture at the fastest rates available

BL_MODE_DUAL - dual channel sample synchronous analog capture

BL_MODE_MIXED - mixed analog + logic signal capture

BL_MODE_LOGIC - logic only capture mode

BL_MODE_STREAM - streaming mixed signal capture

All models offer BL_MODE_FAST and BL_MODE_MIXED. The other modes are available on some models and not others; it depends on the hardware design of each model. See the hardware guide for your device.

BL_MODE_FAST is recommended for analog waveform capture only and BL_MODE_MIXED when also capturing logic data. BL_MODE_DUAL is recommended for single A/D devices when sample synchronous analog waveform capture is required. BL_MODE_LOGIC is recommend when capturing logic only and BL_MODE_STREAM is used for continuous waveform capture.

BL_Offset - assign channel offset

Most BitScope models allow an input offset to be applied to the signal captured on analog channels. BL_Offset assigns this offset (AValue, in volts) to the selected channel on the selected device. It returns the same value if the device can support it, otherwise the nearest value is returned.

Always check the return value because it is the value that is actually used.

It must always be specified and it should be the first parameter assigned when preparing a new trace (if different from the previous trace).

BL_Rate establishes the preferred sample rate (ASampleRate, in Hz). It returns the same value if the device can support it, otherwise the nearest value is returned.

To choose the highest sample rate supported by the selected device in the current mode, specify BL_MAX_RATE. To enquire what the prevailing sample rate is without changing it, specify BL_ASK. Regardless of how BL_Rate is called always check the return value because it is the value that is actually used.

The library makes available multiple devices, channels and input sources. Most API functions operate on one of these at a time. Use BL_Select to choose which one.

BL_Selects chooses which entity type to select via its first (AType) argument:

BL_SELECT_DEVICE - select a device

BL_SELECT_CHANNEL - select a channel on the (previously) selected device

BL_SELECT_SOURCE - select an input source of the selected channel

The entity of that type is selected via the second (AIndex) argument.

BL_Select returns the index of the selected entityif the selection was successful. The prevailing selection is returned unchanged otherwise, so check the return value is the same as the AIndex argument to confirm the new selection was successful. Use BL_ASK to enquire the prevailing selection without changing it.

BL_Size - assign the capture size (samples)

The capture size is a fundamentally important trace parameter. It must always be specified and it should be the second parameter assigned (after BL_Rate) when preparing a new trace (if different from the previous trace).

BL_Size establishes the preferred trace size (ASize, in samples). It returns the same value if the device can support it, otherwise the nearest value is returned. To choose the largest size supported by the selected device in the current mode, specify BL_MAX_SIZE. To enquire what the prevailing size is without changing it, specify BL_ASK. Regardless of how BL_Size is called always check the return value because it is the value that is actually used.

The only state in which it is valid to call BL_Acquire is BL_STATE_DONE. This state means the trace completed successfully, either because a trigger was seen or a timeout occured but in either case data may be acquired from the device.

If BL_STATE_ERROR is reported an error occured during the most recent trace. The trace has completed but the data (if any) cannot be relied upon as reliable. Call BL_Error to learn more about the error and what you may need to do to recover.

While BL_STATE_ACTIVE is reported you must not call any other function to access the device unless you halt it first. If BL_STATE_IDLE is reported you can program the device as required but data is not guaranteed to be available for BL_Acquire.

BL_Statemay be called at any time after the library has been initialized and device selected. If BL_Trace is called synchronouslyit reports the same information except in this case the BL_STATE_ACTIVE state will never be reported (because it prevails only for as long as the synchronous call to BL_Trace does).

BL_Time - assign the capture duration (seconds)

The capture duration is usually assigned implicitly (as a consequence of the prevailing BL_Rate and BL_Size). It may also be specified explicitly but if it is, the sample rate and trace size may also be modified their values should be rechecked.

The recommended use for this function is to enquire what the prevailing duration is without changing it by specifing BL_ASK. Regardless of how BL_Time is called always check the return value because it is the value that is actually used.

The process of capturing data on BitScope is referred to as a trace. Call BL_Trace to initiate a traceafter calling the other functions as required to setup the trace.

BL_Trace is unique because the time it takes to execute can be indeterminate (which depends on the trigger). You must take care to call it correctly, especially if called from your main application thread; it may never return if called synchronously without a timeout. It can be recovered in this case, but only from a different thread.

The first argument (ATimeOut, in seconds) specifies the timeout used and the second (ASync) specifies the call is to be asynchronous. The return value indicates whether BL_Trace commenced successfully (in the asynchronous case) or commenced and completed successfully (in the synchronous case).

The simplest usage is a synchronous call with a non-zero timeout. In this case BL_Trace will block the caller and return when:

If the timeout is short (on a human timescale), this type of usage is compatible with single threaded programming for an interractive program. It is simple because the return value of BL_Trace may be used directly to detemine success (i.e. BL_State is not required) and all programming is synchronous.

If the timeout required is long or you need to specify infinite timeout (i.e. the trigger timing is unknown), an asynchronous call is recommended (unless you are calling BL_Trace from a different thread). In this case BL_Trace will always return to the caller immediately but the trace may not have completed. The return value in this case will always be TRUE unless an error occured when talking to the device.

When BL_Trace is called asynchronously you must poll the trace state (BL_State) to determine when the trace has completed; it is a programming error to use any other library function (except BL_Halt) before the trace has completed.

Two special values for the timeout are available:

BL_TRACE_FORCED - commence immediately regardless of the trigger

BL_TRACE_FOREVER - commence and wait for the trigger, possibly forever.

Use the former if want a trace and you don’t care about the trigger condition (the trigger condition is ignored in this case). Use the latter if you want to wait for as long as it takes for a trigger. If the trigger condition is never met, the trace will never complete unless manually halted.

If BL_Trace is used with a timeout or with BL_TRACE_FOREVER, a trigger condition is applied as a predicate to the completion of the trace. This means the trace will complete only when the trigger condition is satisfied.

Use BL_Trigger to establish a trigger condition on a selected channel. Call it multiple times, once for each channel, if a combinatorial condition is required to apply to more than one channel.

When using the library is may necessary to know the device, library or other version information. This functions provides access to this information as it applies to the selected device. There are several version types that may be requested:

BL_VERSION_DEVICE - device model and version identifier

BL_VERSION_LIBRARY - library version and production build ID

BL_VERSION_BINDING - language binding and version

BL_VERSION_PLATFORM - build platform version

BL_VERSION_FRAMEWORK - library framework version

BL_VERSION_NETWORK - network communication version

In general you will likely be interested in the first two. The other versions are available to help diagnosis in the event that you discover problems when using a particular instance of the library or its language bindings.

License

This document may be copied and redistributed under the terms of the GNU Free Documentation License as published by the Free Software Foundation; either version 1.2, or (at your option) any later version.

Version

In this case an Application Programming Interface (API) is this library which includes a detailed specification for a set of callable functions (ref) ↩

C is a general-purpose programming language. It is one of the most widely used programming languages of all time (ref) ↩

C++ is a statically typed, free-form, multi-paradigm, compiled, general-purpose programming language. It is regarded as an intermediate-level language, as it comprises both high-level and low-level language features. It is one of the most popular programming languages and is implemented on a wide variety of hardware and operating system platforms (ref) ↩

Pascal is an influential imperative and procedural programming language first published in 1970 which has since been extended with object oriented capabilies. It is a small and efficient language intended to encourage good programming practices using structured programming and data structuring (ref) ↩