Xyntos | Logo

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


CoMaster — the CANopen master

CoMaster (in Source/Master/CoMaster.hpp, namespace CANoopEn) is the base class for a CANopen NMT master. On top of everything a node does locally (boot-up, heartbeat, EMCY, TIME, PDO — the same methods as CoSlave), it manages remote nodes: NMT lifecycle commands, heartbeat monitoring per node, SDO client access to remote object dictionaries, and LSS commissioning (CiA 305).

The constructor signature is identical to CoSlave; remote nodes are added before Start():

class MyMaster : public CANoopEn::CoMaster,
                 public CANoopEn::ICoListener,
                 public CANoopEn::ICoObjectDictionaryListener,
                 public CANoopEn::ICoSendHandlerListener
{
public:
    MyMaster() : CoMaster(*this, _objectDictionary, *this, NodeId, _cobIdCia301),
                 _objectDictionary(*this),
                 _slaveOd(*this),
                 _slaveNode(_slaveOd, SlaveNodeId)
    {
        AddRemoteNode(_slaveNode);
    }
private:
    static constexpr uint16_t NodeId = 1, SlaveNodeId = 10;
    MyMasterOd _objectDictionary;      // the master's own object dictionary
    SlaveOd _slaveOd;                  // local image of the slave's object dictionary
    CANoopEn::CoNode _slaveNode;       // remote node = node-id + OD image
    CANoopEn::CoCobIdCia301 _cobIdCia301;
};

Remote nodes: CoNode

Each remote node is described by a CoNode(ICoObjectDictionary& objectDictionary, uint16_t nodeId) — the node-id plus a local image of that node’s object dictionary. SDO reads fill this image; SDO writes send its values to the device. Register each node once with AddRemoteNode(CoNode&) (capacity: CoSettings::MaxNumberOfRemoteNodes).

Methods

Local-node methods (Start, Proceed(msg), Proceed(), SetError/ResetError/ClearErrorHistory, SendTime, WritePdoAsync(nodeId, pdoNumber), SetCanWarningLimitReached, SetCanBusOff) behave as documented for CoSlave; PDO/MPDO methods take the owning nodeId as first argument.

NMT — controlling remote nodes

Method Description
bool StartRemoteNode(uint16_t nodeId) / void StartRemoteNodes() NMT start remote node — switches the node(s) to operational.
bool StopRemoteNode(uint16_t nodeId) / void StopRemoteNodes() NMT stop remote node.
bool EnterPreOperationalRemoteNode(uint16_t nodeId) / ...RemoteNodes() NMT enter pre-operational.
bool ResetRemoteNode(uint16_t nodeId) / void ResetRemoteNodes() NMT reset node.
bool ResetCommunicationRemoteNode(uint16_t nodeId) / ...RemoteNodes() NMT reset communication.

State changes and boot-up messages of remote nodes are reported via ICoListener::OnNmtStateChange; heartbeat timeouts via OnHeartbeatTimeout.

SDO client (CO_ENABLE_SDO_CLIENT)

Method Description
bool ReadSdo(uint16_t nodeId, uint16_t index, uint16_t subIndex, bool blockTransfer = false) Reads an object from the remote device into the local OD image. Synchronous — suspends the calling task until the response arrives or CoSettings::SdoTimeoutTime elapses.
bool WriteSdo(uint16_t nodeId, uint16_t index, uint16_t subIndex, bool blockTransfer = false) Writes the value from the local OD image to the remote device. Synchronous.
bool ReadObjectDictionary(uint16_t nodeId) Reads every readable entry of the node’s OD image via SDO.
bool WriteObjectDictionary(uint16_t nodeId) Writes every writable entry of the node’s OD image via SDO — the classic “download configuration” step of the CiA 302-2 boot process.

Because these calls block, invoke them from an application task — never from the task that runs Proceed. Failed transfers are additionally reported with the abort code via OnSdoAbort.

// Typical boot sequence for a slave (compare CiA 302-2 "boot NMT slave"):
uint32_t deviceType;
if (ReadSdo(SlaveNodeId, 0x1000, 0x00))                    // read device type
    _slaveOd.GetValue(0x1000, 0x00, deviceType);           // ... and check it
WriteObjectDictionary(SlaveNodeId);                        // download configuration
StartRemoteNode(SlaveNodeId);                              // NMT start

PDO and MPDO (CO_ENABLE_PDO, CO_ENABLE_MPDO)

Method Description
bool WritePdoAsync(uint16_t nodeId, uint16_t pdoNumber) Transmits a TPDO of the given node with its currently mapped values.
bool SendMpdoDam(nodeId, pdoNumber, destinationNodeId, localIndex, localSubIndex, destinationIndex, destinationSubIndex) Sends a destination-addressing-mode MPDO (destinationNodeId 0 = broadcast to all configured consumers).
bool SendMpdoSam(nodeId, pdoNumber, localIndex, localSubIndex) Sends a source-addressing-mode MPDO.

LSS master (CO_ENABLE_LSS)

LSS commissions node-id and bit timing of slaves per CiA 305. Requests are asynchronous; responses arrive via the OnLss...Response callbacks of ICoListener.

Method Description
void SwitchLssStateGlobal(CoLssState lssState) Switches all (unselected) LSS slaves into the requested state.
void SwitchLssStateSelective(vendorId, productCode, revisionNumber, serialNumber) Selects a single slave by its identity (1018h) and switches it to configuration state → OnLssSwitchModeSelectiveConfirmed.
void ConfigureLssNodeId(uint16_t nodeId) Sets the selected slave’s node-id (1..127) → OnLssConfigureNodeIdResponse.
void ConfigureLssBitTiming(uint8_t tableSelector, uint8_t tableIndex) Sets the selected slave’s bit rate → OnLssConfigureBitTimingResponse.
void ActivateLssBitTiming(uint16_t switchDelayMs) Activates the configured bit timing after the given delay (no response per CiA 305).
void StoreLssConfiguration() Asks the selected slave to persist node-id and bit timing → OnLssStoreConfigurationResponse.
void InquireLssIdentity(CoLssCommand command) Reads one identity field of the selected slave → OnLssInquireIdentityResponse.
void InquireLssNodeId() Reads the selected slave’s current node-id → OnLssInquireNodeIdResponse.

Execution environment

CoMaster needs an OS-backed system layer (FreeRTOS, Linux, …) because the synchronous SDO calls suspend the calling task. The master samples (Samples/CanOpenMaster/{CiA401, CiA417}/FreeRTOS) show the full task split: a CAN receive task feeding Proceed(msg), a scheduler task calling Proceed() every cycle, and an NMT-master task that boots and monitors the slaves per CiA 302-2.

XYNTOS_Logo_mit_claim_weiss