Overview | Quick Start | Samples | Architecture | CoSlave | CoMaster | Listeners | Object Dictionary | Configuration | Eds2Od
CoSlave — the CANopen slave node
CoSlave (in Source/Slave/CoSlave.hpp, namespace CANoopEn) is the base class for a CANopen device node. It starts the local node and sends the boot-up message, runs all slave-side protocols (NMT, heartbeat, PDO, SDO server, SYNC, TIME, EMCY, LSS slave, indicators), and reports events through the listener interfaces.
Your device class derives from CoSlave and passes its collaborators to the constructor:
class MyDevice : public CANoopEn::CoSlave,
public CANoopEn::ICoListener,
public CANoopEn::ICoObjectDictionaryListener,
public CANoopEn::ICoSendHandlerListener
{
public:
MyDevice() : CoSlave(*this, _objectDictionary, *this, NodeId, _cobIdCia301),
_objectDictionary(*this) {}
// ... listener overrides ...
private:
static constexpr uint16_t NodeId = 10;
MyDeviceOd _objectDictionary;
CANoopEn::CoCobIdCia301 _cobIdCia301;
};
Constructor
CoSlave(ICoListener& listener,
ICoObjectDictionary& objectDictionary,
ICoSendHandlerListener& sendHandlerListener,
uint16_t nodeId,
ICoCobId& cobId);
| Parameter |
Meaning |
listener |
Receives stack events (NMT state changes, EMCY, LED indicators, …) — see ICoListener |
objectDictionary |
The node’s object dictionary — see Object dictionary |
sendHandlerListener |
Your CAN transmit hook — see ICoSendHandlerListener |
nodeId |
The local node-id (1..127) |
cobId |
COB-ID profile, normally a CoCobIdCia301 instance — see Profiles |
Methods
Lifecycle and processing
| Method |
Description |
bool Start() |
Starts the local node and sends the boot-up message. The node enters pre-operational; state changes to operational are commanded by the NMT master. |
bool Proceed(const CoCanMessage& canMessage) |
Feed every received CAN frame into the stack. |
void Proceed() |
Run the scheduler for timed functionality. Call every CoSettings::CoCycleTime ms (default 10 ms). |
Process data (CO_ENABLE_PDO)
| Method |
Description |
bool WritePdoAsync(uint16_t pdoNumber) |
Transmits the given TPDO with the current values of its mapped object dictionary entries — call it to publish a process data change to the PDO consumers. |
Emergency (CO_ENABLE_EMCY)
| Method |
Description |
bool SetError(CoEmcyErrorCode errorCode, const uint8_t* errorField = nullptr) |
Signals an error condition: sends the EMCY message, sets the error register (1001h) and records the error in the history (1003h). errorField is the optional 5-byte manufacturer-specific part. Returns false if the error code is already active. |
bool ResetError(CoEmcyErrorCode errorCode) |
Signals that a previously set error condition is resolved. |
bool ClearErrorHistory() |
Clears the error history (object 1003h). |
Time (CO_ENABLE_TIME)
| Method |
Description |
bool SendTime(uint32_t milliseconds, uint16_t days) |
Sends the TIME message (milliseconds after midnight, days since 1984-01-01). The node must be configured as time producer (object 1012h, bit 30). |
CAN controller state (CO_ENABLE_INDICATORS)
The stack computes the CiA 303-3 LED flash patterns; feed it the CAN controller state so the error LED is correct:
| Method |
Description |
void SetCanWarningLimitReached(bool reached) |
Signal that an error counter of the CAN controller reached the warning level (and false when it recovers). |
void SetCanBusOff(bool busOff) |
Signal that the CAN controller is bus-off (and false when it recovers). |
Typical main loop (bare-metal)
for (;;)
{
CANoopEn::CoCanMessage msg;
if (canDriver.ReceiveCanMessage(msg))
device.Proceed(msg);
if (cycleTimer.IsElapsed(SysTickDriver::GetTickCount())) // every 10 ms
{
device.SetCanBusOff(canDriver.IsBusOff());
device.SetCanWarningLimitReached(canDriver.IsWarningLimitReached());
device.Proceed();
}
}
Under FreeRTOS, Proceed(msg) moves into a CAN receive task and Proceed() into a periodic scheduler task; the stack is internally synchronized for this split (see Architecture — execution model).
See also