Skip to content

Commit a0c7d6a

Browse files
committed
Добавлен доступ к uart через протокол, MockUart и тесты для протокола
1 parent 93e6214 commit a0c7d6a

5 files changed

Lines changed: 348 additions & 15 deletions

File tree

csup/protocol/cobs.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -178,15 +178,15 @@ class COBSDecoder
178178
* @return Result Result::SUCCESS if successful, otherwise an error code.
179179
*/
180180
template <typename Uart, typename Time>
181-
inline Result receive_cobs_stream(hal::IUart<Uart>& uart,
181+
inline Result receive_cobs_stream(Uart& uart,
182182
BufferView& buffer,
183183
const types::u32& timeout,
184184
BufferView& out_buffer)
185185
{
186186
if (!uart.is_open())
187187
return Result::UART_ERROR;
188188

189-
auto start_time = hal::ITime<Time>::now();
189+
auto start_time = Time::now();
190190
COBSDecoder cobsDecoder(buffer);
191191
types::u8 byte;
192192

@@ -210,7 +210,7 @@ inline Result receive_cobs_stream(hal::IUart<Uart>& uart,
210210
break;
211211
}
212212
}
213-
while (hal::ITime<Time>::now() - start_time < timeout);
213+
while (Time::now() - start_time < timeout);
214214

215215
return Result::TIMEOUT;
216216
}
@@ -229,7 +229,7 @@ inline Result receive_cobs_stream(hal::IUart<Uart>& uart,
229229
* @return Result Result::SUCCESS if successful, otherwise an error code.
230230
*/
231231
template <typename Uart>
232-
inline Result send_cobs_stream(hal::IUart<Uart>& uart, const BufferView& buffer)
232+
inline Result send_cobs_stream(Uart& uart, const BufferView& buffer)
233233
{
234234
if (!uart.is_open())
235235
return Result::UART_ERROR;

csup/protocol/protocol.hpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ class Protocol
6767
uart_.close();
6868
}
6969

70+
/** @brief Provides access to the underlying UART interface. */
71+
Uart& uart()
72+
{
73+
return uart_;
74+
}
75+
7076
/** @brief Returns number of bytes available in UART receive buffer. */
7177
types::size available()
7278
{
@@ -89,7 +95,7 @@ class Protocol
8995
{
9096
Result result;
9197

92-
auto start_time = hal::ITime<Time>::now();
98+
auto start_time = Time::now();
9399
do
94100
{
95101
BufferView msg_view;
@@ -127,7 +133,7 @@ class Protocol
127133

128134
return Result::SUCCESS;
129135
}
130-
while (hal::ITime<Time>::now() - start_time < timeout);
136+
while (Time::now() - start_time < timeout);
131137

132138
return (result != Result::SUCCESS) ? result : Result::TIMEOUT;
133139
}
@@ -271,7 +277,7 @@ class Protocol
271277
{
272278
Result result;
273279

274-
auto start_time = hal::ITime<Time>::now();
280+
auto start_time = Time::now();
275281
do
276282
{
277283
BufferView msg_view;
@@ -323,7 +329,7 @@ class Protocol
323329
}
324330
}
325331
}
326-
while (hal::ITime<Time>::now() - start_time < timeout);
332+
while (Time::now() - start_time < timeout);
327333

328334
return (result != Result::SUCCESS) ? result : Result::TIMEOUT;
329335
}
@@ -380,7 +386,7 @@ class Protocol
380386
return Result::SUCCESS;
381387
}
382388

383-
hal::IUart<Uart> uart_;
389+
Uart uart_;
384390
BufferHandler<MaxMsgSize + tp::FieldHeader::SIZE + Crc::SIZE> buffer_;
385391

386392
tp::FieldID frame_id_ = 0;

tests/mocks/uart.hpp

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
/** @brief Mock UART interface for testing purposes. */
2+
3+
#ifndef CSUP_TESTS_MOCKS_UART_HPP
4+
#define CSUP_TESTS_MOCKS_UART_HPP
5+
6+
#include "csup/hal/interfaces/uart.hpp"
7+
8+
#include <chrono>
9+
#include <iostream>
10+
#include <memory>
11+
#include <mutex>
12+
#include <queue>
13+
#include <thread>
14+
15+
namespace csup { namespace hal {
16+
17+
/** @brief Thread-safe queue for simulating UART buffers. */
18+
struct MutexQueue
19+
{
20+
std::queue<uint8_t> q;
21+
std::mutex mtx;
22+
23+
void push(uint8_t val)
24+
{
25+
std::lock_guard<std::mutex> lock(mtx);
26+
q.push(val);
27+
}
28+
29+
void push(const uint8_t* data, size_t size)
30+
{
31+
std::lock_guard<std::mutex> lock(mtx);
32+
for (size_t i = 0; i < size; ++i)
33+
q.push(data[i]);
34+
}
35+
36+
void pop()
37+
{
38+
std::lock_guard<std::mutex> lock(mtx);
39+
if (!q.empty())
40+
q.pop();
41+
}
42+
43+
uint8_t front()
44+
{
45+
std::lock_guard<std::mutex> lock(mtx);
46+
return q.front();
47+
}
48+
49+
bool empty()
50+
{
51+
std::lock_guard<std::mutex> lock(mtx);
52+
return q.empty();
53+
}
54+
55+
size_t size()
56+
{
57+
std::lock_guard<std::mutex> lock(mtx);
58+
return q.size();
59+
}
60+
61+
void clear()
62+
{
63+
std::lock_guard<std::mutex> lock(mtx);
64+
while (!q.empty())
65+
q.pop();
66+
}
67+
};
68+
69+
/** @brief Mock UART implementation for testing. */
70+
class MockUart : public IUart<MockUart>
71+
{
72+
public:
73+
MockUart() = default;
74+
~MockUart() = default;
75+
76+
bool open_impl()
77+
{
78+
return true;
79+
}
80+
81+
void close_impl() {}
82+
83+
bool read_impl(types::u8& byte)
84+
{
85+
if (!rx_buffer_)
86+
return false;
87+
88+
auto start = std::chrono::steady_clock::now();
89+
auto timeout = std::chrono::milliseconds(cfg_.timeout);
90+
auto check_interval = std::chrono::milliseconds(10);
91+
92+
do
93+
{
94+
if (!rx_buffer_->empty())
95+
{
96+
byte = rx_buffer_->front();
97+
rx_buffer_->pop();
98+
return true;
99+
}
100+
std::this_thread::sleep_for(check_interval);
101+
}
102+
while (std::chrono::steady_clock::now() - start < timeout);
103+
104+
return false;
105+
}
106+
107+
bool write_impl(const types::u8* buffer, types::size size)
108+
{
109+
if (!tx_buffer_)
110+
return false;
111+
112+
tx_buffer_->push(buffer, size);
113+
return true;
114+
}
115+
116+
bool write_impl(types::u8 byte)
117+
{
118+
if (!tx_buffer_)
119+
return false;
120+
121+
tx_buffer_->push(byte);
122+
return true;
123+
}
124+
125+
types::size available_impl()
126+
{
127+
return rx_buffer_ ? rx_buffer_->size() : 0;
128+
}
129+
130+
void flush_impl()
131+
{
132+
if (rx_buffer_)
133+
rx_buffer_->clear();
134+
}
135+
136+
void connect(std::shared_ptr<MutexQueue> tx_buffer, std::shared_ptr<MutexQueue> rx_buffer)
137+
{
138+
tx_buffer_ = tx_buffer;
139+
rx_buffer_ = rx_buffer;
140+
}
141+
142+
private:
143+
std::shared_ptr<MutexQueue> tx_buffer_;
144+
std::shared_ptr<MutexQueue> rx_buffer_;
145+
};
146+
147+
148+
}} // namespace csup::hal
149+
150+
#endif

tests/test_crc.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ TYPED_TEST(CRCTest, WriteAndValidate)
4848
EXPECT_EQ(out2.size(), 32);
4949
}
5050

51-
TYPED_TEST(CRCTest, Compute_Consistency)
51+
TYPED_TEST(CRCTest, ComputeConsistency)
5252
{
5353
types::u8 raw[256];
5454
fill_random(raw, sizeof(raw));
@@ -60,7 +60,7 @@ TYPED_TEST(CRCTest, Compute_Consistency)
6060
EXPECT_EQ(crc1, crc2);
6161
}
6262

63-
TYPED_TEST(CRCTest, Validate_Error)
63+
TYPED_TEST(CRCTest, ValidateError)
6464
{
6565
types::u8 raw[256];
6666
fill_random(raw, 224);
@@ -78,12 +78,15 @@ TYPED_TEST(CRCTest, Validate_Error)
7878
EXPECT_EQ(res, Result::CRC_ERROR);
7979
}
8080

81-
// ---------- Tests ----------
82-
TEST(CRCTest, CRC16_CCITT_FALSE_Test)
81+
TYPED_TEST(CRCTest, ReferenceVector)
8382
{
8483
types::u8 data[] = {'1', '2', '3', '4', '5', '6', '7', '8', '9'};
8584
BufferView buffer(data, sizeof(data));
8685

87-
auto res = CRC16_CCITT_FALSE::compute(buffer);
88-
EXPECT_EQ(res, 0x29B1);
86+
auto crc = TypeParam::compute(buffer);
87+
88+
if constexpr (std::is_same_v<TypeParam, CRC16_CCITT_FALSE>)
89+
EXPECT_EQ(crc, 0x29B1);
90+
else
91+
GTEST_SKIP() << "No reference vector defined for this CRC type";
8992
}

0 commit comments

Comments
 (0)