This example libiio program is meant to exercise the features of IIO present in the sample dummy IIO device in the linux kernel.
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <stdio.h>
#include <errno.h>
#include <getopt.h>
#include <inttypes.h>
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#define IIO_ENSURE(expr) { \
if (!(expr)) { \
(void) fprintf(stderr, "assertion failed (%s:%d)\n", __FILE__, __LINE__); \
(void) abort(); \
} \
}
static char *name = "iio_dummy_part_no";
static char *trigger_str = "instance1";
static int buffer_length = 1;
static int count = -1;
enum {
BUFFER_POINTER,
SAMPLE_CALLBACK,
CHANNEL_READ_RAW,
CHANNEL_READ,
MAX_READ_METHOD,
};
static int buffer_read_method = BUFFER_POINTER;
static unsigned int channel_count;
static bool stop;
static bool has_repeat;
static void shutdown(void)
{
int ret;
if (channels) { free(channels); }
printf("* Destroying buffers\n");
printf("* Disassociate trigger\n");
if (dev) {
if (ret < 0) {
char buf[256];
fprintf(stderr, "%s while Disassociate trigger\n", buf);
}
}
printf("* Destroying context\n");
exit(0);
}
static void handle_sig(int sig)
{
printf("Waiting for process to finish... got signal : %d\n", sig);
stop = true;
}
static ssize_t sample_cb(
const struct iio_channel *chn,
void *src,
size_t bytes, __notused
void *d)
{
for (j = 0; j <
repeat; ++j) {
if (bytes == sizeof(int16_t))
printf("%" PRIi16 " ", ((int16_t *)src)[j]);
else if (bytes == sizeof(int64_t))
printf("%" PRId64 " ", ((int64_t *)src)[j]);
}
}
static void usage(__notused int argc, char *argv[])
{
printf("Usage: %s [OPTION]\n", argv[0]);
printf(" -d\tdevice name (default \"iio_dummy_part_no\")\n");
printf(" -t\ttrigger name (default \"instance1\")\n");
printf(" -b\tbuffer length (default 1)\n");
printf(" -r\tread method (default 0 pointer, 1 callback, 2 read raw, 3 read)\n");
printf(" -c\tread count (default no limit)\n");
}
static void parse_options(int argc, char *argv[])
{
int c;
while ((c = getopt(argc, argv, "d:t:b:r:c:h")) != -1) {
switch (c)
{
case 'd':
name = optarg;
break;
case 't':
trigger_str = optarg;
break;
case 'b':
buffer_length = atoi(optarg);
break;
case 'r':
if (atoi(optarg) >= 0 && atoi(optarg) < MAX_READ_METHOD) {
buffer_read_method = atoi(optarg);
} else {
usage(argc, argv);
exit(1);
}
break;
case 'c':
if (atoi(optarg) > 0) {
count = atoi(optarg);
} else {
usage(argc, argv);
exit(1);
}
break;
case 'h':
default:
usage(argc, argv);
exit(1);
}
}
}
int main (int argc, char **argv)
{
parse_options(argc, argv);
signal(SIGINT, handle_sig);
unsigned int i, j, major, minor;
char git_tag[8];
printf("Library version: %u.%u (git tag: %s)\n", major, minor, git_tag);
has_repeat = ((major * 10000) + minor) >= 8 ? true : false;
printf("* Acquiring IIO context\n");
printf("* Acquiring device %s\n", name);
if (!dev) {
perror("No device found");
shutdown();
}
printf("* Initializing IIO streaming channels:\n");
channel_count++;
}
}
if (channel_count == 0) {
printf("No scan elements found (make sure the driver built with 'CONFIG_IIO_SIMPLE_DUMMY_BUFFER=y')\n");
shutdown();
}
channels = calloc(channel_count, sizeof *channels);
if (!channels) {
perror("Channel array allocation failed");
shutdown();
}
for (i = 0; i < channel_count; ++i) {
channels[i] = chn;
}
printf("* Acquiring trigger %s\n", trigger_str);
perror("No trigger found (try setting up the iio-trig-hrtimer module)");
shutdown();
}
printf("* Enabling IIO streaming channels for buffered capture\n");
for (i = 0; i < channel_count; ++i)
printf("* Enabling IIO buffer trigger\n");
perror("Could not set trigger\n");
shutdown();
}
printf("* Creating non-cyclic IIO buffers with %d samples\n", buffer_length);
if (!rxbuf) {
perror("Could not create buffer");
shutdown();
}
printf("* Starting IO streaming (press CTRL+C to cancel)\n");
int64_t last_ts = 0;
while (!stop)
{
ssize_t nbytes_rx;
char *p_dat, *p_end;
ptrdiff_t p_inc;
int64_t now_ts;
if (nbytes_rx < 0) {
printf("Error refilling buf: %d\n", (int)nbytes_rx);
shutdown();
}
if (has_ts)
for (p_dat =
iio_buffer_first(rxbuf, channels[channel_count-1]); p_dat < p_end; p_dat += p_inc) {
now_ts = (((int64_t *)p_dat)[0]);
printf("[%04" PRId64 "] ", last_ts > 0 ? (now_ts - last_ts)/1000/1000 : 0);
last_ts = now_ts;
}
switch (buffer_read_method)
{
case BUFFER_POINTER:
for (i = 0; i < channel_count; ++i) {
for (p_dat =
iio_buffer_first(rxbuf, channels[i]); p_dat < p_end; p_dat += p_inc) {
for (j = 0; j <
repeat; ++j) {
if (fmt->
length/8 ==
sizeof(int16_t))
printf("%" PRIi16 " ", ((int16_t *)p_dat)[j]);
else if (fmt->
length/8 ==
sizeof(int64_t))
printf("%" PRId64 " ", ((int64_t *)p_dat)[j]);
}
}
}
printf("\n");
break;
case SAMPLE_CALLBACK: {
int ret;
if (ret < 0) {
char buf[256];
fprintf(stderr, "%s while processing buffer\n", buf);
}
printf("\n");
break;
}
case CHANNEL_READ_RAW:
case CHANNEL_READ:
for (i = 0; i < channel_count; ++i) {
uint8_t *buf;
size_t sample, bytes;
buf = malloc(sample_size * buffer_length);
if (!buf) {
perror("trying to allocate memory for buffer\n");
shutdown();
}
if (buffer_read_method == CHANNEL_READ_RAW)
else
for (sample = 0; sample < bytes / sample_size; ++sample) {
for (j = 0; j <
repeat; ++j) {
if (fmt->
length / 8 ==
sizeof(int16_t))
printf("%" PRIi16 " ", ((int16_t *)buf)[sample+j]);
else if (fmt->
length / 8 ==
sizeof(int64_t))
printf("%" PRId64 " ", ((int64_t *)buf)[sample+j]);
}
}
free(buf);
}
printf("\n");
break;
}
if (count != -1 && --count == 0)
break;
}
shutdown();
return 0;
}
void * iio_buffer_first(const struct iio_buffer *buffer, const struct iio_channel *chn)
Find the first sample of a channel in a buffer.
Definition: buffer.c:250
ptrdiff_t iio_buffer_step(const struct iio_buffer *buffer)
Get the step size between two samples of one channel.
Definition: buffer.c:288
__api __check_ret ssize_t iio_buffer_foreach_sample(struct iio_buffer *buf, ssize_t(*callback)(const struct iio_channel *chn, void *src, size_t bytes, void *d), void *data)
Call the supplied callback for each sample found in a buffer.
void * iio_buffer_end(const struct iio_buffer *buffer)
Get the address that follows the last sample in a buffer.
Definition: buffer.c:293
void iio_buffer_destroy(struct iio_buffer *buffer)
Destroy the given buffer.
Definition: buffer.c:104
ssize_t iio_buffer_refill(struct iio_buffer *buffer)
Fetch more samples from the hardware.
Definition: buffer.c:123
struct iio_buffer * iio_device_create_buffer(const struct iio_device *dev, size_t samples_count, bool cyclic)
Create an input or output buffer associated to the given device.
Definition: buffer.c:26
bool iio_channel_is_scan_element(const struct iio_channel *chn)
Return True if the given channel is a scan element.
Definition: channel.c:318
void iio_channel_enable(struct iio_channel *chn)
Enable the given channel.
Definition: channel.c:450
size_t iio_channel_read(const struct iio_channel *chn, struct iio_buffer *buf, void *dst, size_t len)
Demultiplex and convert the samples of a given channel.
Definition: channel.c:640
size_t iio_channel_read_raw(const struct iio_channel *chn, struct iio_buffer *buf, void *dst, size_t len)
Demultiplex the samples of a given channel.
Definition: channel.c:625
const char * iio_channel_get_id(const struct iio_channel *chn)
Retrieve the channel ID (e.g. voltage0)
Definition: channel.c:303
struct iio_context * iio_create_default_context(void)
Create a context from local or remote IIO devices.
Definition: context.c:415
void iio_context_destroy(struct iio_context *ctx)
Destroy the given context.
Definition: context.c:258
unsigned int iio_context_get_devices_count(const struct iio_context *ctx)
Enumerate the devices found in the given context.
Definition: context.c:280
struct iio_device * iio_context_find_device(const struct iio_context *ctx, const char *name)
Try to find a device structure by its ID, label or name.
Definition: context.c:294
const struct iio_data_format * iio_channel_get_data_format(const struct iio_channel *chn)
Get a pointer to a channel's data format structure.
Definition: channel.c:438
int iio_device_set_trigger(const struct iio_device *dev, const struct iio_device *trigger)
Associate a trigger to a given device.
Definition: device.c:402
struct iio_channel * iio_device_get_channel(const struct iio_device *dev, unsigned int index)
Get the channel present at the given index.
Definition: device.c:148
bool iio_device_is_trigger(const struct iio_device *dev)
Return True if the given device is a trigger.
Definition: device.c:368
unsigned int iio_device_get_channels_count(const struct iio_device *dev)
Enumerate the channels of the given device.
Definition: device.c:143
__api void iio_strerror(int err, char *dst, size_t len)
Get a string description of an error code.
Definition: utilities.c:204
__api void iio_library_get_version(unsigned int *major, unsigned int *minor, char git_tag[8])
Get the version of the libiio library.
Definition: utilities.c:192
An input or output buffer, used to read or write samples.
Represents an input or output channel of a device.
Contains the representation of an IIO context.
Represents a device in the IIO context.