tetl 0.1.0
Embedded Template Library
Loading...
Searching...
No Matches
stream_buffer.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSL-1.0
2// SPDX-FileCopyrightText: Copyright (C) 2021 Tobias Hienzsch
3
4#ifndef TETL_FREERTOS_STREAM_BUFFER_HPP
5#define TETL_FREERTOS_STREAM_BUFFER_HPP
6
7#include <etl/version.hpp>
8
9#include <etl/cstddef.hpp>
10#include <etl/cstdint.hpp>
11#include <etl/span.hpp>
12#include <etl/utility.hpp>
13
14#if defined(TETL_FREERTOS_USE_STUBS)
15 #include <etl/experimental/freertos/stubs.hpp>
16#endif
17
18namespace etl::experimental::freertos {
19
20/// \brief Stream buffers are an RTOS task to RTOS task, and interrupt to task
21/// communication primitives.
22///
23/// Unlike most other FreeRTOS communications primitives, they are optimised
24/// for single reader single writer scenarios, such as passing data from an
25/// interrupt service routine to a task, or from one microcontroller core to
26/// another on dual core CPUs. Data is passed by copy - the data is copied into
27/// the buffer by the sender and out of the buffer by the read.
28///
29/// https://www.freertos.org/RTOS-stream-buffer-API.html
30/// https://www.freertos.org/RTOS-stream-message-buffers.html
32 using size_type = etl::size_t;
33
34 /// \brief Creates a new stream buffer using dynamically allocated memory.
35 ///
36 /// https://www.freertos.org/xStreamBufferCreate.html
37 stream_buffer(size_type size, size_type triggerLevel) noexcept;
38
39 /// \brief Deletes a stream buffer, then the allocated memory is freed.
40 ///
41 /// https://www.freertos.org/vStreamBufferDelete.html
42 ~stream_buffer() noexcept;
43
44 stream_buffer(stream_buffer const& other) = delete;
45 auto operator=(stream_buffer const& other) -> stream_buffer& = delete;
46
47 stream_buffer(stream_buffer&& other) = delete;
48 auto operator=(stream_buffer&& other) -> stream_buffer& = delete;
49
50 /// \brief Sends bytes to a stream buffer. The bytes are copied into the
51 /// stream buffer.
52 ///
53 /// https://www.freertos.org/xStreamBufferSend.html
54 auto write(etl::span<etl::byte const> data, TickType_t ticks) -> size_type;
55
56 /// \brief Interrupt safe version of the API function that sends a stream of
57 /// bytes to the stream buffer.
58 ///
59 /// https://www.freertos.org/xStreamBufferSendFromISR.html
60 auto write_from_isr(etl::span<etl::byte const> data, BaseType_t* prio) -> size_type;
61
62 /// \brief Receives bytes from a stream buffer.
63 ///
64 /// https://www.freertos.org/xStreamBufferReceive.html
65 auto read(etl::span<etl::byte> data, TickType_t ticks) -> size_type;
66
67 /// \brief Receives bytes from a stream buffer.
68 ///
69 /// https://www.freertos.org/xStreamBufferReceiveFromISR.html
70 auto read_from_isr(etl::span<etl::byte> data, BaseType_t* prio) -> size_type;
71
72 /// \brief Queries a stream buffer to see if it is empty. A stream buffer is
73 /// empty if it does not contain any data.
74 ///
75 /// https://www.freertos.org/xStreamBufferIsEmpty.html
76 [[nodiscard]] auto empty() const noexcept -> bool;
77
78 /// \brief Queries a stream buffer to see if it is full. A stream buffer is
79 /// full if it does not have any free space, and therefore cannot accept any
80 /// more data.
81 ///
82 /// https://www.freertos.org/xStreamBufferIsFull.html
83 [[nodiscard]] auto full() const noexcept -> bool;
84
85 /// \brief Queries a stream buffer to see how much data it contains, which
86 /// is equal to the number of bytes that can be read from the stream buffer
87 /// before the stream buffer would be empty.
88 ///
89 /// https://www.freertos.org/xStreamBufferBytesAvailable.html
90 [[nodiscard]] auto bytes_available() const noexcept -> size_type;
91
92 /// \brief Queries a stream buffer to see how much free space it contains,
93 /// which is equal to the amount of data that can be sent to the stream
94 /// buffer before it is full.
95 ///
96 /// https://www.freertos.org/xStreamBufferSpacesAvailable.html
97 [[nodiscard]] auto space_available() const noexcept -> size_type;
98
99 /// \brief Resets a stream buffer to its initial, empty, state. Any data
100 /// that was in the stream buffer is discarded. A stream buffer can only be
101 /// reset if there are no tasks blocked waiting to either send to or receive
102 /// from the stream buffer.
103 ///
104 /// https://www.freertos.org/xStreamBufferReset.html
105 auto reset() noexcept -> void;
106
107 /// \brief A stream buffer's trigger level is the number of bytes that must
108 /// be in the stream buffer before a task that is blocked on the stream
109 /// buffer to wait for data is moved out of the blocked state.
110 ///
111 /// \details For example, if a task is blocked on a read of an empty stream
112 /// buffer that has a trigger level of 1 then the task will be unblocked
113 /// when a single byte is written to the buffer or the task's block time
114 /// expires. As another example, if a task is blocked on a read of an empty
115 /// stream buffer that has a trigger level of 10 then the task will not be
116 /// unblocked until the stream buffer contains at least 10 bytes or the
117 /// task's block time expires. If a reading task's block time expires before
118 /// the trigger level is reached then the task will still receive however
119 /// many bytes are actually available. Setting a trigger level of 0 will
120 /// result in a trigger level of 1 being used. It is not valid to specify a
121 /// trigger level that is greater than the buffer size.
122 ///
123 /// https://www.freertos.org/xStreamBufferSetTriggerLevel.html
124 auto trigger_level(size_type triggerLevel) noexcept -> void;
125
126 /// \brief Returns the native FreeRTOS handle to the stream_buffer
127 [[nodiscard]] auto native_handle() const noexcept -> StreamBufferHandle_t;
128
129private:
130 StreamBufferHandle_t _handle;
131};
132
133inline stream_buffer::stream_buffer(size_t size, size_t triggerLevel) noexcept
134 : _handle{xStreamBufferCreate(size, triggerLevel)}
135{
136}
137
138inline stream_buffer::~stream_buffer() noexcept
139{
141}
142
143inline auto stream_buffer::write(etl::span<etl::byte const> data, TickType_t ticks) -> size_t
144{
145 return xStreamBufferSend(_handle, data.data(), data.size(), ticks);
146}
147
148inline auto stream_buffer::write_from_isr(etl::span<etl::byte const> data, BaseType_t* prio) -> size_t
149{
150 return xStreamBufferSendFromISR(_handle, data.data(), data.size(), prio);
151}
152
153inline auto stream_buffer::read(etl::span<etl::byte> data, TickType_t ticks) -> size_t
154{
155 return xStreamBufferReceive(_handle, data.data(), data.size(), ticks);
156}
157
158inline auto stream_buffer::read_from_isr(etl::span<etl::byte> data, BaseType_t* prio) -> size_t
159{
160 return xStreamBufferReceiveFromISR(_handle, data.data(), data.size(), prio);
161}
162
163inline auto stream_buffer::empty() const noexcept -> bool
164{
165 return static_cast<bool>(xStreamBufferIsEmpty(_handle));
166}
167
168inline auto stream_buffer::full() const noexcept -> bool
169{
170 return static_cast<bool>(xStreamBufferIsFull(_handle));
171}
172
173inline auto stream_buffer::bytes_available() const noexcept -> size_type
174{
175 return xStreamBufferBytesAvailable(_handle);
176}
177
178inline auto stream_buffer::space_available() const noexcept -> size_type
179{
180 return xStreamBufferSpacesAvailable(_handle);
181}
182
183inline auto stream_buffer::reset() noexcept -> void
184{
186}
187
188inline auto stream_buffer::trigger_level(size_type triggerLevel) noexcept -> void
189{
190 xStreamBufferSetTriggerLevel(_handle, triggerLevel);
191}
192
193inline auto stream_buffer::native_handle() const noexcept -> StreamBufferHandle_t
194{
195 return _handle;
196}
197
198} // namespace etl::experimental::freertos
199
200#endif // TETL_FREERTOS_STREAM_BUFFER_HPP
Definition queue.hpp:16
Definition adjacent_find.hpp:9
enum TETL_MAY_ALIAS byte
etl::byte is a distinct type that implements the concept of byte as specified in the C++ language def...
Definition byte.hpp:22
Stream buffers are an RTOS task to RTOS task, and interrupt to task communication primitives.
Definition stream_buffer.hpp:31
auto empty() const noexcept -> bool
Queries a stream buffer to see if it is empty. A stream buffer is empty if it does not contain any da...
Definition stream_buffer.hpp:163
auto space_available() const noexcept -> size_type
Queries a stream buffer to see how much free space it contains, which is equal to the amount of data ...
Definition stream_buffer.hpp:178
auto native_handle() const noexcept -> StreamBufferHandle_t
Returns the native FreeRTOS handle to the stream_buffer.
Definition stream_buffer.hpp:193
stream_buffer(stream_buffer &&other)=delete
auto trigger_level(size_type triggerLevel) noexcept -> void
A stream buffer's trigger level is the number of bytes that must be in the stream buffer before a tas...
Definition stream_buffer.hpp:188
auto bytes_available() const noexcept -> size_type
Queries a stream buffer to see how much data it contains, which is equal to the number of bytes that ...
Definition stream_buffer.hpp:173
~stream_buffer() noexcept
Deletes a stream buffer, then the allocated memory is freed.
Definition stream_buffer.hpp:138
auto write(etl::span< etl::byte const > data, TickType_t ticks) -> size_type
Sends bytes to a stream buffer. The bytes are copied into the stream buffer.
Definition stream_buffer.hpp:143
auto read_from_isr(etl::span< etl::byte > data, BaseType_t *prio) -> size_type
Receives bytes from a stream buffer.
Definition stream_buffer.hpp:158
auto operator=(stream_buffer const &other) -> stream_buffer &=delete
auto write_from_isr(etl::span< etl::byte const > data, BaseType_t *prio) -> size_type
Interrupt safe version of the API function that sends a stream of bytes to the stream buffer.
Definition stream_buffer.hpp:148
stream_buffer(size_type size, size_type triggerLevel) noexcept
Creates a new stream buffer using dynamically allocated memory.
Definition stream_buffer.hpp:133
auto reset() noexcept -> void
Resets a stream buffer to its initial, empty, state. Any data that was in the stream buffer is discar...
Definition stream_buffer.hpp:183
stream_buffer(stream_buffer const &other)=delete
auto full() const noexcept -> bool
Queries a stream buffer to see if it is full. A stream buffer is full if it does not have any free sp...
Definition stream_buffer.hpp:168
auto read(etl::span< etl::byte > data, TickType_t ticks) -> size_type
Receives bytes from a stream buffer.
Definition stream_buffer.hpp:153
auto operator=(stream_buffer &&other) -> stream_buffer &=delete
constexpr auto data() const noexcept -> pointer
Returns a pointer to the beginning of the sequence.
Definition span.hpp:225
constexpr auto size() const noexcept -> size_type
Returns the number of elements in the span.
Definition span.hpp:231
auto xStreamBufferSend(StreamBufferHandle_t handle, void const *data, etl::size_t size, TickType_t ticksToWait) -> etl::size_t
Definition stubs.hpp:119
auto xStreamBufferReceive(StreamBufferHandle_t handle, void *data, etl::size_t size, TickType_t ticks) -> etl::size_t
Definition stubs.hpp:135
auto xStreamBufferSpacesAvailable(StreamBufferHandle_t handle) -> etl::size_t
Definition stubs.hpp:159
auto xStreamBufferIsEmpty(StreamBufferHandle_t handle) -> BaseType_t
Definition stubs.hpp:177
auto xStreamBufferReset(StreamBufferHandle_t handle) -> BaseType_t
Definition stubs.hpp:171
auto xStreamBufferIsFull(StreamBufferHandle_t handle) -> BaseType_t
Definition stubs.hpp:183
auto xStreamBufferCreate(etl::size_t bufferSizeBytes, etl::size_t triggerLevelBytes) -> StreamBufferHandle_t
Definition stubs.hpp:111
auto xStreamBufferBytesAvailable(StreamBufferHandle_t handle) -> etl::size_t
Definition stubs.hpp:153
auto xStreamBufferReceiveFromISR(StreamBufferHandle_t handle, void *data, etl::size_t size, BaseType_t *prio) -> etl::size_t
Definition stubs.hpp:142
auto vStreamBufferDelete(StreamBufferHandle_t handle) -> void
Definition stubs.hpp:148
auto xStreamBufferSendFromISR(StreamBufferHandle_t handle, void const *data, etl::size_t size, BaseType_t *prio) -> etl::size_t
Definition stubs.hpp:127
auto xStreamBufferSetTriggerLevel(StreamBufferHandle_t handle, etl::size_t triggerLevel) -> BaseType_t
Definition stubs.hpp:165