---
name: "hal_stream"
section: "3hal"
platform: "linux"
package: "linuxcnc-uspace-dev"
version: "1:2.9.4-2+deb13u1"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/hal_stream"
---

# hal\_stream(3hal)

non-blocking realtime streams

## NAME

hal\_stream - non-blocking realtime streams

## SYNOPSIS

.B #include \<hal.h\>

int hal\_stream\_create(hal\_stream\_t \*stream, int comp\_id, int key, int depth, const char \*typestring);\
 void hal\_stream\_destroy(hal\_stream\_t \*stream);\
 int hal\_stream\_attach(hal\_stream\_t \*stream, int comp\_id, int key, const char \*typestring);\
 int hal\_stream\_detach(hal\_stream\_t \*stream);

int hal\_stream\_element\_count(hal\_stream\_t \*stream);\
 hal\_type\_t hal\_stream\_element\_type(hal\_stream\_t \*stream, int idx);\
 int hal\_stream\_depth(hal\_stream\_t \*stream);\
 int hal\_stream\_maxdepth(hal\_stream\_t \*stream);\
 int hal\_stream\_num\_underruns(hal\_stream\_t \*stream);\
 int hal\_stream\_num\_overruns(hal\_stream\_t \*stream);

int hal\_stream\_read(hal\_stream\_t \*stream, union hal\_stream\_data \*buf, unsigned \*sampleno);\
 bool hal\_stream\_readable(hal\_stream\_t \*stream);

int hal\_stream\_write(hal\_stream\_t \*stream, union hal\_stream\_data \*buf);\
 bool hal\_stream\_writable(hal\_stream\_t \*stream);

.B #ifdef ULAPI\
 void hal\_stream\_wait\_writable(hal\_stream\_t \*stream, sig\_atomic\_t \*stop);\
 void hal\_stream\_wait\_readable(hal\_stream\_t \*stream, sig\_atomic\_t \*stop);\
 .B #endif

## DESCRIPTION

A HAL stream provides a limited ability for two components to communicate data which does not fit within the model of HAL pins.  A reader and a writer must agree on a *key* (32-bit integer identifier) and a data structure specified by *typestring.* They must also agree which component (the first one loaded) will **hal\_stream\_create** the stream, and which component (the second one loaded) will **hal\_stream\_attach** to the already-created stream.

The non-realtime part can be **halstreamer** or **halsampler**. In the case of **halstreamer** the key is 0x48535430 plus the channel number.  In the case of **halsampler** the key is 0x48534130 plus the channel number.

### hal\_stream\_create

Create the given stream, initializing the *stream* which is passed by reference.  It is an undiagnosed error if a stream has already been created with the same *key*.

### hal\_stream\_destroy

Destroy the given stream.  It is an undiagnosed error if the stream is still attached by another component. It is an undiagnosed error if the stream was attached with **hal\_stream\_attach** rather than created with **hal\_stream\_create**. It is an undiagnosed error if the call to **hal\_stream\_destroy** is omitted.

### hal\_stream\_attach

Attach the given stream, which was already created by **hal\_stream\_create**. If the typestring is specified, this call fails if it does not match the typestring the stream was created with.  If the typestring argument is NULL, then any typestring is accepted.

### hal\_stream\_detach

Detach the given stream. It is an undiagnosed error if the stream was created with **hal\_stream\_create** rather than attached with **hal\_stream\_attach**. It is an undiagnosed error if the call to **hal\_stream\_detach** is omitted.

### hal\_stream\_element\_count

Returns the number of pins.

### hal\_stream\_element\_type

Returns the type of the given pin number.

### hal\_stream\_readable

Returns true if the stream has at least one sample to read

### hal\_stream\_read

If the stream has one sample to read, stores it in buf.

### hal\_stream\_writable

Returns true if the stream has room for at least one sample to be written.

### hal\_stream\_depth

Returns the number of samples waiting to be read.

### hal\_stream\_maxdepth

Returns the **depth** argument that the stream was created with.

### hal\_stream\_num\_overruns

Returns a number which is incremented each time **hal\_stream\_write** is called without space available.

### hal\_stream\_num\_underruns

Returns a number which is incremented each time **hal\_stream\_read** is called without a sample available.

### hal\_stream\_wait\_readable

Waits until the stream is readable or the stop flag is set.

### hal\_stream\_wait\_writable

Waits until the stream is writable or the stop flag is set.

### hal\_stream\_read

Reads a record from stream.  If successful, it is stored in the given buffer.  Optionally, the sample number can be retrieved. If no sample is available, *num\_underruns* is incremented.  It is an undetected error if more than one component or real-time function calls **hal\_stream\_read** concurrently.

### hal\_stream\_write

Writes a record to the stream.  If successful, it copied from the given buffer.  If no room is available, *num\_overruns* is incremented.  In either case, the internal *sampleno* value is incremented.\
   It is an undetected error if more than one component or real-time function calls **hal\_stream\_write** concurrently.

## ARGUMENTS

- *stream*

  A pointer to a stream object.  In the case of **hal\_stream\_create** and **hal\_stream\_attach** this is an uninitialized stream; in other cases, it must be a stream created or attached by an earlier call and not yet detached or destroyed.

- *hal\_id*

  An HAL component identifier returned by an earlier call to **hal\_init**.

- *key*

  The key for the shared memory segment.

- *depth*

  The number of samples that can be unread before any samples are lost (overrun)

- *typestring*

  A typestring is a case-insensitive string which consists of one or more of the following type characters:

  - B

    for bool / hal\_bit\_t

  - S

    for int32\_t / hal\_s32\_t

  - U

    for uint32\_t / hal\_u32\_t

  - F

    for real\_t / hal\_float\_t

  A typestring is limited to 16 characters.

- *buf*

  A buffer big enough to hold all the data in one sample.

- *sampleno*

  If non-NULL, the last sample number is stored here.  Gaps in this sequence indicate that an overrun occurred between the previous read and this one.  May be NULL, in which case the sample number is not retrieved.

- *stop*

  A pointer to a value which is monitored while waiting.  If it is nonzero, the wait operation returns early.  This allows a wait call to be safely terminated in the case of a signal.

## SAMPLE CODE

In the source tree under *src/hal/components*, **sampler.c** and **streamer.c** are realtime components that read and write HAL streams.

## REALTIME CONSIDERATIONS

**hal\_stream\_read**, **hal\_stream\_readable**, **hal\_stream\_write**, **hal\_stream\_writable**, **hal\_stream\_element\_count**, **hal\_tream\_pin\_type**, **hal\_stream\_depth**, **hal\_stream\_maxdepth**, **hal\_stream\_num\_underruns**, **hal\_stream\_number\_overruns** may be called from realtime code.

**hal\_stream\_wait\_writable**, **hal\_stream\_wait\_writable** may be called from ULAPI code.

Other functions may be called in any context, including realtime contexts.

## RETURN VALUE

**hal\_stream\_create** , **hal\_stream\_attach** , **hal\_stream\_read** , **hal\_stream\_write** , **hal\_stream\_detach** and **hal\_stream\_destroy** return an RTAPI status code.  Other functions' return values are explained above.

## BUGS

The memory overhead of a stream can be large.  Each element in a record uses 8 bytes, and the implicit sample number also uses 8 bytes.  As a result, a stream which is used to transport 8-bit values uses 94% of its memory as overhead. However, for modest stream sizes this overhead is not important.  (this memory is part of its own shared memory region and does not count against the HAL shared memory region used for pins, parameters and signals)

## SEE ALSO

[**sampler**(9)](/sampler/9.md), [**streamer**(9)](/streamer/9.md), [**halsampler**(1)](/halsampler/1.md), [**halstreamer**(1)](/halstreamer/1.md)
