libxr 1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
LibXR::LinuxUART Class Reference
Inheritance diagram for LibXR::LinuxUART:
Collaboration diagram for LibXR::LinuxUART:

Public Member Functions

 LinuxUART (const char *dev_path, unsigned int baudrate=115200, Parity parity=Parity::NO_PARITY, uint8_t data_bits=8, uint8_t stop_bits=1, uint32_t rx_queue_size=5, uint32_t tx_queue_size=5, size_t buffer_size=512)
 
std::string GetByPathForTTY (const std::string &tty_name)
 
void SetLowLatency (int fd)
 
ErrorCode SetConfig (UART::Configuration config) override
 设置 UART 配置 / Sets the UART configuration
 
- Public Member Functions inherited from LibXR::UART
 UART (size_t rx_queue_size, size_t rx_buffer_size, size_t tx_queue_size, size_t tx_buffer_size)
 UART 构造函数 / UART constructor.
 

Static Public Member Functions

static ErrorCode ReadFun (ReadPort &port)
 
static ErrorCode WriteFun (WritePort &port)
 

Private Member Functions

void RxLoop ()
 
void TxLoop ()
 

Private Attributes

int fd_ = -1
 
bool connected_ = true
 
Configuration config_
 
std::string device_path_
 
Thread rx_thread_
 
Thread tx_thread_
 
uint8_trx_buff_ = nullptr
 
uint8_ttx_buff_ = nullptr
 
size_t buff_size_ = 0
 
Semaphore write_sem_
 
Mutex read_mutex_
 

Additional Inherited Members

- Public Types inherited from LibXR::UART
enum class  Parity : uint8_t { NO_PARITY = 0 , EVEN = 1 , ODD = 2 }
 奇偶校验模式 / Parity mode More...
 
- Data Fields inherited from LibXR::UART
ReadPort read_port_
 读取端口 / Read port
 
WritePort write_port_
 写入端口 / Write port
 

Detailed Description

Definition at line 25 of file linux_uart.hpp.

Constructor & Destructor Documentation

◆ LinuxUART()

LibXR::LinuxUART::LinuxUART ( const char dev_path,
unsigned int  baudrate = 115200,
Parity  parity = Parity::NO_PARITY,
uint8_t  data_bits = 8,
uint8_t  stop_bits = 1,
uint32_t  rx_queue_size = 5,
uint32_t  tx_queue_size = 5,
size_t  buffer_size = 512 
)
inline

Definition at line 28 of file linux_uart.hpp.

33 write_sem_(0),
34 rx_buff_(new uint8_t[buffer_size]),
35 tx_buff_(new uint8_t[buffer_size]),
36 buff_size_(buffer_size)
37 {
38 if (std::filesystem::exists(dev_path) == false)
39 {
40 XR_LOG_ERROR("Cannot find UART device: %s", dev_path);
41 ASSERT(false);
42 }
43
44 device_path_ = GetByPathForTTY(dev_path);
45
46 fd_ = open(device_path_.c_str(), O_RDWR | O_NOCTTY);
47 if (fd_ < 0)
48 {
49 XR_LOG_ERROR("Cannot open UART device: %s", device_path_.c_str());
50 ASSERT(false);
51 }
52 else
53 {
54 XR_LOG_PASS("Open UART device: %s", device_path_.c_str());
55 }
56
57 config_ = {.baudrate = baudrate,
58 .parity = parity,
59 .data_bits = data_bits,
60 .stop_bits = stop_bits};
61
62 SetConfig(config_);
63
66
67 rx_thread_.Create<LinuxUART *>(
68 this, [](LinuxUART *self) { self->RxLoop(); }, "rx_uart", 8192,
70
71 tx_thread_.Create<LinuxUART *>(
72 this, [](LinuxUART *self) { self->TxLoop(); }, "tx_uart", 8192,
74 }
ErrorCode SetConfig(UART::Configuration config) override
设置 UART 配置 / Sets the UART configuration
@ REALTIME
实时优先级 Realtime priority
void Create(ArgType arg, void(*function)(ArgType arg), const char *name, size_t stack_depth, Thread::Priority priority)
创建新线程 Creates a new thread
Definition thread.hpp:64
UART(size_t rx_queue_size, size_t rx_buffer_size, size_t tx_queue_size, size_t tx_buffer_size)
UART 构造函数 / UART constructor.
Definition uart.hpp:64
WritePort write_port_
写入端口 / Write port
Definition uart.hpp:52
ReadPort read_port_
读取端口 / Read port
Definition uart.hpp:51
ErrorCode(* ReadFun)(ReadPort &port)
Function pointer type for read operations.
Definition libxr_rw.hpp:279
ErrorCode(* WriteFun)(WritePort &port)
Function pointer type for write operations.
Definition libxr_rw.hpp:275
constexpr auto min(T1 a, T2 b) -> typename std::common_type< T1, T2 >::type
计算两个数的最小值
uint32_t baudrate
波特率 / Baud rate
Definition uart.hpp:45

Member Function Documentation

◆ GetByPathForTTY()

std::string LibXR::LinuxUART::GetByPathForTTY ( const std::string &  tty_name)
inline

Definition at line 76 of file linux_uart.hpp.

77 {
78 const std::string BASE = "/dev/serial/by-path";
79 if (strncmp(tty_name.c_str(), BASE.c_str(), BASE.length()) == 0 ||
80 !std::filesystem::exists(BASE))
81 {
82 return tty_name;
83 }
84 for (const auto &entry : std::filesystem::directory_iterator(BASE))
85 {
86 std::string full = std::filesystem::canonical(entry.path());
87 if (full == tty_name)
88 {
89 return entry.path(); // 返回符号链接路径
90 }
91 }
92 return ""; // 没找到
93 }

◆ ReadFun()

static ErrorCode LibXR::LinuxUART::ReadFun ( ReadPort port)
inlinestatic

Definition at line 214 of file linux_uart.hpp.

215 {
216 auto uart = CONTAINER_OF(&port, LinuxUART, read_port_);
217 Mutex::LockGuard guard(uart->read_mutex_);
218 port.ProcessPendingReads();
219 return ErrorCode::OK;
220 }

◆ RxLoop()

void LibXR::LinuxUART::RxLoop ( )
inlineprivate

Definition at line 236 of file linux_uart.hpp.

237 {
238 while (true)
239 {
240 if (!connected_)
241 {
242 close(fd_);
243 fd_ = open(device_path_.c_str(), O_RDWR | O_NOCTTY);
244
245 if (fd_ < 0)
246 {
247 XR_LOG_WARN("Cannot open UART device: %s", device_path_.c_str());
248 Thread::Sleep(1000);
249 }
250 else
251 {
252 SetConfig(config_);
253 XR_LOG_PASS("Reopen UART device: %s", device_path_.c_str());
254 connected_ = true;
255 }
256 }
257 auto n = read(fd_, rx_buff_, buff_size_);
258 if (n > 0)
259 {
260 read_port_.queue_data_->PushBatch(rx_buff_, n);
261 Mutex::LockGuard guard(read_mutex_);
263 }
264 else
265 {
266 XR_LOG_WARN("Cannot read UART device: %s", device_path_.c_str());
267 connected_ = false;
268 }
269 }
270 }
ErrorCode PushBatch(const void *data, size_t size)
批量推入多个元素 (Push multiple elements into the queue).
Definition queue.hpp:175
void ProcessPendingReads()
Processes pending reads.
Definition libxr_rw.hpp:469
static void Sleep(uint32_t milliseconds)
让线程进入休眠状态 Puts the thread to sleep
Definition thread.cpp:9

◆ SetConfig()

ErrorCode LibXR::LinuxUART::SetConfig ( UART::Configuration  config)
inlineoverridevirtual

设置 UART 配置 / Sets the UART configuration

Parameters
configUART 配置信息 / UART configuration settings
Returns
返回操作状态,成功时返回 ErrorCode::OK,否则返回相应错误码 / Returns the operation status, ErrorCode::OK if successful, otherwise an error code

该方法为纯虚函数,子类必须实现具体的 UART 配置逻辑。 This is a pure virtual function. Subclasses must implement the specific UART configuration logic.

Implements LibXR::UART.

Definition at line 103 of file linux_uart.hpp.

104 {
105 if (&config != &config_)
106 {
107 config_ = config;
108 }
109
110 struct termios2 tio{};
111 if (ioctl(fd_, TCGETS2, &tio) != 0)
112 {
113 return ErrorCode::INIT_ERR;
114 }
115
116 // 设置自定义波特率
117 tio.c_cflag &= ~CBAUD;
118 tio.c_cflag |= BOTHER;
119 tio.c_ispeed = config.baudrate;
120 tio.c_ospeed = config.baudrate;
121
122 // 输入模式:关闭软件流控、特殊字符处理
123 tio.c_iflag &= ~(IXON | IXOFF | IXANY | ISTRIP | IGNCR | INLCR | ICRNL
124#ifdef IUCLC
125 | IUCLC
126#endif
127 );
128
129 // 输出模式:关闭所有加工
130 tio.c_oflag &= ~(OPOST
131#ifdef ONLCR
132 | ONLCR
133#endif
134#ifdef OCRNL
135 | OCRNL
136#endif
137#ifdef ONOCR
138 | ONOCR
139#endif
140#ifdef ONLRET
141 | ONLRET
142#endif
143 );
144
145 // 本地模式:禁用行缓冲、回显、信号中断
146 tio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
147
148 // 控制模式:设置数据位、校验、停止位、流控
149 tio.c_cflag &= ~CSIZE;
150 switch (config.data_bits)
151 {
152 case 5:
153 tio.c_cflag |= CS5;
154 break;
155 case 6:
156 tio.c_cflag |= CS6;
157 break;
158 case 7:
159 tio.c_cflag |= CS7;
160 break;
161 case 8:
162 tio.c_cflag |= CS8;
163 break;
164 default:
165 return ErrorCode::ARG_ERR;
166 }
167
168 // 停止位
169 tio.c_cflag &= ~CSTOPB;
170 if (config.stop_bits == 2)
171 {
172 tio.c_cflag |= CSTOPB;
173 }
174
175 // 奇偶校验
176 switch (config.parity)
177 {
179 tio.c_cflag &= ~PARENB;
180 break;
182 tio.c_cflag |= PARENB;
183 tio.c_cflag &= ~PARODD;
184 break;
186 tio.c_cflag |= PARENB;
187 tio.c_cflag |= PARODD;
188 break;
189 }
190
191 // 禁用硬件流控
192 tio.c_cflag &= ~CRTSCTS;
193
194 // 启用本地模式、读功能
195 tio.c_cflag |= (CLOCAL | CREAD);
196
197 // 控制字符配置:阻塞直到读到 1 字节
198 // for (int i = 0; i < NCCS; ++i) tio.c_cc[i] = 0;
199 tio.c_cc[VTIME] = 0;
200 tio.c_cc[VMIN] = 1;
201
202 if (ioctl(fd_, TCSETS2, &tio) != 0)
203 {
204 return ErrorCode::INIT_ERR;
205 }
206
207 SetLowLatency(fd_);
208
209 tcflush(fd_, TCIOFLUSH);
210
211 return ErrorCode::OK;
212 }
@ NO_PARITY
无校验 / No parity
@ ODD
奇校验 / Odd parity
@ EVEN
偶校验 / Even parity

◆ SetLowLatency()

void LibXR::LinuxUART::SetLowLatency ( int  fd)
inline

Definition at line 95 of file linux_uart.hpp.

96 {
101 }

◆ TxLoop()

void LibXR::LinuxUART::TxLoop ( )
inlineprivate

Definition at line 272 of file linux_uart.hpp.

273 {
274 WritePort::WriteInfo info;
275 while (true)
276 {
277 if (!connected_)
278 {
279 Thread::Sleep(1);
280 continue;
281 }
282
283 write_sem_.Wait();
284 if (write_port_.queue_info_->Pop(info) == ErrorCode::OK)
285 {
286 if (write_port_.queue_data_->PopBatch(tx_buff_, info.size) == ErrorCode::OK)
287 {
288 auto written = write(fd_, tx_buff_, info.size);
289 if (written < 0)
290 {
291 XR_LOG_WARN("Cannot write UART device: %s", device_path_.c_str());
292 connected_ = false;
293 }
294 info.op.UpdateStatus(false, (written == static_cast<int>(info.size))
295 ? ErrorCode::OK
296 : ErrorCode::FAILED);
297 }
298 else
299 {
300 ASSERT(false);
301 info.op.UpdateStatus(false, ErrorCode::FAILED);
302 }
303 }
304 }
305 }
ErrorCode PopBatch(Data *data, size_t batch_size)
批量弹出数据 / Pops multiple elements from the queue
ErrorCode Wait(uint32_t timeout=UINT32_MAX)
等待(减少)信号量 Waits (decrements) the semaphore
Definition semaphore.cpp:15

◆ WriteFun()

static ErrorCode LibXR::LinuxUART::WriteFun ( WritePort port)
inlinestatic

Definition at line 222 of file linux_uart.hpp.

223 {
224 auto uart = CONTAINER_OF(&port, LinuxUART, write_port_);
225 WritePort::WriteInfo info;
226 if (port.queue_info_->Peek(info) != ErrorCode::OK)
227 {
228 return ErrorCode::EMPTY;
229 }
230 port.UpdateStatus(info.op);
231 uart->write_sem_.Post();
232 return ErrorCode::OK;
233 }

Field Documentation

◆ buff_size_

size_t LibXR::LinuxUART::buff_size_ = 0
private

Definition at line 315 of file linux_uart.hpp.

◆ config_

Configuration LibXR::LinuxUART::config_
private

Definition at line 309 of file linux_uart.hpp.

◆ connected_

bool LibXR::LinuxUART::connected_ = true
private

Definition at line 308 of file linux_uart.hpp.

◆ device_path_

std::string LibXR::LinuxUART::device_path_
private

Definition at line 310 of file linux_uart.hpp.

◆ fd_

int LibXR::LinuxUART::fd_ = -1
private

Definition at line 307 of file linux_uart.hpp.

◆ read_mutex_

Mutex LibXR::LinuxUART::read_mutex_
private

Definition at line 317 of file linux_uart.hpp.

◆ rx_buff_

uint8_t* LibXR::LinuxUART::rx_buff_ = nullptr
private

Definition at line 313 of file linux_uart.hpp.

◆ rx_thread_

Thread LibXR::LinuxUART::rx_thread_
private

Definition at line 311 of file linux_uart.hpp.

◆ tx_buff_

uint8_t* LibXR::LinuxUART::tx_buff_ = nullptr
private

Definition at line 314 of file linux_uart.hpp.

◆ tx_thread_

Thread LibXR::LinuxUART::tx_thread_
private

Definition at line 312 of file linux_uart.hpp.

◆ write_sem_

Semaphore LibXR::LinuxUART::write_sem_
private

Definition at line 316 of file linux_uart.hpp.


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