HardFOC Core
API reference
Loading...
Searching...
No Matches
HfCoPortBinding.h
Go to the documentation of this file.
1
13#pragma once
14
15#include <cstddef>
16#include <cstring>
17
18#include "HfCanPort.h"
19#include "hf_co_driver.h"
20
21namespace hf::can {
22
23static_assert(sizeof(CanFrame) == sizeof(hf_co_frame_t), "CanFrame and hf_co_frame_t must match");
24static_assert(offsetof(CanFrame, id) == offsetof(hf_co_frame_t, id), "CanFrame layout");
25static_assert(offsetof(CanFrame, len) == offsetof(hf_co_frame_t, len), "CanFrame layout");
26static_assert(offsetof(CanFrame, flags) == offsetof(hf_co_frame_t, flags), "CanFrame layout");
27static_assert(offsetof(CanFrame, data) == offsetof(hf_co_frame_t, data), "CanFrame layout");
28static_assert(offsetof(CanFrame, ts_us) == offsetof(hf_co_frame_t, ts_us), "CanFrame layout");
32 "flag bits");
33
35inline void ToC(const CanFrame& in, hf_co_frame_t& out) noexcept {
36 out.id = in.id;
37 out.len = in.len;
38 out.flags = in.flags;
39 std::memcpy(out.data, in.data, sizeof(out.data));
40 out.ts_us = in.ts_us;
41}
42inline void FromC(const hf_co_frame_t& in, CanFrame& out) noexcept {
43 out.id = in.id;
44 out.len = in.len;
45 out.flags = in.flags;
46 std::memcpy(out.data, in.data, sizeof(out.data));
47 out.ts_us = in.ts_us;
48}
49
52 public:
53 CoPortBinding() = default;
55 CoPortBinding(const CoPortBinding&) = delete;
57
62 bool Attach(hf_co_driver_t* drv, uint8_t index, ICanPort& port, bool error_source) noexcept {
63 if (drv_ != nullptr || drv == nullptr) {
64 return false;
65 }
67 const PortCaps caps = port.Caps();
68 drv_ = drv;
69 index_ = index;
70 port_ = &port;
72 if (!hf_co_driver_attach_port(drv, index, &kOps, this, caps.max_len,
73 error_source ? HF_CO_PORT_ERROR_SOURCE : 0U)) {
74 drv_ = nullptr;
75 port_ = nullptr;
76 return false;
77 }
79 port.SetRxSink(&RxTrampoline, this);
80 return true;
81 }
82
84 void Detach() noexcept {
85 if (drv_ == nullptr) {
86 return;
87 }
88 port_->SetRxSink(nullptr, nullptr);
89 port_->SetTxDoneSink(nullptr, nullptr);
91 drv_ = nullptr;
92 port_ = nullptr;
93 }
94
95 ICanPort* Port() const noexcept { return port_; }
96 uint8_t Index() const noexcept { return index_; }
97
98 private:
99 static hf_co_tx_result_t SendTrampoline(void* ctx, const hf_co_frame_t* frame) {
100 auto* self = static_cast<CoPortBinding*>(ctx);
101 CanFrame f;
102 FromC(*frame, f);
103 return static_cast<hf_co_tx_result_t>(self->port_->Send(f));
104 }
105 static bool StatusTrampoline(void* ctx, hf_co_port_status_t* out) {
106 const PortStatus s = static_cast<CoPortBinding*>(ctx)->port_->Status();
107 out->state = static_cast<uint8_t>(s.state);
108 out->tec = s.tec;
109 out->rec = s.rec;
110 out->rx_overruns = s.rx_overruns;
113 return true;
114 }
115 static bool RecoverTrampoline(void* ctx) { return static_cast<CoPortBinding*>(ctx)->port_->Recover(); }
116 static bool RxTrampoline(void* ctx, const CanFrame& frame) {
117 auto* self = static_cast<CoPortBinding*>(ctx);
119 ToC(frame, f);
120 return self->backpressure_ ? hf_co_driver_rx_offer(self->drv_, self->index_, &f)
121 : hf_co_driver_rx_push(self->drv_, self->index_, &f);
122 }
123 static void TxDoneTrampoline(void* ctx) {
124 auto* self = static_cast<CoPortBinding*>(ctx);
125 hf_co_driver_tx_done(self->drv_, self->index_);
126 }
127
128 hf_co_driver_t* drv_{nullptr};
129 ICanPort* port_{nullptr};
130 uint8_t index_{0};
131 bool backpressure_{false};
132};
133
134} // namespace hf::can
void hf_co_driver_detach_port(hf_co_driver_t *drv, uint8_t index)
Definition CO_driver_hardfoc.c:227
bool hf_co_driver_rx_push(hf_co_driver_t *drv, uint8_t port, const hf_co_frame_t *frame)
Definition CO_driver_hardfoc.c:310
bool hf_co_driver_rx_offer(hf_co_driver_t *drv, uint8_t port, const hf_co_frame_t *frame)
Definition CO_driver_hardfoc.c:314
bool hf_co_driver_attach_port(hf_co_driver_t *drv, uint8_t index, const hf_co_port_ops_t *ops, void *ctx, uint8_t max_len, uint8_t flags)
Definition CO_driver_hardfoc.c:204
void hf_co_driver_tx_done(hf_co_driver_t *drv, uint8_t port)
Definition CO_driver_hardfoc.c:318
Transport-neutral CAN frame and the ICanPort interface for port bindings (EspTwaiPort,...
One ICanPort attached to one CO driver port slot.
Definition HfCoPortBinding.h:51
ICanPort * Port() const noexcept
Definition HfCoPortBinding.h:95
CoPortBinding & operator=(const CoPortBinding &)=delete
ICanPort * port_
Definition HfCoPortBinding.h:129
static bool StatusTrampoline(void *ctx, hf_co_port_status_t *out)
Definition HfCoPortBinding.h:105
static bool RxTrampoline(void *ctx, const CanFrame &frame)
Definition HfCoPortBinding.h:116
uint8_t index_
Definition HfCoPortBinding.h:130
bool backpressure_
Definition HfCoPortBinding.h:131
uint8_t Index() const noexcept
Definition HfCoPortBinding.h:96
bool Attach(hf_co_driver_t *drv, uint8_t index, ICanPort &port, bool error_source) noexcept
Attach port at slot index of drv.
Definition HfCoPortBinding.h:62
static void TxDoneTrampoline(void *ctx)
Definition HfCoPortBinding.h:123
CoPortBinding(const CoPortBinding &)=delete
hf_co_driver_t * drv_
Definition HfCoPortBinding.h:128
void Detach() noexcept
Stop RX delivery and detach the slot.
Definition HfCoPortBinding.h:84
static bool RecoverTrampoline(void *ctx)
Definition HfCoPortBinding.h:115
static hf_co_tx_result_t SendTrampoline(void *ctx, const hf_co_frame_t *frame)
Definition HfCoPortBinding.h:99
~CoPortBinding()
Definition HfCoPortBinding.h:54
One CAN transport binding.
Definition HfCanPort.h:106
virtual bool RxBackpressure() const
True if the port holds a frame the RX sink refused and offers it again (no loss).
Definition HfCanPort.h:121
virtual void SetRxSink(RxSink sink, void *ctx)=0
Install the RX sink (nullptr detaches).
virtual void SetTxDoneSink(TxDoneSink sink, void *ctx)
Install the TX-done sink. Ports without a TX-done event ignore it.
Definition HfCanPort.h:123
virtual bool Recover()=0
Request bus-off recovery; false when not possible now.
virtual PortStatus Status() const =0
Error counters and state.
C interface of the generic CANopenNode driver (CO_driver_hardfoc.c).
#define HF_CO_FRAME_ESI
Definition hf_co_driver.h:101
hf_co_tx_result_t
Definition hf_co_driver.h:115
#define HF_CO_FRAME_RTR
Definition hf_co_driver.h:98
#define HF_CO_FRAME_EXT
Definition hf_co_driver.h:97
#define HF_CO_FRAME_FDF
Definition hf_co_driver.h:99
#define HF_CO_FRAME_BRS
Definition hf_co_driver.h:100
#define HF_CO_PORT_ERROR_SOURCE
Definition hf_co_driver.h:152
constexpr uint8_t kFdf
FD frame format.
Definition HfCanPort.h:42
constexpr uint8_t kBrs
bit-rate switch (FD only)
Definition HfCanPort.h:43
constexpr uint8_t kEsi
error state indicator (FD only)
Definition HfCanPort.h:44
constexpr uint8_t kRtr
remote request (classic only)
Definition HfCanPort.h:41
constexpr uint8_t kExt
29-bit identifier
Definition HfCanPort.h:40
Definition EspTwaiPort.cpp:12
void FromC(const hf_co_frame_t &in, CanFrame &out) noexcept
Definition HfCoPortBinding.h:42
void ToC(const CanFrame &in, hf_co_frame_t &out) noexcept
Copy between the C++ and C frame types (identical layout).
Definition HfCoPortBinding.h:35
One CAN or CAN FD frame; len is a byte count, never a DLC code.
Definition HfCanPort.h:49
What a port binding can carry.
Definition HfCanPort.h:76
uint8_t max_len
Definition HfCanPort.h:78
Error counters and statistics of one port.
Definition HfCanPort.h:91
uint32_t bus_off_count
Definition HfCanPort.h:97
uint32_t rx_overruns
Definition HfCanPort.h:95
uint32_t tx_queue_full
Definition HfCanPort.h:96
uint16_t tec
Definition HfCanPort.h:93
uint16_t rec
Definition HfCanPort.h:94
BusState state
Definition HfCanPort.h:92
Definition hf_co_driver.h:104
Definition hf_co_driver.h:142
Definition hf_co_driver.h:132
uint32_t rx_overruns
Definition hf_co_driver.h:136
uint16_t tec
Definition hf_co_driver.h:134
uint8_t state
Definition hf_co_driver.h:133
uint16_t rec
Definition hf_co_driver.h:135
uint32_t tx_queue_full
Definition hf_co_driver.h:137
uint32_t bus_off_count
Definition hf_co_driver.h:138