Loading...
Searching...
No Matches
pipe.h File Reference

Pipe convenience module. More...

#include <furi.h>
#include <stddef.h>

Go to the source code of this file.

Data Structures

struct  PipeSideBundle
 
struct  PipeSideReceiveSettings
 

Typedefs

typedef struct PipeSide PipeSide
 
typedef void(* PipeSideDataArrivedCallback) (PipeSide *pipe, void *context)
 Callback for when data arrives to a PipeSide.
 
typedef void(* PipeSideSpaceFreedCallback) (PipeSide *pipe, void *context)
 Callback for when data is read out of the opposite PipeSide.
 
typedef void(* PipeSideBrokenCallback) (PipeSide *pipe, void *context)
 Callback for when the opposite PipeSide is freed, making the pipe broken.
 

Enumerations

enum  PipeRole { PipeRoleAlice , PipeRoleBob }
 The role of a pipe side. More...
 
enum  PipeState { PipeStateOpen , PipeStateBroken }
 The state of a pipe. More...
 

Functions

PipeSideBundle pipe_alloc (size_t capacity, size_t trigger_level)
 Allocates two connected sides of one pipe.
 
PipeSideBundle pipe_alloc_ex (PipeSideReceiveSettings alice, PipeSideReceiveSettings bob)
 Allocates two connected sides of one pipe.
 
PipeRole pipe_role (PipeSide *pipe)
 Gets the role of a pipe side.
 
PipeState pipe_state (PipeSide *pipe)
 Gets the state of a pipe.
 
void pipe_free (PipeSide *pipe)
 Frees a side of a pipe.
 
void pipe_install_as_stdio (PipeSide *pipe)
 Connects the pipe to the stdin and stdout of the current thread.
 
size_t pipe_receive (PipeSide *pipe, void *data, size_t length, FuriWait timeout)
 Receives data from the pipe.
 
size_t pipe_send (PipeSide *pipe, const void *data, size_t length, FuriWait timeout)
 Sends data into the pipe.
 
size_t pipe_bytes_available (PipeSide *pipe)
 Determines how many bytes there are in the pipe available to be read.
 
size_t pipe_spaces_available (PipeSide *pipe)
 Determines how many space there is in the pipe for data to be written into.
 
void pipe_attach_to_event_loop (PipeSide *pipe, FuriEventLoop *event_loop)
 Attaches a PipeSide to a FuriEventLoop, allowing to attach callbacks to the PipeSide.
 
void pipe_detach_from_event_loop (PipeSide *pipe)
 Detaches a PipeSide from the FuriEventLoop that it was previously attached to.
 
void pipe_set_callback_context (PipeSide *pipe, void *context)
 Sets the custom context for all callbacks.
 
void pipe_set_data_arrived_callback (PipeSide *pipe, PipeSideDataArrivedCallback callback, FuriEventLoopEvent event)
 Sets the callback for when data arrives.
 
void pipe_set_space_freed_callback (PipeSide *pipe, PipeSideSpaceFreedCallback callback, FuriEventLoopEvent event)
 Sets the callback for when data is read out of the opposite PipeSide.
 
void pipe_set_broken_callback (PipeSide *pipe, PipeSideBrokenCallback callback, FuriEventLoopEvent event)
 Sets the callback for when the opposite PipeSide is freed, making the pipe broken.
 

Detailed Description

Pipe convenience module.

Pipes are used to send bytes between two threads in both directions. The two threads are referred to as Alice and Bob and their abilities regarding what they can do with the pipe are equal.

It is also possible to use both sides of the pipe within one thread.

Typedef Documentation

◆ PipeSideBrokenCallback

typedef void(* PipeSideBrokenCallback) (PipeSide *pipe, void *context)

Callback for when the opposite PipeSide is freed, making the pipe broken.

Parameters
[in]pipePipe side that called the callback
[in,out]contextCustom context

◆ PipeSideDataArrivedCallback

typedef void(* PipeSideDataArrivedCallback) (PipeSide *pipe, void *context)

Callback for when data arrives to a PipeSide.

Parameters
[in]pipePipe side that called the callback
[in,out]contextCustom context

◆ PipeSideSpaceFreedCallback

typedef void(* PipeSideSpaceFreedCallback) (PipeSide *pipe, void *context)

Callback for when data is read out of the opposite PipeSide.

Parameters
[in]pipePipe side that called the callback
[in,out]contextCustom context

Enumeration Type Documentation

◆ PipeRole

enum PipeRole

The role of a pipe side.

Both roles are equal, as they can both read and write the data. This status might be helpful in determining the role of a thread w.r.t. another thread in an application that builds on the pipe.

◆ PipeState

enum PipeState

The state of a pipe.

  • PipeStateOpen: Both pipe sides are in place, meaning data that is sent down the pipe might be read by the peer, and new data sent by the peer might arrive.
  • PipeStateBroken: The other side of the pipe has been freed, meaning data that is written will never reach its destination, and no new data will appear in the buffer.

A broken pipe can never become open again, because there's no way to connect a side of a pipe to another side of a pipe.

Function Documentation

◆ pipe_alloc()

PipeSideBundle pipe_alloc ( size_t capacity,
size_t trigger_level )

Allocates two connected sides of one pipe.

Creating a pair of sides using this function is the only way to connect two pipe sides together. Two unrelated orphaned sides may never be connected back together.

The capacity and trigger level for both directions are the same when the pipe is created using this function. Use pipe_alloc_ex if you want more control.

Parameters
capacityMaximum number of bytes buffered in one direction
trigger_levelNumber of bytes that need to be available in the buffer in order for a blocked thread to unblock
Returns
Bundle with both sides of the pipe

◆ pipe_alloc_ex()

Allocates two connected sides of one pipe.

Creating a pair of sides using this function is the only way to connect two pipe sides together. Two unrelated orphaned sides may never be connected back together.

The capacity and trigger level may be different for the two directions when the pipe is created using this function. Use pipe_alloc if you don't need control this fine.

Parameters
alicecapacity and trigger_level settings for Alice's receiving buffer
bobcapacity and trigger_level settings for Bob's receiving buffer
Returns
Bundle with both sides of the pipe

◆ pipe_attach_to_event_loop()

void pipe_attach_to_event_loop ( PipeSide * pipe,
FuriEventLoop * event_loop )

Attaches a PipeSide to a FuriEventLoop, allowing to attach callbacks to the PipeSide.

Parameters
[in]pipePipe side to attach to the event loop
[in]event_loopEvent loop to attach the pipe side to

◆ pipe_bytes_available()

size_t pipe_bytes_available ( PipeSide * pipe)

Determines how many bytes there are in the pipe available to be read.

Parameters
[in]pipePipe side to query
Returns
Number of bytes available to be read out from that side of the pipe

◆ pipe_detach_from_event_loop()

void pipe_detach_from_event_loop ( PipeSide * pipe)

Detaches a PipeSide from the FuriEventLoop that it was previously attached to.

Parameters
[in]pipePipe side to detach to the event loop

◆ pipe_free()

void pipe_free ( PipeSide * pipe)

Frees a side of a pipe.

When only one of the sides is freed, the pipe is transitioned from the "Open" state into the "Broken" state. When both sides are freed, the underlying data structures are freed too.

Parameters
[in]pipePipe side to free

◆ pipe_install_as_stdio()

void pipe_install_as_stdio ( PipeSide * pipe)

Connects the pipe to the stdin and stdout of the current thread.

After performing this operation, you can use getc, puts, etc. to send and receive data to and from the pipe. If the pipe becomes broken, C stdlib calls will return EOF wherever possible.

You can disconnect the pipe by manually calling furi_thread_set_stdout_callback and furi_thread_set_stdin_callback with NULL.

Parameters
[in]pipePipe side to connect to the stdio

◆ pipe_receive()

size_t pipe_receive ( PipeSide * pipe,
void * data,
size_t length,
FuriWait timeout )

Receives data from the pipe.

Parameters
[in]pipeThe pipe side to read data out of
[out]dataThe buffer to fill with data
lengthMaximum length of data to read
timeoutThe timeout (in ticks) after which the read operation is interrupted
Returns
The number of bytes actually written into the provided buffer

◆ pipe_role()

PipeRole pipe_role ( PipeSide * pipe)

Gets the role of a pipe side.

The roles (Alice and Bob) are equal, as both can send and receive data. This status might be helpful in determining the role of a thread w.r.t. another thread.

Parameters
[in]pipePipe side to query
Returns
Role of provided pipe side

◆ pipe_send()

size_t pipe_send ( PipeSide * pipe,
const void * data,
size_t length,
FuriWait timeout )

Sends data into the pipe.

Parameters
[in]pipeThe pipe side to send data into
[out]dataThe buffer to get data from
lengthMaximum length of data to send
timeoutThe timeout (in ticks) after which the write operation is interrupted
Returns
The number of bytes actually read from the provided buffer

◆ pipe_set_broken_callback()

void pipe_set_broken_callback ( PipeSide * pipe,
PipeSideBrokenCallback callback,
FuriEventLoopEvent event )

Sets the callback for when the opposite PipeSide is freed, making the pipe broken.

Parameters
[in]pipePipe side to assign the callback to
[in]callbackCallback to assign to the pipe side. Set to NULL to unsubscribe.
[in]eventAdditional event loop flags (e.g. Edge, Once, etc.). Non-flag values of the enum are not allowed.
Warning
Attach the pipe side to an event loop first using pipe_attach_to_event_loop.

◆ pipe_set_callback_context()

void pipe_set_callback_context ( PipeSide * pipe,
void * context )

Sets the custom context for all callbacks.

Parameters
[in]pipePipe side to set the context of
[in,out]contextCustom context that will be passed to callbacks

◆ pipe_set_data_arrived_callback()

void pipe_set_data_arrived_callback ( PipeSide * pipe,
PipeSideDataArrivedCallback callback,
FuriEventLoopEvent event )

Sets the callback for when data arrives.

Parameters
[in]pipePipe side to assign the callback to
[in]callbackCallback to assign to the pipe side. Set to NULL to unsubscribe.
[in]eventAdditional event loop flags (e.g. Edge, Once, etc.). Non-flag values of the enum are not allowed.
Warning
Attach the pipe side to an event loop first using pipe_attach_to_event_loop.

◆ pipe_set_space_freed_callback()

void pipe_set_space_freed_callback ( PipeSide * pipe,
PipeSideSpaceFreedCallback callback,
FuriEventLoopEvent event )

Sets the callback for when data is read out of the opposite PipeSide.

Parameters
[in]pipePipe side to assign the callback to
[in]callbackCallback to assign to the pipe side. Set to NULL to unsubscribe.
[in]eventAdditional event loop flags (e.g. Edge, Once, etc.). Non-flag values of the enum are not allowed.
Warning
Attach the pipe side to an event loop first using pipe_attach_to_event_loop.

◆ pipe_spaces_available()

size_t pipe_spaces_available ( PipeSide * pipe)

Determines how many space there is in the pipe for data to be written into.

Parameters
[in]pipePipe side to query
Returns
Number of bytes available to be written into that side of the pipe

◆ pipe_state()

PipeState pipe_state ( PipeSide * pipe)

Gets the state of a pipe.

When the state is PipeStateOpen, both sides are active and may send or receive data. When the state is PipeStateBroken, only one side is active (the one that this method has been called on). If you find yourself in that state, the data that you send will never be heard by anyone, and the data you receive are leftovers in the buffer.

Parameters
[in]pipePipe side to query
Returns
State of the pipe