Dawn Framework 1.0
Universal data acquisition framework for embedded systems
can.hxx
1// dawn/include/dawn/proto/can/can.hxx
2//
3// SPDX-License-Identifier: Apache-2.0
4//
5
6#pragma once
7
8#include <poll.h>
9#include <vector>
10
11#include "dawn/common/thread.hxx"
12#include "dawn/porting/config.hxx"
13#include "dawn/proto/common.hxx"
14#include "dawn/proto/can/isotp.hxx"
15
16#if defined(CONFIG_DAWN_PROTO_CAN_SEG) || defined(CONFIG_DAWN_PROTO_CAN_SINGLE_ID)
17# define DAWN_PROTO_HAS_ISOTP
18#endif
19
20namespace dawn
21{
22// Forward declaration
23
24struct io_ddata_t;
25
34 : public CProtoCommon
35 , protected CThreadedObject
36{
37public:
38 enum
39 {
45 };
46
47 enum
48 {
56 };
57
58 struct
59 {
60 uint32_t type;
61 uint32_t start;
62 uint32_t size;
63 uint32_t objid[];
64 } typedef SProtoCanIOBind;
65
66 explicit CProtoCan(CDescObject &desc)
67 : CProtoCommon(desc)
68 , devno(getPriv())
69 , nodeid(CONFIG_DAWN_PROTO_CAN_NODEID)
70 , fd(-1)
71 , initialized(false)
72 {
73 }
74
75 ~CProtoCan() override;
76
77#ifdef CONFIG_DAWN_OBJECT_HAS_NAME
78 const char *getClassNameStr() const override
79 {
80 return "can";
81 }
82#endif
83
84 int configure() override;
85 int init() override;
86 int deinit() override;
87 int doStart() override;
88 int doStop() override;
89 bool hasThread() const override;
90
91 constexpr static SObjectId::ObjectId objectId(uint16_t id)
92 {
95 }
96
97 constexpr static SObjectCfg::ObjectCfgId cfgId(bool rw, uint8_t dtype, uint8_t size, uint8_t id)
98 {
101 }
102
103 constexpr static SObjectCfg::ObjectCfgId cfgIdIOBind(uint16_t size)
104 {
105 return CProtoCan::cfgId(false, SObjectId::DTYPE_ANY, size, PROTO_CAN_CFG_IOBIND);
106 }
107
108 constexpr static SObjectCfg::ObjectCfgId cfgIdDevno()
109 {
110 return CProtoCan::cfgId(true, SObjectId::DTYPE_UINT32, 1, PROTO_CAN_CFG_DEVNO);
111 }
112
113 constexpr static SObjectCfg::ObjectCfgId cfgIdNodeid()
114 {
115 return CProtoCan::cfgId(true, SObjectId::DTYPE_UINT32, 1, PROTO_CAN_CFG_NODEID);
116 }
117
118private:
119 struct
120 {
121 CProtoCan *proto;
122 CIOCommon *io;
123 uint16_t canid;
124 io_ddata_t *iodata;
125 size_t data_len;
126#ifdef DAWN_PROTO_HAS_ISOTP
127 CIsoTp::State *isotp;
128#endif
129 } typedef SCanIoData;
130
131#ifdef DAWN_PROTO_HAS_ISOTP
132 struct
133 {
134 CIsoTp::State isotp;
135 size_t io_idx;
136 size_t io_off;
137 } typedef SProtoCanWriteAll;
138#endif
139
140 struct
141 {
142 const SProtoCanIOBind *cfg;
143 size_t ios;
144 SCanIoData *io;
145#ifdef CONFIG_DAWN_PROTO_CAN_SINGLE_ID
146 SProtoCanWriteAll *write_all;
147#endif
148 } typedef SProtoCanRegs;
149
150 char path[PATH_MAX] = {}; // CAN device path string (e.g. "/dev/can0")
151 uint8_t devno; // CAN device number (0 = can0, 1 = can1, etc.)
152 uint16_t nodeid; // CAN node ID base address for I/O mapping.
153 int fd; // File descriptor for CAN socket.
154 bool initialized; // Initialization completion flag
155
156 std::vector<SProtoCanIOBind *> valloc; // Vector of I/O bindings (from descriptor).
157 std::vector<SProtoCanRegs *> vregs; // Vector of register groups.
158
159 int configureDesc(const CDescObject &desc);
160 void allocObject(SProtoCanIOBind *alloc);
161 void thread();
162 int createRegs();
163 int validateCanIo(const SProtoCanIOBind *v, CIOCommon *io, SCanIoData *canio);
164 int createRegsForGroup(SProtoCanIOBind *v);
165 int destroyRegs();
166 int canInitialize();
167 int msgRecv(const dawn::porting::canmsg_s &msg);
168#ifdef DAWN_PROTO_HAS_ISOTP
169 int sendSegmented(uint16_t canid,
170 const uint8_t *data,
171 size_t len,
172 bool with_index,
173 uint8_t index);
174 int sendSegmentedRead(SCanIoData *canio,
175 size_t len,
176 bool with_index,
177 uint8_t index,
178 size_t offset = 0);
179#endif
180 int sendIoResponse(SCanIoData *canio, uint8_t index, bool segmented);
181#ifdef CONFIG_DAWN_PROTO_CAN_SINGLE_ID
182 int handleSingleIdGroup(const dawn::porting::canmsg_s &msg, SProtoCanRegs *v);
183 int handleSingleIdReadAll(const dawn::porting::canmsg_s &msg,
184 SProtoCanRegs *v,
185 bool ignore_len = false);
186 int handleSingleIdWriteAll(const dawn::porting::canmsg_s &msg,
187 SProtoCanRegs *v,
188 uint8_t seg_no,
189 bool seg_last);
190 int handleSingleIdIndex(const dawn::porting::canmsg_s &msg,
191 SProtoCanRegs *v,
192 uint8_t index,
193 uint8_t seg_no,
194 bool seg_last);
195#endif
196 int handleLegacyGroup(const dawn::porting::canmsg_s &msg, SProtoCanRegs *v);
197
198 static int beforePoll(void *priv, struct pollfd *pfds, nfds_t nfds);
199 static void afterPoll(void *priv, struct pollfd *pfds, nfds_t nfds, int ret);
200 static int onPollReady(void *priv, struct pollfd *pfds, nfds_t nfds, int pollRet);
201 static int notifierCb(void *priv, io_ddata_t *data);
202};
203
204} // Namespace dawn
uint16_t getPriv() const
Get instance/private data field.
Definition object.cxx:185
int start()
Start object.
Definition object.hxx:116
CAN bus protocol for industrial automation.
Definition can.hxx:36
int deinit()
De-initialize object.
Definition can.cxx:232
@ CAN_TYPE_READ_SEG
segmented response, requested by data frame
Definition can.hxx:54
@ CAN_TYPE_WRITE_SEG
segmented request
Definition can.hxx:55
@ CAN_TYPE_PUSH
device autonomously sends data
Definition can.hxx:49
@ CAN_TYPE_INDEXED_WRITE
indexed request/response
Definition can.hxx:53
@ CAN_TYPE_INDEXED_READ
indexed request/response
Definition can.hxx:52
@ CAN_TYPE_READ
request/response with RTR frame
Definition can.hxx:50
@ CAN_TYPE_WRITE
master sends command
Definition can.hxx:51
int configure()
Configure object from descriptor data.
Definition can.cxx:198
int init()
One-time initialize object after bindings are resolved.
Definition can.cxx:212
int doStop()
Stop implementation hook.
Definition can.cxx:250
bool hasThread() const
Check if a background thread is active.
Definition can.cxx:255
int doStart()
Start implementation hook.
Definition can.cxx:245
@ PROTO_CAN_CFG_DEVNO
CAN device number (0=can0)
Definition can.hxx:42
@ PROTO_CAN_CFG_IOBIND
I/O object binding.
Definition can.hxx:41
@ PROTO_CAN_CFG_FIRST
Reserved.
Definition can.hxx:40
@ PROTO_CAN_CFG_NODEID
CAN node ID base address.
Definition can.hxx:43
@ PROTO_CAN_CFG_LAST
Reserved.
Definition can.hxx:44
Base class for all protocol implementations.
Definition common.hxx:23
@ PROTO_CLASS_CAN
CAN bus protocol.
Definition common.hxx:75
Portable thread owner abstraction for Dawn components.
Definition thread.hxx:32
static ObjectCfgId objectCfg(uint8_t type, uint16_t cls, uint8_t dtype, bool rw, uint16_t size, uint8_t id)
Construct 32-bit ConfigID from component fields.
uint32_t ObjectCfgId
ConfigID type - single 32-bit value.
Definition objectcfg.hxx:60
Out-of-tree user-extension hooks for Dawn.
Definition bindable.hxx:13
@ OBJTYPE_PROTO
Protocol object type.
Definition objectid.hxx:193
@ DTYPE_ANY
Wildcard data type (matches any actual type).
Definition objectid.hxx:68
@ DTYPE_UINT32
Unsigned 32-bit integer (0 to 4294967295).
Definition objectid.hxx:96
uint32_t ObjectId
ObjectID type - single 32-bit value.
Definition objectid.hxx:44
static ObjectId objectId(uint8_t type, uint16_t cls, uint8_t dtype, uint8_t flags, uint16_t priv)
Construct 32-bit ObjectID from component fields.
Definition objectid.hxx:290
Common CAN message format for chardev and socketCAN.
Definition can.hxx:20