Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions README_BUILD.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,46 @@ It will try to link against the `call_function` symbol even though it's clearly

For this reason, when building with MSVC, please build in `RelWithDebInfo` mode. If you try to build in `Debug` mode, it will error.

## Environment Variable Configuration

### DMA Heap Path Configuration

libiio supports configuring the DMA heap path globally through the `LIBIIO_DMA_HEAP_PATH` environment variable. This overrides the default `/dev/dma_heap/system` path for all IIO devices.

#### Supported Format (Global Only)
```bash
export LIBIIO_DMA_HEAP_PATH=heap_name
```
This will use `/dev/dma_heap/<heap_name>` for every device.

#### Accepted Values

The environment variable accepts only the following predefined heap names:
- `system` (default when unset or empty)
- `default_cma_region`
- `reserved`
- `linux,cma`
- `default-pool`

**Examples:**
```bash
export LIBIIO_DMA_HEAP_PATH=default_cma_region
./an_iio_application

export LIBIIO_DMA_HEAP_PATH=reserved
./an_iio_application
```

#### Behavior and Error Handling

- **Unset or empty**: Defaults to `system` heap (`/dev/dma_heap/system`)
- **Valid value**: Uses the specified heap (`/dev/dma_heap/<heap_name>`)
- **Invalid value**: **Operation fails with error** - no fallback occurs

Setting an invalid heap name will cause DMABUF operations to fail immediately with an error message listing the accepted values. This ensures users are aware when their configuration is incorrect rather than silently using a fallback.

This feature is intended for users who need to select an alternative DMA heap present under `/dev/dma_heap/` (for example a reserved or CMA heap).

## Instructions applicable to Microcontroller configurations

### Install Prerequisites/Dependencies
Expand Down
2 changes: 1 addition & 1 deletion bindings/cpp/iio.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ class Device : public impl::IndexedSequence<Device, Channel>
Device trigger() const {return Device{const_cast<iio_device*>(impl::check(iio_device_get_trigger(p), "iio_device_get_trigger"))};}
void set_trigger(iio_device const * trigger) {impl::check(iio_device_set_trigger(p, trigger), "iio_device_set_trigger");}
bool is_trigger() const {return iio_device_is_trigger(p);}
BufferPtr create_buffer(iio_buffer_params * params, iio_channels_mask * mask) {return BufferPtr(impl::check(iio_device_create_buffer(p, params, mask), "iio_device_create_buffer"));}
BufferPtr create_buffer(unsigned int idx, iio_channels_mask * mask) {return BufferPtr(impl::check(iio_device_create_buffer(p, idx, mask), "iio_device_create_buffer"));}
bool is_hwmon() const {return iio_device_is_hwmon(p);}
EventStreamPtr create_event_stream() { return EventStreamPtr{impl::check(iio_device_create_event_stream(p), "iio_device_create_event_stream")};}
ssize_t sample_size(iio_channels_mask * mask) const {return impl::check_n(iio_device_get_sample_size(p, mask), "iio_device_get_sample_size");}
Expand Down
6 changes: 3 additions & 3 deletions bindings/csharp/IOBuffer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ namespace iio
public class IOBuffer : IIOObject
{
[DllImport(IioLib.dllname, CallingConvention = CallingConvention.Cdecl)]
private static extern IIOPtr iio_device_create_buffer(IntPtr dev, IntPtr buffer_params, IntPtr mask);
private static extern IIOPtr iio_device_create_buffer(IntPtr dev, uint index, IntPtr mask);

[DllImport(IioLib.dllname, CallingConvention = CallingConvention.Cdecl)]
private static extern void iio_buffer_destroy(IntPtr buf);
Expand Down Expand Up @@ -75,12 +75,12 @@ public bool enabled {
/// <param name="mask">The channels mask to use to create the buffer object.</param>
/// <param name="index">The index of the hardware buffer. Should be 0 in most cases.</param>
/// <exception cref="IioLib.IIOException">The buffer could not be created.</exception>
public IOBuffer(Device dev, ChannelsMask mask)
public IOBuffer(Device dev, ChannelsMask mask, uint index = 0)
{
this.mask = mask;
this.dev = dev;

IIOPtr ptr = iio_device_create_buffer(dev.dev, IntPtr.Zero, mask.hdl);
IIOPtr ptr = iio_device_create_buffer(dev.dev, index, mask.hdl);
if (!ptr)
throw new IIOException("Unable to create buffer", ptr);

Expand Down
10 changes: 3 additions & 7 deletions bindings/python/iio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,6 @@ class _Attr(Structure):
class ContextParams(Structure):
pass # TODO

class BufferParams(Structure):
pass # TODO

class DataFormat(Structure):
"""Represents the data format of an IIO channel."""

Expand Down Expand Up @@ -317,7 +314,6 @@ class ChannelType(Enum):
_BlockPtr = _POINTER(_Block)
_DataFormatPtr = _POINTER(DataFormat)
_ContextParamsPtr = _POINTER(ContextParams)
_BufferParamsPtr = _POINTER(BufferParams)
_StreamPtr = _POINTER(_Stream)
_AttrPtr = _POINTER(_Attr)

Expand Down Expand Up @@ -654,7 +650,7 @@ class ChannelType(Enum):
_create_buffer.restype = _BufferPtr
_create_buffer.argtypes = (
_DevicePtr,
_BufferParamsPtr,
c_uint,
_ChannelsMaskPtr,
)
_create_buffer.errcheck = _check_ptr_err
Expand Down Expand Up @@ -1103,7 +1099,7 @@ def buffer(self):
class Buffer(_IIO_Object):
"""Represents a hardware I/O buffer."""

def __init__(self, device, mask, params):
def __init__(self, device, mask, idx=0):
"""
Initialize a new instance of the Buffer class.

Expand All @@ -1119,7 +1115,7 @@ def __init__(self, device, mask, params):
An new instance of this class
"""
try:
self._buffer = _create_buffer(device._device, params._params, mask._mask)
self._buffer = _create_buffer(device._device, idx, mask._mask)
except Exception:
self._buffer = None
raise
Expand Down
20 changes: 3 additions & 17 deletions buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,7 @@ static int iio_buffer_enqueue_worker(void *_, void *d)
}

struct iio_buffer *
iio_device_create_buffer(const struct iio_device *dev,
struct iio_buffer_params *params,
iio_device_create_buffer(const struct iio_device *dev, unsigned int idx,
const struct iio_channels_mask *mask)
{
const struct iio_backend_ops *ops = dev->ctx->ops;
Expand All @@ -122,21 +121,8 @@ iio_device_create_buffer(const struct iio_device *dev,
if (!buf)
return iio_ptr(-ENOMEM);

if (params) {
/* We need to make sure that all reserved bytes are zero initialized.
* This is important for the ABI stability.
*/
for (i = 0; i < sizeof(buf->params.__rsrv); i++) {
if (params->__rsrv[i]) {
dev_err(dev, "Reserved bytes in buffer params must be zero.\n");
err = -E2BIG;
goto err_free_buf;
}
}

buf->params = *params;
}
buf->dev = dev;
buf->idx = idx;

/* Duplicate buffer attributes from the iio_device.
* This ensures that those can contain a pointer to our iio_buffer */
Expand Down Expand Up @@ -175,7 +161,7 @@ iio_device_create_buffer(const struct iio_device *dev,
if (err < 0)
goto err_free_mutex;

buf->pdata = ops->create_buffer(dev, &buf->params, buf->mask);
buf->pdata = ops->create_buffer(dev, idx, buf->mask);
err = iio_err(buf->pdata);
if (err < 0)
goto err_destroy_worker;
Expand Down
5 changes: 2 additions & 3 deletions compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ struct iio_channel;
struct iio_channels_mask;
struct iio_context;
struct iio_context_params;
struct iio_buffer_params;
struct iio_data_format;
struct iio_device;
struct iio_scan;
Expand Down Expand Up @@ -168,7 +167,7 @@ struct compat {

/* Buffers */
struct iio_buffer * (*iio_device_create_buffer)(const struct iio_device *,
struct iio_buffer_params *,
unsigned int,
const struct iio_channels_mask *);
void (*iio_buffer_destroy)(struct iio_buffer *);
void (*iio_buffer_cancel)(struct iio_buffer *);
Expand Down Expand Up @@ -2038,7 +2037,7 @@ struct iio_buffer * iio_device_create_buffer(const struct iio_device *dev,
len = samples_count * compat->sample_size;
compat->size = len;

buf = IIO_CALL(iio_device_create_buffer)(dev, NULL, dev_compat->mask);
buf = IIO_CALL(iio_device_create_buffer)(dev, 0, dev_compat->mask);
err = iio_err(buf);
if (err)
goto err_free_compat;
Expand Down
4 changes: 2 additions & 2 deletions examples/ad9361-iiostream.c
Original file line number Diff line number Diff line change
Expand Up @@ -263,14 +263,14 @@ int main (int argc, char **argv)
iio_channel_enable(tx0_q, txmask);

printf("* Creating non-cyclic IIO buffers with 1 MiS\n");
rxbuf = iio_device_create_buffer(rx, NULL, rxmask);
rxbuf = iio_device_create_buffer(rx, 0, rxmask);
err = iio_err(rxbuf);
if (err) {
rxbuf = NULL;
dev_perror(rx, err, "Could not create RX buffer");
shutdown();
}
txbuf = iio_device_create_buffer(tx, NULL, txmask);
txbuf = iio_device_create_buffer(tx, 0, txmask);
err = iio_err(txbuf);
if (err) {
txbuf = NULL;
Expand Down
4 changes: 2 additions & 2 deletions examples/ad9371-iiostream.c
Original file line number Diff line number Diff line change
Expand Up @@ -270,14 +270,14 @@ int main (int argc, char **argv)
iio_channel_enable(tx0_q, txmask);

printf("* Creating non-cyclic IIO buffers with 1 MiS\n");
rxbuf = iio_device_create_buffer(rx, NULL, rxmask);
rxbuf = iio_device_create_buffer(rx, 0, rxmask);
err = iio_err(rxbuf);
if (err) {
rxbuf = NULL;
dev_perror(rx, err, "Could not create RX buffer");
shutdown();
}
txbuf = iio_device_create_buffer(tx, NULL, txmask);
txbuf = iio_device_create_buffer(tx, 0, txmask);
err = iio_err(txbuf);
if (err) {
txbuf = NULL;
Expand Down
4 changes: 2 additions & 2 deletions examples/adrv9002-iiostream.c
Original file line number Diff line number Diff line change
Expand Up @@ -281,14 +281,14 @@ int main(int argc, char **argv)
}

info("* Creating non-cyclic IIO buffers with 1 MiS\n");
rxbuf = iio_device_create_buffer(rx, NULL, rxmask);
rxbuf = iio_device_create_buffer(rx, 0, rxmask);
if (iio_err(rxbuf)) {
rxbuf = NULL;
ctx_perror(ctx, iio_err(rxbuf), "Could not create RX buffer");
goto clean;
}

txbuf = iio_device_create_buffer(tx, NULL, txmask);
txbuf = iio_device_create_buffer(tx, 0, txmask);
if (iio_err(txbuf)) {
txbuf = NULL;
ctx_perror(ctx, iio_err(txbuf), "Could not create TX buffer");
Expand Down
4 changes: 2 additions & 2 deletions examples/adrv9009-iiostream.c
Original file line number Diff line number Diff line change
Expand Up @@ -262,14 +262,14 @@ int main (int argc, char **argv)
iio_channel_enable(tx0_q, txmask);

printf("* Creating non-cyclic IIO buffers with 1 MiS\n");
rxbuf = iio_device_create_buffer(rx, NULL, rxmask);
rxbuf = iio_device_create_buffer(rx, 0, rxmask);
err = iio_err(rxbuf);
if (err) {
rxbuf = NULL;
ctx_perror(ctx, err, "Could not create RX buffer");
shutdown();
}
txbuf = iio_device_create_buffer(tx, NULL, txmask);
txbuf = iio_device_create_buffer(tx, 0, txmask);
err = iio_err(txbuf);
if (err) {
txbuf = NULL;
Expand Down
2 changes: 1 addition & 1 deletion examples/dummy-iiostream.c
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ int main (int argc, char **argv)
}

printf("* Creating non-cyclic RX IIO buffer\n");
rxbuf = iio_device_create_buffer(dev, NULL, rxmask);
rxbuf = iio_device_create_buffer(dev, 0, rxmask);
err = iio_err(rxbuf);
if (err) {
rxbuf = NULL;
Expand Down
2 changes: 1 addition & 1 deletion examples/iio_adi_xflow_check.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ int main(int argc, char **argv)
printf("Monitoring %s for underflows/overflows\n",
iio_device_get_name(dev));

buffer = iio_device_create_buffer(dev, NULL, mask);
buffer = iio_device_create_buffer(dev, 0, mask);
ret = iio_err(buffer);
if (ret) {
IIO_PERROR(ret, "Unable to create buffer");
Expand Down
3 changes: 2 additions & 1 deletion iio-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,8 @@ struct iio_buffer {
size_t length;

struct iio_channels_mask *mask;
struct iio_buffer_params params;
unsigned int idx;

struct iio_task *worker;

/* These two fields are set by the last block created. They are only
Expand Down
Loading