libxr
Embedded C++ framework for bare-metal, RTOS and Linux
Loading...
Searching...
No Matches
LibXR::USB::EndpointPool Class Reference

USB端点池类 / USB endpoint pool class. More...

#include <ep_pool.hpp>

Inheritance diagram for LibXR::USB::EndpointPool:
[legend]

Public Member Functions

 EndpointPool (size_t endpoint_num)
 构造函数 / Constructor
 
 EndpointPool (const EndpointPool &)=delete
 
EndpointPool & operator= (const EndpointPool &)=delete
 
ErrorCode Put (Endpoint *ep)
 登记一个端点到池中 / Register an endpoint into the pool
 
ErrorCode Get (Endpoint *&ep_info, Endpoint::Direction direction, Endpoint::EPNumber ep_num)
 分配端点 / Allocate endpoint
 
ErrorCode Release (Endpoint *ep_info)
 回收端点 / Release endpoint
 
ErrorCode FindEndpoint (uint8_t ep_addr, Endpoint *&ans)
 查找端点/ Lookup endpoint
 
Endpoint * GetEndpoint0Out ()
 获取端点0的OUT对象 / Get Endpoint 0's OUT object
 
Endpoint * GetEndpoint0In ()
 获取端点0的IN对象 / Get Endpoint 0's IN object
 
void SetEndpoint0 (Endpoint *ep0_in, Endpoint *ep0_out)
 设置端点0的IN/OUT对象 / Set Endpoint 0 IN/OUT objects
 

Detailed Description

USB端点池类 / USB endpoint pool class.

按「端点号 × 方向」二维索引管理固定的 Endpoint 指针。所有 Endpoint 对象由后端在 初始化时通过 Put() 填入,池只负责登记、分配、查找与回收,不负责对象生命周期。 端点 0 的 IN/OUT 不进入索引数组,由 SetEndpoint0/GetEndpoint0* 单独管理。

Manages fixed Endpoint pointers indexed by (endpoint-number, direction). All Endpoint objects are populated by the backend at init time via Put(); the pool only registers, allocates, looks up and recycles them, and does not own their lifetime. Endpoint 0's IN/OUT are kept out of the index array and managed by SetEndpoint0/GetEndpoint0*.

Note
分配/回收发生在配置切换(SetConfiguration/Reset)这类低频、非并发路径, 因此使用普通数组与非原子状态,无需无锁结构。 Allocation/recycling happens on low-frequency, non-concurrent paths (SetConfiguration/Reset), so a plain array with non-atomic state is used.

Definition at line 28 of file ep_pool.hpp.

Constructor & Destructor Documentation

◆ EndpointPool()

EndpointPool::EndpointPool ( size_t endpoint_num)
explicit

构造函数 / Constructor

Parameters
endpoint_num端点总数(包含端点0,必须 >=2)/ Total number of endpoints (including EP0, must >=2)
Note
端点对象本身由后端通过 Put() 填入;该参数仅用于合法性校验。 Endpoint objects are populated by the backend via Put(); this argument is only used for a validity check.

Definition at line 5 of file ep_pool.cpp.

5{ ASSERT(endpoint_num >= 2); }

Member Function Documentation

◆ FindEndpoint()

LibXR::ErrorCode EndpointPool::FindEndpoint ( uint8_t ep_addr,
Endpoint *& ans )

查找端点/ Lookup endpoint

端点 0 走 ep0_in_/ep0_out_ 旁路;其余端点仅在「已分配(in-use)」状态下可被查到, 未分配的端点返回 NOT_FOUND(收到端点级请求视为异常)。 Endpoint 0 goes through the ep0_in_/ep0_out_ bypass; other endpoints are visible only while allocated (in-use); an unallocated endpoint returns NOT_FOUND (an endpoint-level request for it is treated as an error).

Parameters
ep_addr端点地址,IN端点高位需加0x80 / Endpoint address (0x80 for IN endpoints)
[out]ans查找到的端点对象指针 / Found endpoint pointer
Return values
ErrorCode操作结果(OK/NOT_FOUND)/ Operation result

Definition at line 119 of file ep_pool.cpp.

120{
121 const Endpoint::Direction direction =
122 (ep_addr & 0x80) ? Endpoint::Direction::IN : Endpoint::Direction::OUT;
123
124 if ((ep_addr & 0x7F) == 0)
125 {
126 ans = (direction == Endpoint::Direction::IN) ? ep0_in_ : ep0_out_;
127 return (ans != nullptr) ? LibXR::ErrorCode::OK : LibXR::ErrorCode::NOT_FOUND;
128 }
129
130 const size_t num = ep_addr & 0x7F;
131 if (num >= SLOT_COUNT)
132 {
134 }
135
136 const size_t d = DirIndex(direction);
137 Endpoint* ep = slots_[num][d];
138 // 仅「已分配(in-use)」且当前配置地址/方向与请求一致的端点可被反查到。
139 // 必须核对 GetAddress()/GetDirection()(当前配置方向):
140 // 一个 BOTH 端点被配置成单一方向后,不会再被另一方向的同号地址查到。
141 // Only endpoints that are allocated (in-use) AND whose current configured
142 // address/direction match the request are visible here.
143 // GetAddress()/GetDirection() (the configured direction) are checked so that once a
144 // BOTH endpoint is configured for a single direction, it is no longer reachable via the
145 // opposite-direction address of the same number.
146 if (ep != nullptr && use_[num][d] == SlotUse::IN_USE && ep->GetAddress() == ep_addr &&
147 ep->GetDirection() == direction)
148 {
149 ans = ep;
151 }
152
154}
USB 端点基类 / USB Endpoint base class.
Definition ep.hpp:24
uint8_t GetAddress() const
获取端点地址(方向 + 号) / Get endpoint address (dir + num)
Definition ep.hpp:194
Direction
端点方向 Endpoint direction
Definition ep.hpp:31
@ IN
输入方向 / IN direction
Direction GetDirection() const
获取当前端点方向 / Get current endpoint direction
Definition ep.hpp:181
@ NOT_FOUND
未找到 / Not found
@ OK
操作成功 / Operation successful

◆ Get()

LibXR::ErrorCode EndpointPool::Get ( Endpoint *& ep_info,
Endpoint::Direction direction,
Endpoint::EPNumber ep_num )

分配端点 / Allocate endpoint

按指定端点号与方向精确匹配一个已登记且空闲的端点。调用方必须显式指定端点号, 不再支持自动分配。 Precisely matches a registered, available endpoint by the given number and direction. The caller must specify the endpoint number explicitly; auto-allocation is no longer supported.

Parameters
[out]ep_info分配得到的端点对象指针 / Allocated endpoint pointer
direction端点方向(IN/OUT)/ Endpoint direction
ep_num指定端点号(必填)/ Endpoint number (required)
Return values
ErrorCode操作结果(OK/NOT_FOUND)/ Operation result

Definition at line 52 of file ep_pool.cpp.

54{
55 const auto num = static_cast<size_t>(ep_num);
56 if (num >= SLOT_COUNT || direction == Endpoint::Direction::BOTH)
57 {
59 }
60
61 const size_t d = DirIndex(direction);
62 Endpoint* ep = slots_[num][d];
63 if (ep == nullptr || use_[num][d] != SlotUse::AVAILABLE)
64 {
66 }
67
68 // 端点登记方向必须与请求方向兼容(具体方向匹配,或登记为 BOTH)。
69 // The registered direction must be compatible with the requested one (exact match, or
70 // registered as BOTH).
71 const Endpoint::Direction avail = ep->AvailableDirection();
72 if (avail != direction && avail != Endpoint::Direction::BOTH)
73 {
75 }
76
77 ep_info = ep;
78
79 // BOTH 端点占用后,两个方向槽一并标记为使用中。
80 // For a BOTH endpoint, mark both direction slots as in-use together.
81 if (avail == Endpoint::Direction::BOTH)
82 {
83 use_[num][0] = SlotUse::IN_USE;
84 use_[num][1] = SlotUse::IN_USE;
85 }
86 else
87 {
88 use_[num][d] = SlotUse::IN_USE;
89 }
91}
Direction AvailableDirection() const
获取允许配置的方向 / Get allowed endpoint direction
Definition ep.hpp:175
@ BOTH
双向(可配置为 IN/OUT) / Both (configurable as IN/OUT)

◆ GetEndpoint0In()

Endpoint * EndpointPool::GetEndpoint0In ( )

获取端点0的IN对象 / Get Endpoint 0's IN object

Returns
Endpoint* 端点0 IN对象指针 / Endpoint 0 IN pointer

Definition at line 158 of file ep_pool.cpp.

158{ return ep0_in_; }

◆ GetEndpoint0Out()

Endpoint * EndpointPool::GetEndpoint0Out ( )

获取端点0的OUT对象 / Get Endpoint 0's OUT object

Returns
Endpoint* 端点0 OUT对象指针 / Endpoint 0 OUT pointer

Definition at line 156 of file ep_pool.cpp.

156{ return ep0_out_; }

◆ Put()

LibXR::ErrorCode EndpointPool::Put ( Endpoint * ep)

登记一个端点到池中 / Register an endpoint into the pool

按端点自身的号(GetNumber)与可用方向(AvailableDirection)入位。端点 0 不应 通过此接口登记(应使用 SetEndpoint0)。 Registered by the endpoint's own number (GetNumber) and available direction (AvailableDirection). Endpoint 0 must not be registered here (use SetEndpoint0).

Parameters
ep待登记的端点对象指针 / Endpoint pointer to register
Return values
ErrorCode操作结果(OK/ARG_ERR/FULL)/ Operation result

Definition at line 7 of file ep_pool.cpp.

8{
9 if (ep == nullptr)
10 {
12 }
13
14 const auto ep_num = static_cast<size_t>(ep->GetNumber());
15 if (ep_num >= SLOT_COUNT)
16 {
18 }
19
21
22 // BOTH 端点同时登记到该号的两个方向槽;其余按具体方向入位。
23 // A BOTH endpoint is registered into both direction slots of its number; others go
24 // into their concrete direction slot.
26 {
27 for (size_t d = 0; d < DIR_COUNT; ++d)
28 {
29 if (slots_[ep_num][d] != nullptr)
30 {
32 }
33 }
34 for (size_t d = 0; d < DIR_COUNT; ++d)
35 {
36 slots_[ep_num][d] = ep;
37 use_[ep_num][d] = SlotUse::AVAILABLE;
38 }
40 }
41
42 const size_t d = DirIndex(dir);
43 if (slots_[ep_num][d] != nullptr)
44 {
46 }
47 slots_[ep_num][d] = ep;
48 use_[ep_num][d] = SlotUse::AVAILABLE;
50}
EPNumber GetNumber() const
获取端点号 / Get endpoint number
Definition ep.hpp:169
@ FULL
已满 / Full
@ ARG_ERR
参数错误 / Argument error

◆ Release()

LibXR::ErrorCode EndpointPool::Release ( Endpoint * ep_info)

回收端点 / Release endpoint

Parameters
ep_info待回收的端点对象指针 / Endpoint pointer to release
Return values
ErrorCode操作结果(OK/NOT_FOUND)/ Operation result

Definition at line 93 of file ep_pool.cpp.

94{
95 if (ep_info == nullptr)
96 {
98 }
99
100 const auto num = static_cast<size_t>(ep_info->GetNumber());
101 if (num >= SLOT_COUNT)
102 {
104 }
105
106 bool released = false;
107 for (size_t d = 0; d < DIR_COUNT; ++d)
108 {
109 if (slots_[num][d] == ep_info && use_[num][d] == SlotUse::IN_USE)
110 {
111 use_[num][d] = SlotUse::AVAILABLE;
112 released = true;
113 }
114 }
115
117}

◆ SetEndpoint0()

void EndpointPool::SetEndpoint0 ( Endpoint * ep0_in,
Endpoint * ep0_out )

设置端点0的IN/OUT对象 / Set Endpoint 0 IN/OUT objects

Parameters
ep0_in端点0 IN对象指针 / Endpoint 0 IN pointer
ep0_out端点0 OUT对象指针 / Endpoint 0 OUT pointer

Definition at line 160 of file ep_pool.cpp.

161{
162 ep0_in_ = ep0_in;
163 ep0_out_ = ep0_out;
164}

The documentation for this class was generated from the following files: