Overview | Quick Start | Samples | Architecture | CoSlave | CoMaster | Listeners | Object Dictionary | Configuration | Eds2Od
The stack communicates with your application exclusively through three small interfaces. Your device class typically implements all three (multiple inheritance next to CoSlave/CoMaster) and passes *this to the constructor — but they can just as well live in separate objects.
Source/Common/ICoSendHandlerListener.hpp — the stack’s only way out to the hardware:
virtual bool SendCanMessage(const CANoopEn::CoCanMessage& canMessage) = 0;
Forward the frame to your CAN driver and return true on success. This is the complete CAN driver binding — reception is your side calling Proceed(msg).
Source/ObjectDictionary/ICoObjectDictionaryListener.hpp — passed to your CoObjectDictionary:
virtual void OnValueChanged(uint16_t nodeId, uint16_t index, uint16_t subIndex) = 0;
Called whenever an object’s value changes — e.g. a received RPDO wrote the digital outputs, or a remote SDO write changed a parameter. This is where your application reacts to incoming process values:
void MyDevice::OnValueChanged(uint16_t nodeId, uint16_t index, uint16_t subIndex)
{
if (index == 0x6200 && subIndex == 0x01) // digital outputs written via RPDO
{
uint8_t outputs;
_objectDictionary.GetValue(index, subIndex, outputs);
LedDriver::Set(outputs);
}
}
Source/Common/ICoListener.hpp — all stack events. Callbacks belonging to a disabled feature (CoConfiguration) disappear from the interface, so a minimal build only implements what remains.
| Callback | When |
|---|---|
OnDebugOutput(const char* formatSpecifiers, ...) |
The stack traces an event (printf-style). Route it to a UART/log, or leave the body empty. |
OnNmtStateChange(uint16_t nodeId, CoNmtState nmtState) |
A node’s NMT state changed — the local node on NMT commands, remote nodes (master) on boot-up/heartbeat evaluation. |
OnNmtCommand(uint16_t nodeId, CoNmtCommand nmtCommand) |
An NMT command was processed. |
| Callback | Switch | When |
|---|---|---|
OnIndicatorChanged(bool errorLedState, bool runLedState) |
CO_ENABLE_INDICATORS |
The CiA 303-3 flash patterns (flickering, blinking, single/double/triple flash) are computed by the stack; you receive the resulting physical on/off state — just drive the two LED outputs. |
OnHeartbeatTimeout(uint16_t nodeId) |
CO_ENABLE_HEARTBEAT |
A monitored node’s heartbeat stayed away longer than its consumer heartbeat time. |
OnSdoAbort(uint16_t nodeId, CoSdoAbortCode abortCode, uint16_t index, uint16_t subIndex) |
SDO server or client | An SDO transfer was aborted (either side). |
OnEmergency(uint16_t nodeId, CoEmcyErrorCode errorCode, uint8_t errorRegister, const uint8_t* errorField) |
CO_ENABLE_EMCY |
An EMCY message was received (errorField: 5 manufacturer-specific bytes). |
OnSync(uint16_t nodeId, uint8_t counter) |
CO_ENABLE_SYNC |
A SYNC message was processed (counter 0 if the message carried none). |
OnTime(uint16_t nodeId, uint32_t milliseconds, uint16_t days) |
CO_ENABLE_TIME |
A TIME message was received (ms after midnight, days since 1984-01-01). |
CO_ENABLE_LSS)Slave-role requests — the application must actually perform what was requested:
| Callback | When |
|---|---|
OnLssConfigureBitTimingRequest(uint16_t nodeId, uint8_t tableSelector, uint8_t tableIndex) |
The node’s bit timing was configured via LSS; apply the new bit rate to your CAN controller. |
OnLssStoreConfigurationRequest(uint16_t nodeId) |
The node shall persist its LSS configuration; write it to non-volatile memory. |
Master-role responses to the CoMaster LSS requests:
| Callback | Answers |
|---|---|
OnLssSwitchModeSelectiveConfirmed(uint16_t nodeId) |
SwitchLssStateSelective |
OnLssConfigureNodeIdResponse(uint16_t nodeId, uint8_t errorCode) |
ConfigureLssNodeId (0 = success) |
OnLssConfigureBitTimingResponse(uint16_t nodeId, uint8_t errorCode) |
ConfigureLssBitTiming (0 = success) |
OnLssStoreConfigurationResponse(uint16_t nodeId, uint8_t errorCode) |
StoreLssConfiguration (0 = success) |
OnLssInquireIdentityResponse(uint16_t nodeId, CoLssCommand command, uint32_t value) |
InquireLssIdentity |
OnLssInquireNodeIdResponse(uint16_t nodeId, uint8_t responseNodeId) |
InquireLssNodeId |
Source/Common/CoCanMessage.hpp — the frame type used on both sides of the driver boundary. Constructors take the CAN identifier and up to eight data bytes; accessors: GetId/SetId, GetRtr/SetRtr, GetDataLength/SetDataLength, GetData(byteNumber)/SetData(byteNumber, value), Clear. Converting between CoCanMessage and your CAN controller’s frame format is a few lines in the driver (see the sample CanDriver implementations).
