Loading...
Searching...
No Matches
UHD - C API

# Introduction

Alongside its C++ API, UHD provides a C API wrapper for the uhd::usrp::multi_usrp and uhd::usrp_clock::multi_usrp_clock classes, as well as their associated classes and structs. Other important UHD functions are also included in this API. To use this API, simply:

#include <uhd.h>
uhd.h

...and all UHD C-level structs and functions will be available to you. The sections below give more detail on the key features of the C API.

## C-Level Handles

Most of the UHD classes that can be accessed on the C level are done so through handles, which internally store the C++ representation and allow access to internal values through helper functions.

All handles have associated *_make() and *_free() functions. After creating a handle, it must be passed through its make() function before it can be used in your program. Before the program terminates, you must pass the handle into its free() function, or your program will have a memory leak. The example below shows the proper usage of an RX metadata handle over the course of its lifetime, from instantiation to destruction.

uhd_rx_metadata_handle md;
uhd_rx_metadata_make(&md);
// Streaming here puts useful information into metadata
int64_t full_secs;
double frac_secs;
uhd_rx_metadata_time_spec(md, &full_secs, &frac_secs);
uhd_rx_metadata_free(&md);
uhd_rx_metadata_make
UHD_API uhd_error uhd_rx_metadata_make(uhd_rx_metadata_handle *handle)
Create a new RX metadata handle.
uhd_rx_metadata_handle
struct uhd_rx_metadata_t * uhd_rx_metadata_handle
RX metadata interface for describing sent IF data.
Definition metadata.h:54
uhd_rx_metadata_free
UHD_API uhd_error uhd_rx_metadata_free(uhd_rx_metadata_handle *handle)
Free an RX metadata handle.
uhd_rx_metadata_time_spec
UHD_API uhd_error uhd_rx_metadata_time_spec(uhd_rx_metadata_handle h, int64_t *full_secs_out, double *frac_secs_out)
Time of first sample.

Again, make sure to pass your handle into a make() function before using it, or you will run into undefined behavior. Also be careful not to use the handle after passing it into a free() function, or your program will segfault.

## Error Codes

As C cannot handle C++ runtime exceptions, UHD's C wrapper functions catch all exceptions and translate them into error codes, which are returned by each function. Any output variables are passed in as pointers into the function, which will set them internally.

Each uhd::runtime_error has a corresponding uhd_error value. Separate error codes indicate that a boost::exception or std::exception has been thrown, and any other exceptions are indicated by a catch-all UHD_ERROR_UNKNOWN code.

All UHD C-level handles store the string representation of the last C++ exception thrown internally. These handles have corresponding *_get_last_error() functions that will place the error string into a supplied string buffer.

For example, if a USRP device's handle throws an exception internally, the following code can access its error info:

char err_msg[256];
uhd_usrp_handle usrp;
double gain;
// USRP configuration done here
uhd_error error_code = uhd_usrp_get_rx_gain(usrp, 0, "", &gain);
if(error_code){
uhd_usrp_get_last_error(usrp, err_msg, 256);
fprintf(stderr, "Error code %d: %s\n", error_code, err_msg);
}
uhd_error
uhd_error
UHD error codes.
Definition error.h:20
uhd_usrp_get_rx_gain
UHD_API uhd_error uhd_usrp_get_rx_gain(uhd_usrp_handle h, size_t chan, const char *gain_name, double *gain_out)
Get the given channel's RX gain.
uhd_usrp_handle
struct uhd_usrp * uhd_usrp_handle
C-level interface for working with a USRP device.
Definition usrp.h:255

All error codes can be found in <uhd/error.h>.

## Example Code

UHD provides two examples that demonstrate the typical use case of the C API: RX and TX streaming. The rx_samples_c example is a simplified C version of rx_samples_to_file, and the tx_samples_c example is a simplified C version of tx_waveforms. These examples can be easily adapted or serve as a starting point for your own UHD C applications.