Architecture¶
How the driver is put together: three layers, one of them yours, and what happens on one call.
Figure description and sources
From top to bottom. Your application calls a VortexHostSession (its public methods are listed from inc/vortex/VortexHostSession.hpp). The session encodes CANopen NMT and expedited SDO download frames as VortexCanFrame values and hands each to the VortexCanTransport interface (its pure-virtual methods are listed from inc/vortex/VortexCanTransport.hpp). Your transport class implements that interface with BaseCan, SocketCAN or a test loopback, and puts the frame on a classic CAN bus. The Vortex device on the bus is the CANopen server.
Drawn from: inc/vortex/VortexHostSession.hpp VortexHostSession; inc/vortex/VortexCanTransport.hpp VortexCanTransport; inc/vortex/VortexProtocol.hpp NmtCommand; figure module docs/diagrams/figures/driver-layers.py.
Layers¶
| Layer | Files | Role |
|---|---|---|
| Session | inc/vortex/VortexHostSession.hpp, src/VortexHostSession.cpp |
Encodes NMT and expedited SDO download frames; holds only a reference to the transport |
| Protocol | inc/vortex/VortexProtocol.hpp, inc/vortex/VortexCanFrame.hpp |
NmtCommand, object constants, the classic CAN frame type |
| Transport interface | inc/vortex/VortexCanTransport.hpp |
One pure-virtual method, send() |
| Your transport | your code | Puts a VortexCanFrame on a real bus (BaseCan, SocketCAN) or records it (tests) |
One call through the layers¶
sequenceDiagram
participant App as Your code
participant S as VortexHostSession
participant T as Your transport
participant C as CAN controller
App->>S: sdoDownloadExpedited(5, 0x6060, 0, 3, 1)
S->>S: size check, makeSdoDownload(): ID 0x605, 2F 60 60 00 03 00 00 00
S->>T: send(frame)
T->>C: queue the frame (e.g. BaseCan::TrySendMessage)
C-->>T: queued / queue full / bus-off
T-->>App: true or false
Design choices¶
- A virtual interface, not a template. The transport is a runtime object, like the BNO08x and TMC9660 transports elsewhere in HardFOC. One virtual call per frame is negligible next to the time an 8-byte frame takes on the wire (roughly 0.25 ms at 500 kbit/s).
- No heap, no threads, no RTOS. The session is one reference; frames are built on the stack.
- Transmit only. Receiving needs a thread or a callback, a filter and timeouts, which belong to the application or to a CANopen stack. The session stays a pure encoder.
- Same bytes as hf-utils-canopen.
VortexCanFramehas the same fields asCanFramein hf-utils-canopen, and the NMT and SDO download encodings are the same CiA 301 layouts, so a field-by-field copy converts between them.
Where it sits in HardFOC¶
| Layer | Repository | Uses this driver for |
|---|---|---|
| Driver collection | hf-core-drivers | Carries it as external/hf-vortex-driver |
| CANopen glue | hf-core handlers/common/canopen/ |
BaseCan links and the CANopenNode driver for the device side |
| Device firmware | hf-hal-vortex-v1 | The Vortex board this driver talks to |
Next: API guide.