libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
libxr_system.cpp
1#include "libxr_system.hpp"
2
3#include <sys/ioctl.h>
4#include <sys/select.h>
5#include <sys/types.h>
6#include <termios.h>
7#include <unistd.h>
8
9#include <cstddef>
10
11#include "libxr_def.hpp"
12#include "libxr_rw.hpp"
13#include "libxr_type.hpp"
14#include "linux_timebase.hpp"
15#include "logger.hpp"
16#include "thread.hpp"
17#include "timer.hpp"
18
19struct timespec libxr_linux_start_time_spec; // NOLINT
20
21static LibXR::LinuxTimebase libxr_linux_timebase;
22
23static LibXR::Semaphore stdo_sem;
24
25void StdiThread(LibXR::ReadPort* read_port)
26{
27 static uint8_t read_buff[static_cast<size_t>(4 * LIBXR_PRINTF_BUFFER_SIZE)];
28
29 if (!isatty(STDIN_FILENO))
30 {
31 XR_LOG_WARN("STDIO.read_: stdin is not a TTY, parking thread forever");
32 while (true)
33 {
34 LibXR::Thread::Sleep(UINT32_MAX);
35 }
36 }
37
38 while (true)
39 {
40 fd_set rfds;
41 FD_ZERO(&rfds);
42 FD_SET(STDIN_FILENO, &rfds);
43
44 int ret = select(STDIN_FILENO + 1, &rfds, NULL, NULL, NULL);
45
46 if (ret > 0 && FD_ISSET(STDIN_FILENO, &rfds))
47 {
48 int ready = 0;
49 if (ioctl(STDIN_FILENO, FIONREAD, &ready) != -1 && ready > 0)
50 {
51 auto size = fread(read_buff, sizeof(char), ready, stdin);
52 if (size < 1)
53 {
54 continue;
55 }
56 read_port->queue_data_->PushBatch(read_buff, size);
57 read_port->ProcessPendingReads(false);
58 }
59 }
60 }
61}
62
63void StdoThread(LibXR::WritePort* write_port)
64{
66 static uint8_t write_buff[static_cast<size_t>(4 * LIBXR_PRINTF_BUFFER_SIZE)];
67
68 while (true)
69 {
70 if (stdo_sem.Wait() == LibXR::ErrorCode::OK)
71 {
72 auto ans = write_port->queue_info_->Pop(info);
73 if (ans != LibXR::ErrorCode::OK)
74 {
75 continue;
76 }
77
78 ans = write_port->queue_data_->PopBatch(write_buff, info.data.size_);
79 if (ans != LibXR::ErrorCode::OK)
80 {
81 continue;
82 }
83
84 auto write_size = fwrite(write_buff, sizeof(char), info.data.size_, stdout);
85 auto fflush_ans = fflush(stdout);
86
87 UNUSED(write_size);
88 UNUSED(fflush_ans);
89
90 write_port->Finish(
91 false, write_size == info.data.size_ ? LibXR::ErrorCode::OK : LibXR::ErrorCode::FAILED, info);
92 }
93 }
94}
95
96void LibXR::PlatformInit(uint32_t timer_pri, uint32_t timer_stack_depth)
97{
98 LibXR::Timer::priority_ = static_cast<LibXR::Thread::Priority>(timer_pri);
99 LibXR::Timer::stack_depth_ = timer_stack_depth;
100 auto write_fun = [](WritePort& port, bool)
101 {
102 UNUSED(port);
103 stdo_sem.Post();
105 };
106
108 new LibXR::WritePort(32, static_cast<size_t>(4 * LIBXR_PRINTF_BUFFER_SIZE));
109
110 *LibXR::STDIO::write_ = write_fun;
111
112 auto read_fun = [](ReadPort& port, bool)
113 {
114 UNUSED(port);
116 };
117
119 new LibXR::ReadPort(static_cast<size_t>(4 * LIBXR_PRINTF_BUFFER_SIZE));
120
121 *LibXR::STDIO::read_ = read_fun;
122
123 UNUSED(clock_gettime(CLOCK_MONOTONIC, &libxr_linux_start_time_spec));
124
125 struct termios tty;
126 tcgetattr(STDIN_FILENO, &tty); // 获取当前终端属性
127 tty.c_lflag &= ~(ICANON | ECHO); // 禁用规范模式和回显
128 tcsetattr(STDIN_FILENO, TCSANOW, &tty); // 立即生效
129
130 LibXR::Thread stdi_thread, stdo_thread;
131 stdi_thread.Create<LibXR::ReadPort*>(LibXR::STDIO::read_, StdiThread, "STDIO.read_",
133
134 stdo_thread.Create<LibXR::WritePort*>(LibXR::STDIO::write_, StdoThread, "STDIO.write_",
136}
size_t size_
数据大小(字节)。 The size of the data (in bytes).
Linux 时间基准实现 / Linux timebase implementation.
ErrorCode PushBatch(const Data *data, size_t size)
批量推入数据 / Pushes multiple elements into the queue
ErrorCode PopBatch(Data *data, size_t size)
批量弹出数据 / Pops multiple elements from the queue
ReadPort class for handling read operations.
Definition libxr_rw.hpp:379
void ProcessPendingReads(bool in_isr)
Processes pending reads.
Definition libxr_rw.cpp:193
static ReadPort * read_
Read port instance. 读取端口。
Definition libxr_rw.hpp:771
static WritePort * write_
Write port instance. 写入端口。
Definition libxr_rw.hpp:772
信号量类,实现线程同步机制 Semaphore class implementing thread synchronization
Definition semaphore.hpp:23
void Post()
释放(增加)信号量 Releases (increments) the semaphore
Definition semaphore.cpp:44
ErrorCode Wait(uint32_t timeout=UINT32_MAX)
等待(减少)信号量 Waits (decrements) the semaphore
Definition semaphore.cpp:53
线程管理类,封装 POSIX 线程创建和调度 Thread management class encapsulating POSIX thread creation and scheduling
Definition thread.hpp:18
Priority
线程优先级枚举 Enumeration for thread priorities
Definition thread.hpp:25
@ MEDIUM
中等优先级 Medium 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:68
static void Sleep(uint32_t milliseconds)
让线程进入休眠状态 Puts the thread to sleep
Definition thread.cpp:15
static uint32_t stack_depth_
线程栈深度 Thread stack depth
Definition timer.hpp:169
static LibXR::Thread::Priority priority_
线程优先级 Thread priority
Definition timer.hpp:167
WritePort class for handling write operations.
Definition libxr_rw.hpp:538
void Finish(bool in_isr, ErrorCode ans, WriteInfoBlock &info)
更新写入操作的状态。 Updates the status of the write operation.
Definition libxr_rw.cpp:294
@ FAILED
操作失败 | Operation failed
@ PENDING
等待中 | Pending
@ OK
操作成功 | Operation successful
void PlatformInit(uint32_t timer_pri=2, uint32_t timer_stack_depth=65536)
平台初始化函数 Platform initialization function
ConstRawData data
Data buffer. 数据缓冲区。
Definition libxr_rw.hpp:370