tutrcos
読み取り中…
検索中…
一致する文字列を見つけられません
cobs_bridge.hpp
[詳解]
1#pragma once
2
3#include <cstddef>
4#include <cstdint>
5#include <vector>
6
7#include "cobs.h"
8
9#include "tutrcos/core.hpp"
11
12namespace tutrcos {
13namespace module {
14
16 uint8_t id;
17 std::vector<uint8_t> data;
18};
19
21public:
22 COBSBridge(peripheral::UART &uart) : uart_{uart} {}
23
24 bool transmit(const COBSBridgeMessage &msg, uint32_t timeout) {
25 // id(1 byte) + data(n byte) + checksum(1 byte) + delimiter(1 byte)
26 if (!msg.data.empty()) {
27 tx_buf_.resize(COBS_ENCODE_DST_BUF_LEN_MAX(msg.data.size()) + 3);
28 cobs_encode_result res =
29 cobs_encode(tx_buf_.data() + 1, tx_buf_.size() - 3, msg.data.data(),
30 msg.data.size());
31 if (res.status != COBS_ENCODE_OK) {
32 return false;
33 }
34 tx_buf_.resize(res.out_len + 3);
35 } else {
36 tx_buf_.resize(3);
37 }
38
39 tx_buf_[0] = msg.id;
40 tx_buf_[tx_buf_.size() - 2] = checksum(tx_buf_.data(), tx_buf_.size() - 2);
41 tx_buf_[tx_buf_.size() - 1] = 0; // delimiter
42 return uart_.transmit(tx_buf_.data(), tx_buf_.size(), timeout);
43 }
44
45 bool receive(COBSBridgeMessage &msg, uint32_t timeout) {
46 uint32_t start = core::Kernel::get_ticks();
47 while (!read_to_end()) {
48 uint32_t elapsed = core::Kernel::get_ticks() - start;
49 if (elapsed >= timeout) {
50 return false;
51 }
53 }
54
55 if (rx_buf_.size() < 3) {
56 rx_buf_.clear();
57 return false;
58 }
59 if (checksum(rx_buf_.data(), rx_buf_.size() - 2) !=
60 rx_buf_[rx_buf_.size() - 2]) {
61 rx_buf_.clear();
62 return false;
63 }
64
65 if (rx_buf_.size() > 3) {
66 msg.data.resize(COBS_DECODE_DST_BUF_LEN_MAX(rx_buf_.size() - 3));
67 cobs_decode_result res =
68 cobs_decode(msg.data.data(), msg.data.size(), rx_buf_.data() + 1,
69 rx_buf_.size() - 3);
70 if (res.status != COBS_DECODE_OK) {
71 rx_buf_.clear();
72 return false;
73 }
74 msg.data.resize(res.out_len);
75 } else {
76 msg.data.resize(0);
77 }
78
79 msg.id = rx_buf_[0];
80 rx_buf_.clear();
81 return true;
82 }
83
84private:
85 peripheral::UART &uart_;
86 std::vector<uint8_t> tx_buf_;
87 std::vector<uint8_t> rx_buf_;
88
89 bool read_to_end() {
90 uint8_t tmp;
91 while (uart_.receive(&tmp, 1, 0)) {
92 rx_buf_.push_back(tmp);
93 if (tmp == 0x00) {
94 return true;
95 }
96 }
97 return false;
98 }
99
100 uint8_t checksum(const uint8_t *data, size_t size) {
101 uint8_t res = 0;
102 for (size_t i = 0; i < size; ++i) {
103 res += data[i];
104 }
105 return 0x80 | (res & 0x7F);
106 }
107};
108
109} // namespace module
110} // namespace tutrcos
static uint32_t get_ticks()
Definition kernel.hpp:14
static void delay(uint32_t ticks)
Definition thread.hpp:32
Definition cobs_bridge.hpp:20
bool receive(COBSBridgeMessage &msg, uint32_t timeout)
Definition cobs_bridge.hpp:45
COBSBridge(peripheral::UART &uart)
Definition cobs_bridge.hpp:22
bool transmit(const COBSBridgeMessage &msg, uint32_t timeout)
Definition cobs_bridge.hpp:24
Definition uart.hpp:51
bool receive(uint8_t *data, size_t size, uint32_t timeout)
Definition uart.hpp:85
bool transmit(const uint8_t *data, size_t size, uint32_t timeout)
Definition uart.hpp:69
Definition kernel.hpp:7
Definition cobs_bridge.hpp:15
std::vector< uint8_t > data
Definition cobs_bridge.hpp:17
uint8_t id
Definition cobs_bridge.hpp:16