libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
libxr_rw.hpp
1#pragma once
2
3#include <atomic>
4#include <cstdarg>
5#include <cstddef>
6#include <cstdint>
7#include <cstdio>
8#include <utility>
9
10#include "libxr_cb.hpp"
11#include "libxr_def.hpp"
12#include "libxr_type.hpp"
13#include "lockfree_queue.hpp"
14#include "mutex.hpp"
15#include "semaphore.hpp"
16
17namespace LibXR
18{
19
27template <typename Args>
29{
30 public:
32
35 enum class OperationType : uint8_t
36 {
37 CALLBACK,
38 BLOCK,
39 POLLING,
40 NONE
41 };
42
45 enum class OperationPollingStatus : uint8_t
46 {
47 READY,
48 RUNNING,
49 DONE,
50 ERROR
51 };
52
55 Operation() : type(OperationType::NONE) { Memory::FastSet(&data, 0, sizeof(data)); }
56
63 Operation(Semaphore& sem, uint32_t timeout = UINT32_MAX) : type(OperationType::BLOCK)
64 {
65 data.sem_info.sem = &sem;
66 data.sem_info.timeout = timeout;
67 }
68
74 Operation(Callback& callback) : type(OperationType::CALLBACK)
75 {
76 data.callback = &callback;
77 }
78
85 {
86 data.status = &status;
87 }
88
96 {
97 if (this != &op)
98 {
99 type = op.type;
100 switch (type)
101 {
102 case OperationType::CALLBACK:
103 data.callback = op.data.callback;
104 break;
105 case OperationType::BLOCK:
106 data.sem_info.sem = op.data.sem_info.sem;
107 data.sem_info.timeout = op.data.sem_info.timeout;
108 break;
109 case OperationType::POLLING:
110 data.status = op.data.status;
111 break;
112 case OperationType::NONE:
113 break;
114 }
115 }
116 return *this;
117 }
118
126 {
127 if (this != &op)
128 {
129 type = op.type;
130 switch (type)
131 {
132 case OperationType::CALLBACK:
133 data.callback = op.data.callback;
134 break;
135 case OperationType::BLOCK:
136 data.sem_info.sem = op.data.sem_info.sem;
137 data.sem_info.timeout = op.data.sem_info.timeout;
138 break;
139 case OperationType::POLLING:
140 data.status = op.data.status;
141 break;
142 case OperationType::NONE:
143 break;
144 }
145 }
146 return *this;
147 }
148
157 template <
158 typename InitOperation,
159 typename = std::enable_if_t<std::is_same_v<std::decay_t<InitOperation>, Operation>>>
160 Operation(InitOperation&& op)
161 {
162 *this = std::forward<InitOperation>(op);
163 }
164
171 template <typename Status>
172 void UpdateStatus(bool in_isr, Status&& status)
173 {
174 // TODO: 任何操作类型都应拿到执行结果。
175 switch (type)
176 {
177 case OperationType::CALLBACK:
178 data.callback->Run(in_isr, std::forward<Status>(status));
179 break;
180 case OperationType::BLOCK:
181 data.sem_info.sem->PostFromCallback(in_isr);
182 break;
183 case OperationType::POLLING:
184 *data.status = (status == ErrorCode::OK) ? OperationPollingStatus::DONE
185 : OperationPollingStatus::ERROR;
186 break;
187 case OperationType::NONE:
188 break;
189 }
190 }
191
206 {
207 if (type == OperationType::POLLING)
208 {
209 *data.status = OperationPollingStatus::RUNNING;
210 }
211 }
212
215 union
216 {
217 Callback* callback;
218 struct
219 {
220 Semaphore* sem;
221 uint32_t timeout;
222 } sem_info;
224 // TODO: state
226
230};
231
232class ReadPort;
233class WritePort;
234
238
242
245typedef ErrorCode (*WriteFun)(WritePort& port, bool in_isr);
246
249typedef ErrorCode (*ReadFun)(ReadPort& port, bool in_isr);
250
260
266
272{
273 public:
274 enum class BusyState : uint32_t
275 {
276 IDLE = 0,
277 PENDING = 1,
278 EVENT = UINT32_MAX
279 };
280
281 ReadFun read_fun_ = nullptr;
282 LockFreeQueue<uint8_t>* queue_data_ = nullptr;
283 ReadInfoBlock info_;
284 std::atomic<BusyState> busy_{BusyState::IDLE};
285
295 ReadPort(size_t buffer_size = 128);
296
307 size_t EmptySize();
308
319 size_t Size();
320
323 bool Readable();
324
339
351 void Finish(bool in_isr, ErrorCode ans, ReadInfoBlock& info);
352
363 void MarkAsRunning(ReadInfoBlock& info);
364
383 ErrorCode operator()(RawData data, ReadOperation& op, bool in_isr = false);
384
392 virtual void OnRxDequeue(bool) {}
393
401 void ProcessPendingReads(bool in_isr);
402
405 void Reset();
406};
407
413{
414 public:
415 enum class LockState : uint32_t
416 {
417 LOCKED = 0,
418 UNLOCKED = UINT32_MAX
419 };
420
421 WriteFun write_fun_ = nullptr;
423 LockFreeQueue<uint8_t>* queue_data_;
424 std::atomic<LockState> lock_{LockState::UNLOCKED};
425
437 class Stream
438 {
439 public:
447
453 ~Stream();
454
461 Stream& operator<<(const ConstRawData& data);
462
474 ErrorCode Commit();
475
476 private:
479 size_t cap_;
480 size_t size_ = 0;
481 bool locked_ = false;
482 };
483
500 WritePort(size_t queue_size = 3, size_t buffer_size = 128);
501
509 size_t EmptySize();
510
518 size_t Size();
519
527 bool Writable();
528
543
559 void Finish(bool in_isr, ErrorCode ans, WriteInfoBlock& info);
560
572
591 ErrorCode operator()(ConstRawData data, WriteOperation& op, bool in_isr = false);
592
595 void Reset();
596
611 ErrorCode CommitWrite(ConstRawData data, WriteOperation& op, bool pushed = false,
612 bool in_isr = false);
613};
614
619class STDIO
620{
621 public:
622 // NOLINTBEGIN
623 static inline ReadPort* read_ = nullptr;
624 static inline WritePort* write_ = nullptr;
625 static inline LibXR::Mutex* write_mutex_ =
626 nullptr;
627 static inline LibXR::WritePort::Stream* write_stream_ = nullptr;
628#if LIBXR_PRINTF_BUFFER_SIZE > 0
629 static inline char
630 printf_buff_[LIBXR_PRINTF_BUFFER_SIZE];
631#endif
632 // NOLINTEND
633
643 static int Printf(const char* fmt, ...); // NOLINT
644};
645} // namespace LibXR
通用回调包装,支持动态参数传递 / Generic callback wrapper supporting dynamic argument passing
Definition libxr_cb.hpp:150
常量原始数据封装类。 A class for encapsulating constant raw data.
无锁队列实现 / Lock-free queue implementation
static void FastSet(void *dst, uint8_t value, size_t size)
快速内存填充 / Fast memory fill
互斥锁类,提供线程同步机制 (Mutex class providing thread synchronization mechanisms).
Definition mutex.hpp:18
Defines an operation with different execution modes.
Definition libxr_rw.hpp:29
Operation & operator=(const Operation &op)
Copy assignment operator.
Definition libxr_rw.hpp:95
Operation(Semaphore &sem, uint32_t timeout=UINT32_MAX)
Constructs a blocking operation with a semaphore and timeout.
Definition libxr_rw.hpp:63
Operation & operator=(Operation &&op) noexcept
Move assignment operator.
Definition libxr_rw.hpp:125
Operation(Callback &callback)
Constructs a callback-based operation.
Definition libxr_rw.hpp:74
union LibXR::Operation::@5 data
Operation()
Default constructor, initializes with NONE type.
Definition libxr_rw.hpp:55
void UpdateStatus(bool in_isr, Status &&status)
Updates operation status based on type.
Definition libxr_rw.hpp:172
void MarkAsRunning()
标记操作为运行状态。 Marks the operation as running.
Definition libxr_rw.hpp:205
OperationType type
Definition libxr_rw.hpp:229
Operation(OperationPollingStatus &status)
Constructs a polling operation.
Definition libxr_rw.hpp:84
Operation(InitOperation &&op)
构造一个新的 Operation 对象(初始化操作)。 Constructs a new Operation object (initialization operation).
Definition libxr_rw.hpp:160
原始数据封装类。 A class for encapsulating raw data.
ReadPort class for handling read operations.
Definition libxr_rw.hpp:272
bool Readable()
Checks if read operations are supported.
Definition libxr_rw.cpp:30
void Finish(bool in_isr, ErrorCode ans, ReadInfoBlock &info)
更新读取操作的状态。 Updates the status of the read operation.
Definition libxr_rw.cpp:38
ReadPort(size_t buffer_size=128)
Constructs a ReadPort with queue sizes.
Definition libxr_rw.cpp:11
void Reset()
Resets the ReadPort.
Definition libxr_rw.cpp:156
size_t EmptySize()
获取队列的剩余可用空间。 Gets the remaining available space in the queue.
Definition libxr_rw.cpp:18
ErrorCode operator()(RawData data, ReadOperation &op, bool in_isr=false)
读取操作符重载,用于执行读取操作。 Overloaded function call operator to perform a read operation.
Definition libxr_rw.cpp:46
void ProcessPendingReads(bool in_isr)
Processes pending reads.
Definition libxr_rw.cpp:127
ReadPort & operator=(ReadFun fun)
赋值运算符重载,用于设置读取函数。 Overloaded assignment operator to set the read function.
Definition libxr_rw.cpp:32
size_t Size()
获取当前队列的已使用大小。 Gets the currently used size of the queue.
Definition libxr_rw.cpp:24
virtual void OnRxDequeue(bool)
RX 数据从软件队列成功出队后的通知。 Notification after bytes are popped from RX data queue.
Definition libxr_rw.hpp:392
void MarkAsRunning(ReadInfoBlock &info)
标记读取操作为运行中。 Marks the read operation as running.
Definition libxr_rw.cpp:44
STDIO interface for read/write ports.
Definition libxr_rw.hpp:620
static int Printf(const char *fmt,...)
Prints a formatted string to the write port (like printf).
Definition libxr_rw.cpp:380
static LibXR::Mutex * write_mutex_
Write port mutex. 写入端口互斥锁。
Definition libxr_rw.hpp:625
static ReadPort * read_
Read port instance. 读取端口。
Definition libxr_rw.hpp:623
static WritePort * write_
Write port instance. 写入端口。
Definition libxr_rw.hpp:624
信号量类,实现线程同步机制 Semaphore class implementing thread synchronization
Definition semaphore.hpp:23
WritePort 的流式写入操作器,支持链式 << 操作和批量提交。
Definition libxr_rw.hpp:438
bool locked_
是否持有写锁 Whether write lock is held
Definition libxr_rw.hpp:481
size_t size_
当前已写入但未提交的字节数 Bytes written but not yet committed
Definition libxr_rw.hpp:480
ErrorCode Commit()
手动提交已写入的数据到队列,并尝试续锁。
Definition libxr_rw.cpp:353
size_t cap_
当前队列容量 Current queue capacity
Definition libxr_rw.hpp:479
LibXR::WritePort * port_
写端口指针 Pointer to the WritePort
Definition libxr_rw.hpp:477
LibXR::WriteOperation op_
写操作对象 Write operation object
Definition libxr_rw.hpp:478
~Stream()
析构时自动提交已累积的数据并释放锁。
Definition libxr_rw.cpp:305
Stream(LibXR::WritePort *port, LibXR::WriteOperation op)
构造流写入对象,并尝试锁定端口。
Definition libxr_rw.cpp:288
Stream & operator<<(const ConstRawData &data)
追加写入数据,支持链式调用。
Definition libxr_rw.cpp:319
WritePort class for handling write operations.
Definition libxr_rw.hpp:413
size_t EmptySize()
获取数据队列的剩余可用空间。 Gets the remaining available space in the data queue.
Definition libxr_rw.cpp:171
size_t Size()
获取当前数据队列的已使用大小。 Gets the used size of the current data queue.
Definition libxr_rw.cpp:177
void Finish(bool in_isr, ErrorCode ans, WriteInfoBlock &info)
更新写入操作的状态。 Updates the status of the write operation.
Definition libxr_rw.cpp:191
WritePort(size_t queue_size=3, size_t buffer_size=128)
构造一个新的 WritePort 对象。 Constructs a new WritePort object.
Definition libxr_rw.cpp:162
WritePort & operator=(WriteFun fun)
赋值运算符重载,用于设置写入函数。 Overloaded assignment operator to set the write function.
Definition libxr_rw.cpp:185
bool Writable()
判断端口是否可写。 Checks whether the port is writable.
Definition libxr_rw.cpp:183
ErrorCode CommitWrite(ConstRawData data, WriteOperation &op, bool pushed=false, bool in_isr=false)
提交写入操作。 Commits a write operation.
Definition libxr_rw.cpp:225
void MarkAsRunning(WriteOperation &op)
标记写入操作为运行中。 Marks the write operation as running.
Definition libxr_rw.cpp:196
void Reset()
Resets the WritePort.
Definition libxr_rw.cpp:281
ErrorCode operator()(ConstRawData data, WriteOperation &op, bool in_isr=false)
执行写入操作。 Performs a write operation.
Definition libxr_rw.cpp:198
LibXR 命名空间
Definition ch32_can.hpp:14
ErrorCode(* ReadFun)(ReadPort &port, bool in_isr)
Function pointer type for read operations.
Definition libxr_rw.hpp:249
ErrorCode(* WriteFun)(WritePort &port, bool in_isr)
Function pointer type for write operations.
Definition libxr_rw.hpp:245
Operation< ErrorCode > ReadOperation
Read operation type.
Definition libxr_rw.hpp:237
Operation< ErrorCode > WriteOperation
Write operation type.
Definition libxr_rw.hpp:241
Read information block structure.
Definition libxr_rw.hpp:256
RawData data
Data buffer. 数据缓冲区。
Definition libxr_rw.hpp:257
ReadOperation op
Read operation instance. 读取操作实例。
Definition libxr_rw.hpp:258
ConstRawData data
Data buffer. 数据缓冲区。
Definition libxr_rw.hpp:263
WriteOperation op
Write operation instance. 写入操作实例。
Definition libxr_rw.hpp:264