Xyntos | Logo

Overview  |  Quick Start  |  Samples  |  Architecture  |  CoSlave  |  CoMaster  |  Listeners  |  Object Dictionary  |  Configuration  |  Eds2Od


Configuration, profiles and porting

Everything build-time-configurable lives in Source/Settings/; the platform binding lives in Source/System/. The samples keep per-project copies of the two settings files, so each device tunes the stack independently.

CoConfiguration — feature switches

Source/Settings/CoConfiguration.hpp compiles services in or out. Every switch defaults to enabled; override on the compiler command line (preferred, e.g. -DCO_ENABLE_LSS=0) or in a project-local copy. Disabling a service removes its code from the link and removes its callbacks from ICoListener. Dependencies resolve automatically (no master → no SDO client, no PDO → no MPDO, …).

Switch Controls
CO_ENABLE_MASTER / CO_ENABLE_SLAVE The CoMaster / CoSlave role — disable whichever this build never instantiates.
CO_ENABLE_HEARTBEAT Heartbeat producer/consumer (1016h/1017h), OnHeartbeatTimeout.
CO_ENABLE_SYNC SYNC producer/consumer (1005h/1006h/1019h), OnSync.
CO_ENABLE_TIME TIME producer/consumer (1012h), OnTime.
CO_ENABLE_EMCY EMCY producer/consumer (1001h/1003h/1014h/1015h), OnEmergency.
CO_ENABLE_PDO PDO transmit and receive.
CO_ENABLE_MPDO Multiplexed PDOs (SAM/DAM).
CO_ENABLE_SDO_SERVER SDO server — without it the device cannot be configured or read by a master.
CO_ENABLE_SDO_CLIENT SDO client (master only).
CO_ENABLE_SDO_BLOCK_TRANSFER SDO block transfer — a pure throughput optimization, first candidate on a tight flash budget.
CO_ENABLE_LSS LSS (CiA 305) — skippable when node-id and bit rate are fixed (e.g. DIP switches).
CO_ENABLE_INDICATORS CiA 303-3 run/error LED patterns, OnIndicatorChanged.

NMT is always included — every CANopen node needs it.

CoSettings — sizing constants

Source/Settings/CoSettings.hpp statically sizes all tables and buffers (defaults in parentheses):

Constant Meaning
CoCycleTime (10) Stack cycle time in ms — the period at which you call Proceed().
SdoTimeoutTime (2000) SDO transfer timeout in ms.
MaxNumberOfOdEntries (100) Capacity of an object dictionary.
MaxNumberOfRemoteNodes (5) Remote node table of a master.
MaxNumberOfSdoChannels (4) Concurrently active SDO channels.
MaxStringLength (100) Largest string an SDO channel can carry.
SdoBlocTransferUseCrc (true), MaxSdoBlockSize (127), SdoProtocolSwitchThreshold (28) Block transfer tuning.
MaxNumberOfRpdoMappingParameters (9) / MaxNumberOfTpdoMappingParameters (5) PDO mappings per dictionary.
MaxNumberOfPdoMappingParameterEntries (8) Mapped objects per PDO (a PDO carries at most 8 bytes).
MaxNumberOfEmcyErrors (8) Concurrently tracked active EMCY errors.

Profiles

The mapping from protocol to CAN identifier sits behind ICoCobId — the profile is a constructor argument of your device, not a build variant of the stack.

CiA 301 — CoCobIdCia301

Source/Common/CoCobIdCia301.hpp implements the pre-defined connection set of CiA 301 (SDO at 600h/580h + node-id, TPDO1 at 180h + node-id, …). This is the default for general CANopen devices:

CANoopEn::CoCobIdCia301 _cobId;

CiA 417 — the lift application profile

Source/Profiles/CiA417/ supports CANopen Lift devices:

  • CoCobIdCia417 — the CiA 417 COB-ID mapping; constructed with the node-id: CoCobIdCia417 _cobId(nodeId);
  • CoCia417 — the profile’s constants: device profile number 417, the profile object indices (6000h virtual device types, 6003h floor number, 6010h/6011h virtual I/O mapping, 6100h call input groups, 6108h fire inputs, output objects 6200h/6210h/6218h/6219h/62B0h/62B1h), virtual device types, basic/sub function codes, door and panel designators.
  • CoCia417VirtualMapping — encodes/decodes the 32-bit virtual I/O mapping values (basic function, sub function, lift, panel, door, function data): construct from fields or FromValue(...), compare with Matches(...), read with GetBasicFunction(), IsStatusOn(), etc.

The Samples/CanOpenClient/CiA417 projects show a complete lift call panel node, and the Samples/CanOpenMaster/CiA417 projects the matching lift call controller, built from these pieces. Pressing the panel’s user button registers a hall call with the call controller; pressing the call controller’s button answers with the call acknowledgement — each shown on the blue led of the other device.

This is what the round trip of the two sample boards looks like to a standard CANopen lift analyzer — here the Toolbox from Thor Engineering (panel = node 10, call controller 1 = node 1):

16:00:22.431  NMT-Command 'Start Remote Node' for node 10
16:00:22.804  Node   10, NMT-State operational
16:00:33.644  Node   10, Lift   1, Hall call, up, floor 1, door A, on  <02-01-01-01-11-01>
16:00:34.243  Node   10, Lift   1, Hall call, up, floor 1, door A, off <02-01-01-01-11-00>
16:00:38.155  Node    1, Lift   1, Hall call acknowledge, up, floor 1, door A, on  <02-01-01-01-11-01>
16:00:38.515  Node    1, Lift   1, Hall call acknowledge, up, floor 1, door A, off <02-01-01-01-11-00>

Porting the system layer

Source/System/ declares two primitives the stack synchronizes with; the application supplies the implementation (.cpp) matching its platform — that is the entire OS port:

  • CoSemaphore(count) — counting semaphore: Pend(timeoutMs) (0 = wait forever, returns false on timeout), Post(), Set(count). Guards the object dictionary and internal state.
  • CoEvent() — event object: Wait(timeoutMs), Pulse() (signal and resume waiters), Set(), Reset(). Used to suspend the caller of synchronous SDO transfers.

Ready-made implementations ship with the samples under Source/CANoopEn/System/:

Platform Implementation
Bare-metal Trivial (single context, no suspension) — CanOpenClient/CiA401/BareMetal
FreeRTOS Semaphores/event groups — the FreeRTOS samples

Copy the matching pair into your project (they are application code, not stack code). Note that CoMaster‘s synchronous SDO calls require a real OS implementation; a pure bare-metal port supports the slave role.

Compiler requirements

C++17, no RTTI/exceptions required, no dynamic allocation. The samples build with Arm GCC (Cortex-M) and MSVC (unit tests) from the same sources.

XYNTOS_Logo_mit_claim_weiss