6#include "libxr_def.hpp"
65 const std::size_t REMAINING =
Remaining();
72 const std::size_t TAKE = (REMAINING < cap) ? REMAINING : cap;
116 *completed_info = popped;
140 const std::size_t REMAINING =
Remaining();
160 *dropped_info = popped;
269 using LibXR::UART::Read;
271 using LibXR::UART::Write;
286 size_t rx_buffer_size = 128,
size_t tx_buffer_size = 128,
size_t tx_queue_size = 5,
290 const char* control_interface_string = CDCBase::DEFAULT_CONTROL_INTERFACE_STRING,
291 const char* data_interface_string = CDCBase::DEFAULT_DATA_INTERFACE_STRING)
292 :
CDCBase(data_in_ep_num, data_out_ep_num, comm_ep_num, control_interface_string,
293 data_interface_string),
312 auto& line_coding = GetLineCoding();
317 line_coding.bCharFormat = 0;
320 line_coding.bCharFormat = 2;
329 line_coding.bParityType = 0;
332 line_coding.bParityType = 1;
335 line_coding.bParityType = 2;
348 line_coding.bDataBits =
static_cast<uint8_t
>(cfg.
data_bits);
354 line_coding.dwDTERate = cfg.
baudrate;
370 auto ep_data_out = GetDataOutEndpoint();
371 if (ep_data_out ==
nullptr)
376 const std::size_t MPS = ep_data_out->MaxPacketSize();
409 auto ans = ep_data_out->Transfer(MPS);
468 if (cdc->in_write_isr_.IsSet())
473 auto ep = cdc->GetDataInEndpoint();
476 auto drop_ans = cdc->tx_deq_.DropHead(
nullptr);
486 auto drop_ans = cdc->tx_deq_.DropHead(
nullptr);
501 if (ep->GetActiveLength() != 0)
511 if (cdc->tx_deq_.HasOp())
513 cdc->need_write_zlp_ =
false;
524 auto buffer = ep->GetBuffer();
528 cdc->tx_deq_.Take(
reinterpret_cast<uint8_t*
>(buffer.addr_), buffer.size_, len);
538 ep->SetActiveLength(len);
541 std::atomic_signal_fence(std::memory_order_seq_cst);
547 const std::size_t TO_SEND = ep->GetActiveLength();
559 !cdc->tx_deq_.HasOp())
564 std::atomic_signal_fence(std::memory_order_seq_cst);
567 ep->SetActiveLength(0);
568 auto ans = ep->Transfer(TO_SEND);
577 if (slot_ec ==
ErrorCode::OK && cdc->tx_deq_.HeadCompleted())
579 auto pop_ok = cdc->tx_deq_.PopCompleted(
nullptr);
584 const std::size_t MPS = ep->MaxPacketSize();
585 if (MPS > 0 && (TO_SEND % MPS) == 0 && ep->GetActiveLength() == 0 &&
586 !cdc->tx_deq_.HasOp())
588 cdc->need_write_zlp_ =
true;
596 if (!cdc->tx_deq_.HasOp())
601 auto buffer = ep->GetBuffer();
602 std::size_t len2 = 0;
605 cdc->tx_deq_.Take(
reinterpret_cast<uint8_t*
>(buffer.addr_), buffer.size_, len2);
615 ep->SetActiveLength(len2);
635 reinterpret_cast<const uint8_t*
>(data.
addr_), data.
size_);
664 auto ep = GetDataInEndpoint();
683 auto z = ep->TransferZLP();
693 const std::size_t PENDING_LEN = ep->GetActiveLength();
694 if (PENDING_LEN == 0)
701 ep->SetActiveLength(0);
702 auto ans = ep->Transfer(PENDING_LEN);
720 auto buffer = ep->GetBuffer();
721 std::size_t len2 = 0;
724 tx_deq_.
Take(
reinterpret_cast<uint8_t*
>(buffer.addr_), buffer.size_, len2);
727 ep->SetActiveLength(len2);
733 const std::size_t MPS = ep->MaxPacketSize();
734 if (!primed && PENDING_LEN > 0 && MPS > 0 && (PENDING_LEN % MPS) == 0 &&
WritePort(info 队列 + data 队列)的“单 op 不跨界”出队辅助器 Dequeue helper for WritePort (info + data) without cross...
WritePort & port_
写端口引用 / Write port reference
bool HeadCompleted() const
head op 是否已全部出队 Whether the cached head op is fully dequeued
CDCUartTxOpDequeueHelper(WritePort &port)
构造函数 Constructor
bool head_valid_
head 缓存有效标志 / Cached head valid flag
void Reset()
重置内部状态(head 缓存与偏移) Reset internal state (cached head and offset)
ErrorCode EnsureHead()
确保 head 缓存可用(必要时 Peek info) Ensure cached head is valid (Peek info if needed)
ErrorCode DropHead(WriteInfoBlock *dropped_info=nullptr)
丢弃当前 head op 的剩余数据并 pop info Drop the current head op's remaining bytes and pop its info.
WriteInfoBlock head_
缓存的 head info / Cached head info
ErrorCode PopCompleted(WriteInfoBlock *completed_info=nullptr)
在 head 完成后 pop info 并重置状态 Pop info after head completes and reset state
bool HasOp()
是否存在可处理的 op Whether any op exists
std::size_t offset_
当前 op 已出队偏移 / Dequeued offset within current op
std::size_t Remaining() const
当前 op 剩余未出队字节数 Remaining bytes of current op
ErrorCode Take(uint8_t *dst, std::size_t cap, std::size_t &out_len)
从 data 队列搬运数据到目标 buffer,并推进 offset(不 pop info) Dequeue bytes from data queue into destination buffer ...
只读原始数据视图 / Immutable raw data view
size_t size_
数据字节数 / Data size in bytes
const void * addr_
数据起始地址 / Data start address
普通标志位(非原子)/ Non-atomic flag
作用域标志管理器:构造时写入指定值,析构时恢复原值 / Scoped flag restorer: set on entry, restore on exit
ErrorCode PushBatch(const Data *data, size_t size)
批量推入数据 / Pushes multiple elements into the queue
size_t EmptySize()
计算队列剩余可用空间 / Calculates the remaining available space in the queue
ErrorCode PopBatch(Data *data, size_t size)
批量弹出数据 / Pops multiple elements from the queue
ReadPort class for handling read operations.
LockFreeQueue< uint8_t > * queue_data_
RX payload queue. 接收数据字节队列。
void ProcessPendingReads(bool in_isr)
Processes pending reads.
ReadPort & operator=(ReadFun fun)
赋值运算符重载,用于设置读取函数。 Overloaded assignment operator to set the read function.
void FailAndClearAll(ErrorCode reason, bool in_isr)
失败完成并清空当前所有挂起读操作。
通用异步收发传输(UART)基类 / Abstract base class for Universal Asynchronous Receiver-Transmitter (UART)
ReadPort * read_port_
读取端口 / Read port
@ NO_PARITY
无校验 / No parity
WritePort * write_port_
写入端口 / Write port
USB CDC ACM (Abstract Control Model) 设备类实现 USB CDC ACM (Abstract Control Model) device class implemen...
ErrorCode SendSerialState()
发送串行状态通知 Send serial state notification
virtual void UnbindEndpoints(EndpointPool &endpoint_pool, bool) override
反初始化CDC设备 Deinitialize CDC device
USB CDC-ACM UART 适配器 USB CDC-ACM UART adapter.
CDCUartReadPort read_port_cdc_
CDC RX 读端口 / CDC RX read port.
CDCUart(size_t rx_buffer_size=128, size_t tx_buffer_size=128, size_t tx_queue_size=5, Endpoint::EPNumber data_in_ep_num=Endpoint::EPNumber::EP_AUTO, Endpoint::EPNumber data_out_ep_num=Endpoint::EPNumber::EP_AUTO, Endpoint::EPNumber comm_ep_num=Endpoint::EPNumber::EP_AUTO, const char *control_interface_string=CDCBase::DEFAULT_CONTROL_INTERFACE_STRING, const char *data_interface_string=CDCBase::DEFAULT_DATA_INTERFACE_STRING)
构造函数 Constructor
bool TryRearmOut(bool in_isr)
尝试 rearm OUT(背压恢复/持续接收) Try to rearm OUT endpoint (backpressure recovery / continuous RX)
void UnbindEndpoints(EndpointPool &endpoint_pool, bool in_isr) override
解绑端点(清理队列、状态与背压标志) Unbind endpoints (cleanup queues, states, and backpressure flags)
static ErrorCode WriteFun(WritePort &port, bool in_isr)
写端口回调(TX) Write port callback (TX)
void OnDataInComplete(bool in_isr, ConstRawData &data) override
IN 完成回调(TX) IN complete callback (TX)
LibXR::CDCUartTxOpDequeueHelper tx_deq_
TX 出队辅助器 / TX dequeue helper.
void OnDataOutComplete(bool in_isr, ConstRawData &data) override
OUT 完成回调(RX) OUT complete callback (RX)
bool need_write_zlp_
ZLP 需求标志 / ZLP required flag.
LibXR::WritePort write_port_cdc_
CDC TX 写端口 / CDC TX write port.
ErrorCode SetConfig(UART::Configuration cfg) override
设置 UART 配置(CDC Line Coding) Set UART configuration (CDC Line Coding)
Flag::Plain in_write_isr_
写 ISR 保护标志 / Write ISR guard flag
CDC UART 读端口(背压 + pending 缓存) CDC UART read port (backpressure + pending cache)
CDCUartReadPort(uint32_t size, CDCUart &owner)
构造函数 Constructor
ConstRawData pending_data_
pending 数据(指向底层 USB buffer)/ Pending data pointing to USB buffer
CDCUart & owner_
所属 CDCUart / Owning CDCUart
bool recv_pause_
背压标志:true 表示 OUT 未 rearm / Backpressure flag: OUT not rearmed
void OnRxDequeue(bool in_isr) override
数据队列被消费时回调(解除背压并尝试恢复 OUT rearm) Called when RX queue is dequeued (lift backpressure and try to rearm ...
EPNumber
端点号 Endpoint number
@ EP_AUTO
自动分配端点号 / Auto allocate
USB端点池类 / USB endpoint pool class.
WritePort class for handling write operations.
void FailAndClearAll(ErrorCode reason, bool in_isr)
失败完成并清空当前所有挂起写操作。
void Finish(bool in_isr, ErrorCode ans, WriteInfoBlock &info)
更新写入操作的状态。 Updates the status of the write operation.
LockFreeQueue< uint8_t > * queue_data_
Payload queue for pending write bytes. 挂起写入字节的数据队列。
LockFreeQueue< WriteInfoBlock > * queue_info_
Metadata queue for pending write batches. 挂起写批次的元数据队列。
@ INIT_ERR
初始化错误 | Initialization error
@ FAILED
操作失败 | Operation failed
@ OK
操作成功 | Operation successful
@ ARG_ERR
参数错误 | Argument error
ErrorCode(* ReadFun)(ReadPort &port, bool in_isr)
Function pointer type for read notifications.
ErrorCode(* WriteFun)(WritePort &port, bool in_isr)
Function pointer type for write operations.
OwnerType * ContainerOf(MemberType *ptr, MemberType OwnerType::*member) noexcept
通过成员指针恢复其所属对象指针
UART 配置结构体 / UART configuration structure.
uint8_t stop_bits
停止位长度 / Number of stop bits
Parity parity
校验模式 / Parity mode
uint8_t data_bits
数据位长度 / Number of data bits
uint32_t baudrate
波特率 / Baud rate
ConstRawData data
Data buffer. 数据缓冲区。