FreeRTOScpp
StreamBufferCPP.h
Go to the documentation of this file.
1 /**
2  * @file StreamBufferCPP.h
3  * @brief FreeRTOS Streambuffer wrapper
4  *
5  * @copyright (c) 2024 Richard Damon
6  * @author Richard Damon <richard.damon@gmail.com>
7  * @parblock
8  * MIT License:
9  *
10  * Permission is hereby granted, free of charge, to any person obtaining a copy
11  * of this software and associated documentation files (the "Software"), to deal
12  * in the Software without restriction, including without limitation the rights
13  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14  * copies of the Software, and to permit persons to whom the Software is
15  * furnished to do so, subject to the following conditions:
16  *
17  * The above copyright notice and this permission notice shall be included in
18  * all copies or substantial portions of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26  * THE SOFTWARE.
27  *
28  * It is requested (but not required by license) that any bugs found or
29  * improvements made be shared, preferably to the author.
30  * @endparblock
31  *
32  * @ingroup FreeRTOSCpp
33  */
34 
35 #ifndef STREAMBUFFER_CPP_H
36 #define STREAMBUFFER_CPP_H
37 
38 #include "FreeRTOScpp.h"
39 
40 #include "stream_buffer.h"
41 
42 #if FREERTOSCPP_USE_NAMESPACE
43 namespace FreeRTOScpp {
44 #endif
45 
46  /**
47  * @brief Base class for the Various Stream Buffers
48  *
49  * This class provides all the generic operations.
50  *
51  * The derived class will create the buffer, or can be created as a wrapper from an existing streambuffer.
52  */
54 public:
55  StreamBufferBase(StreamBufferHandle_t sbHandle) : streamHandle(sbHandle) {}
56  virtual ~StreamBufferBase() { }
57 
58  size_t send(const void* data, size_t len, TickType_t delay = portMAX_DELAY)
59  {return xStreamBufferSend(streamHandle, data, len, delay);}
60 #if FREERTOSCPP_USE_CHRONO
61  size_t send(const void* data, size_t len, Time_ms delay)
62  {return xStreamBufferSend(streamHandle, data, len, ms2ticks(delay));}
63 #endif
64  size_t send_ISR(const void* data, size_t len, BaseType_t &wasWoken)
65  {return xStreamBufferSendFromISR(streamHandle, data, len, &wasWoken);}
66 
67  size_t read(void* data, size_t len, TickType_t delay = portMAX_DELAY)
68  {return xStreamBufferReceive(streamHandle, data, len, delay);}
69 #if FREERTOSCPP_USE_CHRONO
70  size_t read(void* data, size_t len, Time_ms delay)
71  {return xStreamBufferReceive(streamHandle, data, len, ms2ticks(delay));}
72 #endif
73  size_t read_ISR(void* data, size_t len, BaseType_t &wasWoken)
74  {return xStreamBufferReceiveFromISR(streamHandle, data, len, &wasWoken);}
75 
76  /// @brief Get number of bytes of data available in the StreamBuffer
77  /// @return The number of bytes that can be read
78  size_t waiting() const { return xStreamBufferBytesAvailable(streamHandle);}
79 
80  /// @brief Get the amount of available space open in the StreamBuffer
81  /// @return The number of bytes that can be sent before the buffer is full
82  size_t available() const { return xStreamBufferSpacesAvailable(streamHandle);}
83 
84  bool isEmpty() const { return xStreamBufferIsEmpty(streamHandle);}
85 
86  bool isFull() const { return xStreamBufferIsFull(streamHandle);}
87 
88  /// @brief Resets the buffer to empty
89  /// @return True if done, stream can not be reset if a task is waiting on the StreamBuffer.
90  bool reset() { return xStreamBufferReset(streamHandle);}
91 
92  /// @brief Sets the Trigger Level for the StreamBuffer
93  /// @param trigger the Trigger Level
94  /// @return If trigger level was set (false means trigger bigger than the buffer size)
95  bool trigger(size_t trigger) { return xStreamBufferSetTriggerLevel(streamHandle, trigger);}
96 
97  StreamBufferHandle_t streamHandle;
98 };
99 
100 /**
101  * StreamBuffer wrapper
102  *
103  * @tparam size The size of the stream buffer, 0 for dynamically created
104  */
105 template <size_t size
106 #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
107  = 0
108 #endif
109 >
111 public:
112  StreamBuffer(size_t trigger = 1) :
114 #if( configSUPPORT_STATIC_ALLOCATION == 1 )
115  xStreamBufferCreateStatic(size, trigger, storage, streamBuff)
116 #else
117  xStreamBufferCreate(size, trigger)
118 #endif
119  ) {}
120  virtual ~StreamBuffer() { vStreamBufferDelete(streamHandle);}
121 
122 #if configUSE_SB_COMPLETED_CALLBACK
123  StreamBuffer(size_t trigger, StreamBufferCallbackFunction_t sendCallback, StreamBufferCallbackFunction_t recvCallback) :
125 #if( configSUPPORT_STATIC_ALLOCATION == 1 )
126  xStreamBufferCreateStaticWithCallback(size, trigger, storage, streamBuff, sendCallback, recvCallback)
127 #else
128  xStreamBufferCreateWithCallback(size, trigger, sendCallback. recvCallBack)
129 #endif
130  )
131  {}
132 #endif //configUSE_SB_COMPLETED_CALLBACK
133 
134 #if( configSUPPORT_STATIC_ALLOCATION == 1 )
135  uint8_t storage[size+1];
136  StaticStreamBuffer_t streamBuff;
137 #endif
138 };
139 
140 #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
141 
142 /**
143  * Dynamically created StreamBuffer
144  */
145 template <>
146 class StreamBuffer<0> : public StreamBufferBase {
147 public:
148  StreamBuffer(size_t size, size_t trigger=1) :
149  StreamBufferBase(xStreamBufferCreate(size, trigger))
150  {}
151 #if configUSE_SB_COMPLETED_CALLBACK
152  StreamBuffer(size_t size, size_t trigger, StreamBufferCallbackFunction_t sendCallback, StreamBufferCallbackFunction_t recvCallback) :
153  StreamBufferBase(xStreamBufferCreateWithCallback(size, trigger, sendCallback, recvCallback))
154  {}
155 #endif // configUSE_SB_COMPLETED_CALLBACK
156 };
157 #endif
158 
159 #if FREERTOS_VERSION_ALL >= 11'001'000
160 // Version 11.1.0 added StraamBatchBuffer Varient
161 
162 /**
163  * BatchingBuffer variant wrapper
164  *
165  * Batching buffers are like normal streambuffers but don't return partial buffer
166  * until the timeout period has expired even if some data is available.
167  */
168 template <size_t size
169 #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
170  = 0
171 #endif
172 >
173 class BatchingBuffer : public StreamBufferBase {
174 public:
175  BatchingBuffer(size_t trigger = 1) :
177 #if( configSUPPORT_STATIC_ALLOCATION == 1 )
178  xStreamBatchingBufferCreateStatic(size, trigger, storage, streamBuff)
179 #else
180  xStreamBatchingBufferCreate(size, trigger)
181 #endif
182  ) {}
183  virtual ~BatchBuffer() { vStreamBufferDelete(streamHandle);}
184 #if configUSE_SB_COMPLETED_CALLBACK
185  BatchingBuffer(size_t trigger, StreamBufferCallbackFunction_t sendCallback, StreamBufferCallbackFunction_t recvCallback) :
187 #if( configSUPPORT_STATIC_ALLOCATION == 1 )
188  xStreamBatchingBufferCreateStaticWithCallback(size, trigger, storage, streamBuff, sendCallback, recvCallback)
189 #else
190  xStreamBatchingBufferCreateWithCallback(size, trigger, sendCallback. recvCallBack)
191 #endif
192  )
193  {}
194 #endif //configUSE_SB_COMPLETED_CALLBACK
195 
196 #if( configSUPPORT_STATIC_ALLOCATION == 1 )
197  uint8_t storage[size+1];
198  StaticStreamBuffer_t streamBuff;
199 #endif
200 };
201 
202 #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
203 /**
204  * Dynamically Created BatchingBuffer wrapper.
205  */
206 
207 template <>
208 class BatchingBuffer<0> : public StreamBufferBase {
209 public:
210  BatchingBuffer(size_t size, size_t trigger=1) :
211  StreamBufferBase(xStreamBatchingBufferCreate(size, trigger))
212  {}
213  virtual ~BatchingBuffer() { vStreamBufferDelete(streamHandle);}
214 #if configUSE_SB_COMPLETED_CALLBACK
215  BatchingBuffer(size_t size, size_t trigger, StreamBufferCallbackFunction_t sendCallback, StreamBufferCallbackFunction_t recvCallback) :
216  StreamBatchingBufferBase(xStreamBufferCreateWithCallback(size, trigger, sendCallback, recvCallback))
217  {}
218 #endif // configUSE_SB_COMPLETED_CALLBACK
219 };
220 #endif
221 #endif
222 
223 #if FREERTOSCPP_USE_NAMESPACE
224 }
225 #endif
226 
227 #endif
StreamBuffer wrapper.
Definition: StreamBufferCPP.h:110
size_t send_ISR(const void *data, size_t len, BaseType_t &wasWoken)
Definition: StreamBufferCPP.h:64
size_t read(void *data, size_t len, Time_ms delay)
Definition: StreamBufferCPP.h:70
StreamBufferHandle_t streamHandle
Definition: StreamBufferCPP.h:97
size_t waiting() const
Get number of bytes of data available in the StreamBuffer.
Definition: StreamBufferCPP.h:78
size_t available() const
Get the amount of available space open in the StreamBuffer.
Definition: StreamBufferCPP.h:82
constexpr TickType_t ms2ticks(Time_ms ms)
Definition: FreeRTOScpp.h:81
std::chrono::milliseconds Time_ms
Definition: FreeRTOScpp.h:79
virtual ~StreamBufferBase()
Definition: StreamBufferCPP.h:56
Base class for the Various Stream Buffers.
Definition: StreamBufferCPP.h:53
Definition: CallBack.h:63
size_t send(const void *data, size_t len, TickType_t delay=portMAX_DELAY)
Definition: StreamBufferCPP.h:58
FreeRTOS Wrapper.
StreamBufferBase(StreamBufferHandle_t sbHandle)
Definition: StreamBufferCPP.h:55
virtual ~StreamBuffer()
Definition: StreamBufferCPP.h:120
StreamBuffer(size_t trigger=1)
Definition: StreamBufferCPP.h:112
bool trigger(size_t trigger)
Sets the Trigger Level for the StreamBuffer.
Definition: StreamBufferCPP.h:95
bool isFull() const
Definition: StreamBufferCPP.h:86
bool isEmpty() const
Definition: StreamBufferCPP.h:84
size_t read_ISR(void *data, size_t len, BaseType_t &wasWoken)
Definition: StreamBufferCPP.h:73
size_t send(const void *data, size_t len, Time_ms delay)
Definition: StreamBufferCPP.h:61
size_t read(void *data, size_t len, TickType_t delay=portMAX_DELAY)
Definition: StreamBufferCPP.h:67
bool reset()
Resets the buffer to empty.
Definition: StreamBufferCPP.h:90