lacteApp
C++17 service for Lacte hardware
Loading...
Searching...
No Matches
cm_protocol.hpp
Go to the documentation of this file.
1#pragma once
2
10
11#include <libraries/interfaces/UartLinux.hpp>
12
13#include "ProtocolEndpoint.hpp"
16
18
19// Простая контрольная сумма побайтовым сложением - не CRC в строгом смысле,
20// реализована именно так, потому что таким образом её считает плата
21// (см. "сделай как в коде" ниже - это воспроизведение поведения из образца
22// вендорского кода, а не собственный выбор алгоритма).
23class CustomCrc final : ICrc {
24 public:
25 explicit CustomCrc() : ICrc("custom crc") {}
26 void reset() override {}
27 auto calc(const CustomSpan<uint8_t> buffer) -> uint32_t override {
28 uint8_t crc = 0;
29 for (const auto value : buffer) {
30 crc += value;
31 }
32 return crc; // сделай как в коде
33 }
34
35 auto append(const uint32_t last_crc, const CustomSpan<uint8_t> data)
36 -> uint32_t override {
37 const uint8_t crc = calc(data) + last_crc;
38 return crc; // сделай как в коде
39 }
40};
41
42template <typename T>
43void log_change(const char* name, T& old_val, T new_val) {
44 if (old_val != new_val) {
45 std::cout << name << ": " << +old_val << " -> " << +new_val << '\n';
46 old_val = new_val;
47 }
48}
49
50template <typename T>
51void log_flag(const char* name, T& old_val, T new_val) {
52 const bool old_b = old_val != 0;
53 if (const bool new_b = new_val != 0; old_b != new_b) {
54 std::cout << name << ": " << old_b << " -> " << new_b << '\n';
55 old_val = new_val;
56 }
57}
58
59// Конечная точка протокола обмена с задней платой: принимает кадры
60// HeadBoardPrototype и отправляет кадры BackBoardPrototype, используя
61// CustomCrc в качестве контрольной суммы.
62template <uint8_t* RX_BASE, uint8_t* TX_BASE>
64 : public ProtocolEndpoint<
65 typename HeadBoardPrototype<RX_BASE>::packet_fields,
66 typename BackBoardPrototype<TX_BASE>::packet_fields, CustomCrc> {
67 public:
68 using ReceiveType = typename ProtocolEndpoint<
71 CustomCrc>::RxFieldsSnapshot;
72 explicit BackBoardProtocol(bool debug = false) {
73 this->m_rx.set_print_flags(PRINT_PARSING_ERRORS);
74
75 this->set_debug(debug);
76 }
77
78 void test_diagnostics(interface::UartLinuxInterface m_uart_interface) {
79 using namespace std::string_literals;
80 this->set_interfaces(m_uart_interface, m_uart_interface);
81 auto get_diff = [&](ReceiveType&& snapshot) -> void {
82 static HeadFlags flags;
83 static HeadPacketTypes packet_types;
84 auto new_flags = meta::get_named<FieldName::HEADER_FIELD>(snapshot);
85 auto new_packet = meta::get_named<FieldName::TYPE_FIELD>(snapshot);
86 auto new_data = meta::get_named<FieldName::DATA_FIELD>(snapshot);
87 for (int i = 0; i < static_cast<int>(flags.m_dummy1.size()); i++) {
88 using namespace std::string_literals;
89 log_change<uint8_t>(("m_dummy1["s + std::to_string(i) + "] ").c_str(),
90 flags.m_dummy1[i], new_flags.m_dummy1[i]);
91 }
92 log_change<uint8_t>("door_flags_and_other"s.c_str(), flags.door_and_other,
93 new_flags.door_and_other);
94 for (int i = 0; i < static_cast<int>(flags.m_dummy2.size()); i++) {
95 using namespace std::string_literals;
96 log_change<uint8_t>(("m_dummy1["s + std::to_string(i) + "] ").c_str(),
97 flags.m_dummy1[i], new_flags.m_dummy1[i]);
98 }
99 log_change("packet type", packet_types, new_packet);
100 };
101 set_receive_callback(get_diff);
102 }
103
105 void reset() { this->m_rx.reset(); }
106};
107} // namespace proto::back_board_proto
Прототип полей протокола задней (back) платы: типы пакетов, статусные флаги BoardFlags/StatusFieldDat...
void reset()
Сброс состояния парсера
void test_diagnostics(interface::UartLinuxInterface m_uart_interface)
typename ProtocolEndpoint< typename HeadBoardPrototype< RX_BASE >::packet_fields, typename BackBoardPrototype< TX_BASE >::packet_fields, CustomCrc >::RxFieldsSnapshot ReceiveType
auto calc(const CustomSpan< uint8_t > buffer) -> uint32_t override
auto append(const uint32_t last_crc, const CustomSpan< uint8_t > data) -> uint32_t override
Прототип полей протокола головной (HMI) платы: типы пакетов, флаги door_and_other и раскладка HeadFla...
void log_flag(const char *name, T &old_val, T new_val)
void log_change(const char *name, T &old_val, T new_val)
std::tuple< IdFieldType, LenFieldType, StatusFieldType, FlagsFieldType, TypeFieldType, SubStageFieldType, DateFieldType, DumpFieldType, CrcFieldType > packet_fields
std::tuple< IdFieldType, LenFieldType, FlagsFieldType, TypeFieldType, DateFieldType, CrcFieldType > packet_fields
std::array< uint8_t, HEAD_FLAGS_RESERVED_AFTER_SIZE > m_dummy2
std::array< uint8_t, HEAD_FLAGS_RESERVED_BEFORE_SIZE > m_dummy1