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;
288 size_t tx_buffer_size = 128,
size_t tx_queue_size = 5,
289 const char* control_interface_string = CDCBase::DEFAULT_CONTROL_INTERFACE_STRING,
290 const char* data_interface_string = CDCBase::DEFAULT_DATA_INTERFACE_STRING)
291 :
CDCBase(data_in_ep_num, data_out_ep_num, comm_ep_num, control_interface_string,
292 data_interface_string),
311 auto& line_coding = GetLineCoding();
316 line_coding.bCharFormat = 0;
319 line_coding.bCharFormat = 2;
328 line_coding.bParityType = 0;
331 line_coding.bParityType = 1;
334 line_coding.bParityType = 2;
347 line_coding.bDataBits =
static_cast<uint8_t
>(cfg.
data_bits);
353 line_coding.dwDTERate = cfg.
baudrate;
369 auto ep_data_out = GetDataOutEndpoint();
370 if (ep_data_out ==
nullptr)
375 const std::size_t MPS = ep_data_out->MaxPacketSize();
408 auto ans = ep_data_out->Transfer(MPS);
467 if (cdc->in_write_isr_.IsSet())
472 auto ep = cdc->GetDataInEndpoint();
475 auto drop_ans = cdc->tx_deq_.DropHead(
nullptr);
485 auto drop_ans = cdc->tx_deq_.DropHead(
nullptr);
500 if (ep->GetActiveLength() != 0)
510 if (cdc->tx_deq_.HasOp())
512 cdc->need_write_zlp_ =
false;
523 auto buffer = ep->GetBuffer();
527 cdc->tx_deq_.Take(
reinterpret_cast<uint8_t*
>(buffer.addr_), buffer.size_, len);
537 ep->SetActiveLength(len);
540 std::atomic_signal_fence(std::memory_order_seq_cst);
546 const std::size_t TO_SEND = ep->GetActiveLength();
558 !cdc->tx_deq_.HasOp())
563 std::atomic_signal_fence(std::memory_order_seq_cst);
566 ep->SetActiveLength(0);
567 auto ans = ep->Transfer(TO_SEND);
576 if (slot_ec ==
ErrorCode::OK && cdc->tx_deq_.HeadCompleted())
578 auto pop_ok = cdc->tx_deq_.PopCompleted(
nullptr);
583 const std::size_t MPS = ep->MaxPacketSize();
584 if (MPS > 0 && (TO_SEND % MPS) == 0 && ep->GetActiveLength() == 0 &&
585 !cdc->tx_deq_.HasOp())
587 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
ReadPort class for handling read operations.
SPSCQueue< 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)
失败完成并清空当前所有挂起读操作。
size_t EmptySize() const
获取剩余空槽数 / Get the current free-slot count
ErrorCode PopBatch(Data *data, size_t size)
批量弹出多个 payload。
ErrorCode PushBatch(const Data *data, size_t size)
批量推入多个 payload。
通用异步收发传输(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.
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)
CDCUart(Endpoint::EPNumber data_in_ep_num, Endpoint::EPNumber data_out_ep_num, Endpoint::EPNumber comm_ep_num, size_t rx_buffer_size=128, size_t tx_buffer_size=128, size_t tx_queue_size=5, const char *control_interface_string=CDCBase::DEFAULT_CONTROL_INTERFACE_STRING, const char *data_interface_string=CDCBase::DEFAULT_DATA_INTERFACE_STRING)
构造函数 Constructor
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
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.
SPSCQueue< WriteInfoBlock > * queue_info_
Metadata queue for pending write batches. 挂起写批次的元数据队列。
SPSCQueue< uint8_t > * queue_data_
Payload queue for pending write bytes. 挂起写入字节的数据队列。
@ 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. 数据缓冲区。