CANopenNode
SDO server

Files

file  CO_SDOserver.h
 CANopen Service Data Object - server protocol.
 

Data Structures

struct  CO_SDOserver_t
 SDO server object. More...
 

Macros

#define CO_SDO_ST_FLAG_DOWNLOAD   0x10U
 Internal state flags indicate type of transfer. More...
 

Enumerations

enum  CO_SDO_state_t {
  CO_SDO_ST_IDLE = 0x00U, CO_SDO_ST_ABORT = 0x01U, CO_SDO_ST_DOWNLOAD_LOCAL_TRANSFER = 0x10U, CO_SDO_ST_DOWNLOAD_INITIATE_REQ = 0x11U,
  CO_SDO_ST_DOWNLOAD_INITIATE_RSP = 0x12U, CO_SDO_ST_DOWNLOAD_SEGMENT_REQ = 0x13U, CO_SDO_ST_DOWNLOAD_SEGMENT_RSP = 0x14U, CO_SDO_ST_UPLOAD_LOCAL_TRANSFER = 0x20U,
  CO_SDO_ST_UPLOAD_INITIATE_REQ = 0x21U, CO_SDO_ST_UPLOAD_INITIATE_RSP = 0x22U, CO_SDO_ST_UPLOAD_SEGMENT_REQ = 0x23U, CO_SDO_ST_UPLOAD_SEGMENT_RSP = 0x24U,
  CO_SDO_ST_DOWNLOAD_BLK_INITIATE_REQ = 0x51U, CO_SDO_ST_DOWNLOAD_BLK_INITIATE_RSP = 0x52U, CO_SDO_ST_DOWNLOAD_BLK_SUBBLOCK_REQ = 0x53U, CO_SDO_ST_DOWNLOAD_BLK_SUBBLOCK_RSP = 0x54U,
  CO_SDO_ST_DOWNLOAD_BLK_END_REQ = 0x55U, CO_SDO_ST_DOWNLOAD_BLK_END_RSP = 0x56U, CO_SDO_ST_UPLOAD_BLK_INITIATE_REQ = 0x61U, CO_SDO_ST_UPLOAD_BLK_INITIATE_RSP = 0x62U,
  CO_SDO_ST_UPLOAD_BLK_INITIATE_REQ2 = 0x63U, CO_SDO_ST_UPLOAD_BLK_SUBBLOCK_SREQ = 0x64U, CO_SDO_ST_UPLOAD_BLK_SUBBLOCK_CRSP = 0x65U, CO_SDO_ST_UPLOAD_BLK_END_SREQ = 0x66U,
  CO_SDO_ST_UPLOAD_BLK_END_CRSP = 0x67U
}
 Internal states of the SDO state machine. More...
 
enum  CO_SDO_abortCode_t {
  CO_SDO_AB_NONE = 0x00000000UL, CO_SDO_AB_TOGGLE_BIT = 0x05030000UL, CO_SDO_AB_TIMEOUT = 0x05040000UL, CO_SDO_AB_CMD = 0x05040001UL,
  CO_SDO_AB_BLOCK_SIZE = 0x05040002UL, CO_SDO_AB_SEQ_NUM = 0x05040003UL, CO_SDO_AB_CRC = 0x05040004UL, CO_SDO_AB_OUT_OF_MEM = 0x05040005UL,
  CO_SDO_AB_UNSUPPORTED_ACCESS = 0x06010000UL, CO_SDO_AB_WRITEONLY = 0x06010001UL, CO_SDO_AB_READONLY = 0x06010002UL, CO_SDO_AB_NOT_EXIST = 0x06020000UL,
  CO_SDO_AB_NO_MAP = 0x06040041UL, CO_SDO_AB_MAP_LEN = 0x06040042UL, CO_SDO_AB_PRAM_INCOMPAT = 0x06040043UL, CO_SDO_AB_DEVICE_INCOMPAT = 0x06040047UL,
  CO_SDO_AB_HW = 0x06060000UL, CO_SDO_AB_TYPE_MISMATCH = 0x06070010UL, CO_SDO_AB_DATA_LONG = 0x06070012UL, CO_SDO_AB_DATA_SHORT = 0x06070013UL,
  CO_SDO_AB_SUB_UNKNOWN = 0x06090011UL, CO_SDO_AB_INVALID_VALUE = 0x06090030UL, CO_SDO_AB_VALUE_HIGH = 0x06090031UL, CO_SDO_AB_VALUE_LOW = 0x06090032UL,
  CO_SDO_AB_MAX_LESS_MIN = 0x06090036UL, CO_SDO_AB_NO_RESOURCE = 0x060A0023UL, CO_SDO_AB_GENERAL = 0x08000000UL, CO_SDO_AB_DATA_TRANSF = 0x08000020UL,
  CO_SDO_AB_DATA_LOC_CTRL = 0x08000021UL, CO_SDO_AB_DATA_DEV_STATE = 0x08000022UL, CO_SDO_AB_DATA_OD = 0x08000023UL, CO_SDO_AB_NO_DATA = 0x08000024UL
}
 SDO abort codes. More...
 
enum  CO_SDO_return_t {
  CO_SDO_RT_waitingLocalTransfer = 6, CO_SDO_RT_uploadDataBufferFull = 5, CO_SDO_RT_transmittBufferFull = 4, CO_SDO_RT_blockDownldInProgress = 3,
  CO_SDO_RT_blockUploadInProgress = 2, CO_SDO_RT_waitingResponse = 1, CO_SDO_RT_ok_communicationEnd = 0, CO_SDO_RT_wrongArguments = -2,
  CO_SDO_RT_endedWithClientAbort = -9, CO_SDO_RT_endedWithServerAbort = -10
}
 Return values from SDO server or client functions. More...
 

Functions

CO_ReturnError_t CO_SDOserver_init (CO_SDOserver_t *SDO, const OD_t *OD, const OD_entry_t *OD_1200_SDOsrvPar, uint8_t nodeId, uint16_t SDOtimeoutTime_ms, CO_CANmodule_t *CANdevRx, uint16_t CANdevRxIdx, CO_CANmodule_t *CANdevTx, uint16_t CANdevTxIdx)
 Initialize SDO object. More...
 
void CO_SDOserver_initCallbackPre (CO_SDOserver_t *SDO, void *object, void(*pFunctSignalPre)(void *object))
 Initialize SDOrx callback function. More...
 
CO_SDO_return_t CO_SDOserver_process (CO_SDOserver_t *SDO, bool_t NMTisPreOrOperational, uint32_t timeDifference_us, uint32_t *timerNext_us)
 Process SDO communication. More...
 

Detailed Description

CANopen Service Data Object - server protocol.

Service data objects (SDOs) allow the access to any entry of the CANopen Object dictionary. By SDO a peer-to-peer communication channel between two CANopen devices is established. In addition, the SDO protocol enables to transfer any amount of data in a segmented way. Therefore the SDO protocol is mainly used in order to communicate configuration data.

All CANopen devices must have implemented SDO server and first SDO server channel. Servers serves data from Object dictionary. Object dictionary is a collection of variables, arrays or records (structures), which can be used by the stack or by the application. This file (CO_SDOserver.h) implements SDO server.

SDO client can be (optionally) implemented on one (or multiple, if multiple SDO channels are used) device in CANopen network. Usually this is master device and provides also some kind of user interface, so configuration of the network is possible. Code for the SDO client is in file CO_SDOclient.h.

SDO communication cycle is initiated by the client. Client can upload (read) data from device or can download (write) data to device. If data size is less or equal to 4 bytes, communication is finished by one server response (expedited transfer). If data size is longer, data are split into multiple segments of request/response pairs (normal or segmented transfer). For longer data there is also a block transfer protocol, which transfers larger block of data in secure way with little protocol overhead. If error occurs during SDO transfer CO_SDO_abortCode_t is send by client or server and transfer is terminated. For more details see CO_SDO_state_t.

Access to Object dictionary is specified in OD interface.

Macro Definition Documentation

◆ CO_SDO_ST_FLAG_DOWNLOAD

#define CO_SDO_ST_FLAG_DOWNLOAD   0x10U

Internal state flags indicate type of transfer.

These flags correspond to the upper nibble of the SDO state machine states and can be used to determine the type of state an SDO object is in.

Enumeration Type Documentation

◆ CO_SDO_state_t

Internal states of the SDO state machine.

Upper nibble of byte indicates type of state: 0x10: Download 0x20: Upload 0x40: Block Mode

Note: CANopen has little endian byte order.

Enumerator
CO_SDO_ST_IDLE 
  • SDO client may start new download to or upload from specified node, specified index and specified subindex. It can start normal or block communication.
  • SDO server is waiting for client request.
CO_SDO_ST_ABORT 
  • SDO client or server may send SDO abort message in case of error:
    • byte 0: 10000000 binary.
    • byte 1..3: Object index and subIndex.
    • byte 4..7: CO_SDO_abortCode_t.
CO_SDO_ST_DOWNLOAD_LOCAL_TRANSFER 
  • SDO client: Node-ID of the SDO server is the same as node-ID of this node, SDO client is the same device as SDO server. Transfer data directly without communication on CAN.
  • SDO server does not use this state.
CO_SDO_ST_DOWNLOAD_INITIATE_REQ 
  • SDO client initiates SDO download:
    • byte 0: 0010nnes binary: (nn: if e=s=1, number of data bytes, that do not contain data; e=1 for expedited transfer; s=1 if data size is indicated.)
    • byte 1..3: Object index and subIndex.
    • byte 4..7: If e=1, expedited data are here. If e=0 s=1, size of data for segmented transfer is indicated here.
  • SDO server is in CO_SDO_ST_IDLE state and waits for client request.
CO_SDO_ST_DOWNLOAD_INITIATE_RSP 
  • SDO client waits for response.
  • SDO server responses:
    • byte 0: 01100000 binary.
    • byte 1..3: Object index and subIndex.
    • byte 4..7: Reserved.
  • In case of expedited transfer communication ends here.
CO_SDO_ST_DOWNLOAD_SEGMENT_REQ 
  • SDO client sends SDO segment:
    • byte 0: 000tnnnc binary: (t: toggle bit, set to 0 in first segment; nnn: number of data bytes, that do not contain data; c=1 if this is the last segment).
    • byte 1..7: Data segment.
  • SDO server waits for segment.
CO_SDO_ST_DOWNLOAD_SEGMENT_RSP 
  • SDO client waits for response.
  • SDO server responses:
    • byte 0: 001t0000 binary: (t: toggle bit, set to 0 in first segment).
    • byte 1..7: Reserved.
  • If c was set to 1, then communication ends here.
CO_SDO_ST_UPLOAD_LOCAL_TRANSFER 
  • SDO client: Node-ID of the SDO server is the same as node-ID of this node, SDO client is the same device as SDO server. Transfer data directly without communication on CAN.
  • SDO server does not use this state.
CO_SDO_ST_UPLOAD_INITIATE_REQ 
  • SDO client initiates SDO upload:
    • byte 0: 01000000 binary.
    • byte 1..3: Object index and subIndex.
    • byte 4..7: Reserved.
  • SDO server is in CO_SDO_ST_IDLE state and waits for client request.
CO_SDO_ST_UPLOAD_INITIATE_RSP 
  • SDO client waits for response.
  • SDO server responses:
    • byte 0: 0100nnes binary: (nn: if e=s=1, number of data bytes, that do not contain data; e=1 for expedited transfer; s=1 if data size is indicated).
    • byte 1..3: Object index and subIndex.
    • byte 4..7: If e=1, expedited data are here. If e=0 s=1, size of data for segmented transfer is indicated here.
  • In case of expedited transfer communication ends here.
CO_SDO_ST_UPLOAD_SEGMENT_REQ 
  • SDO client requests SDO segment:
    • byte 0: 011t0000 binary: (t: toggle bit, set to 0 in first segment).
    • byte 1..7: Reserved.
  • SDO server waits for segment request.
CO_SDO_ST_UPLOAD_SEGMENT_RSP 
  • SDO client waits for response.
  • SDO server responses with data:
    • byte 0: 000tnnnc binary: (t: toggle bit, set to 0 in first segment; nnn: number of data bytes, that do not contain data; c=1 if this is the last segment).
    • byte 1..7: Data segment.
  • If c is set to 1, then communication ends here.
CO_SDO_ST_DOWNLOAD_BLK_INITIATE_REQ 
  • SDO client initiates SDO block download:
    • byte 0: 11000rs0 binary: (r=1 if client supports generating CRC on data; s=1 if data size is indicated.)
    • byte 1..3: Object index and subIndex.
    • byte 4..7: If s=1, then size of data for block download is indicated here.
  • SDO server is in CO_SDO_ST_IDLE state and waits for client request.
CO_SDO_ST_DOWNLOAD_BLK_INITIATE_RSP 
  • SDO client waits for response.
  • SDO server responses:
    • byte 0: 10100r00 binary: (r=1 if server supports generating CRC on data.)
    • byte 1..3: Object index and subIndex.
    • byte 4: blksize: Number of segments per block that shall be used by the client for the following block download with 0 < blksize < 128.
    • byte 5..7: Reserved.
CO_SDO_ST_DOWNLOAD_BLK_SUBBLOCK_REQ 
  • SDO client sends 'blksize' segments of data in sequence:
    • byte 0: cnnnnnnn binary: (c=1 if no more segments to be downloaded, enter SDO block download end phase; nnnnnnn is sequence number of segment, 1..127.
    • byte 1..7: At most 7 bytes of segment data to be downloaded.
  • SDO server reads sequence of 'blksize' blocks.
CO_SDO_ST_DOWNLOAD_BLK_SUBBLOCK_RSP 
  • SDO client waits for response.
  • SDO server responses:
    • byte 0: 10100010 binary.
    • byte 1: ackseq: sequence number of last segment that was received successfully during the last block download. If ackseq is set to 0 the server indicates the client that the segment with the sequence number 1 was not received correctly and all segments shall be retransmitted by the client.
    • byte 2: Number of segments per block that shall be used by the client for the following block download with 0 < blksize < 128.
    • byte 3..7: Reserved.
  • If c was set to 1, then communication enters SDO block download end phase.
CO_SDO_ST_DOWNLOAD_BLK_END_REQ 
  • SDO client sends SDO block download end:
    • byte 0: 110nnn01 binary: (nnn: number of data bytes, that do not contain data)
    • byte 1..2: 16 bit CRC for the data set, if enabled by client and server.
    • byte 3..7: Reserved.
  • SDO server waits for client request.
CO_SDO_ST_DOWNLOAD_BLK_END_RSP 
  • SDO client waits for response.
  • SDO server responses:
    • byte 0: 10100001 binary.
    • byte 1..7: Reserved.
  • Block download successfully ends here.
CO_SDO_ST_UPLOAD_BLK_INITIATE_REQ 
  • SDO client initiates SDO block upload:
    • byte 0: 10100r00 binary: (r=1 if client supports generating CRC on data.)
    • byte 1..3: Object index and subIndex.
    • byte 4: blksize: Number of segments per block with 0 < blksize < 128.
    • byte 5: pst - protocol switch threshold. If pst > 0 and size of the data in bytes is less or equal pst, then the server may switch to the SDO upload protocol CO_SDO_ST_UPLOAD_INITIATE_RSP.
    • byte 6..7: Reserved.
  • SDO server is in CO_SDO_ST_IDLE state and waits for client request.
CO_SDO_ST_UPLOAD_BLK_INITIATE_RSP 
  • SDO client waits for response.
  • SDO server responses:
    • byte 0: 11000rs0 binary: (r=1 if server supports generating CRC on data; s=1 if data size is indicated. )
    • byte 1..3: Object index and subIndex.
    • byte 4..7: If s=1, then size of data for block upload is indicated here.
  • If enabled by pst, then server may alternatively response with CO_SDO_ST_UPLOAD_INITIATE_RSP
CO_SDO_ST_UPLOAD_BLK_INITIATE_REQ2 
  • SDO client sends second initiate for SDO block upload:
    • byte 0: 10100011 binary.
    • byte 1..7: Reserved.
  • SDO server waits for client request.
CO_SDO_ST_UPLOAD_BLK_SUBBLOCK_SREQ 
  • SDO client reads sequence of 'blksize' blocks.
  • SDO server sends 'blksize' segments of data in sequence:
    • byte 0: cnnnnnnn binary: (c=1 if no more segments to be uploaded, enter SDO block upload end phase; nnnnnnn is sequence number of segment, 1..127.
    • byte 1..7: At most 7 bytes of segment data to be uploaded.
CO_SDO_ST_UPLOAD_BLK_SUBBLOCK_CRSP 
  • SDO client responses:
    • byte 0: 10100010 binary.
    • byte 1: ackseq: sequence number of last segment that was received successfully during the last block upload. If ackseq is set to 0 the client indicates the server that the segment with the sequence number 1 was not received correctly and all segments shall be retransmitted by the server.
    • byte 2: Number of segments per block that shall be used by the server for the following block upload with 0 < blksize < 128.
    • byte 3..7: Reserved.
  • SDO server waits for response.
  • If c was set to 1 and all segments were successfull received, then communication enters SDO block upload end phase.
CO_SDO_ST_UPLOAD_BLK_END_SREQ 
  • SDO client waits for server request.
  • SDO server sends SDO block upload end:
    • byte 0: 110nnn01 binary: (nnn: number of data bytes, that do not contain data)
    • byte 1..2: 16 bit CRC for the data set, if enabled by client and server.
    • byte 3..7: Reserved.
CO_SDO_ST_UPLOAD_BLK_END_CRSP 
  • SDO client responses:
    • byte 0: 10100001 binary.
    • byte 1..7: Reserved.
  • SDO server waits for response.
  • Block download successfully ends here. Note that this communication ends with client response. Client may then start next SDO communication immediately.

◆ CO_SDO_abortCode_t

SDO abort codes.

Send with Abort SDO transfer message.

The abort codes not listed here are reserved.

Enumerator
CO_SDO_AB_NONE 

0x00000000, No abort

CO_SDO_AB_TOGGLE_BIT 

0x05030000, Toggle bit not altered

CO_SDO_AB_TIMEOUT 

0x05040000, SDO protocol timed out

CO_SDO_AB_CMD 

0x05040001, Command specifier not valid or unknown

CO_SDO_AB_BLOCK_SIZE 

0x05040002, Invalid block size in block mode

CO_SDO_AB_SEQ_NUM 

0x05040003, Invalid sequence number in block mode

CO_SDO_AB_CRC 

0x05040004, CRC error (block mode only)

CO_SDO_AB_OUT_OF_MEM 

0x05040005, Out of memory

CO_SDO_AB_UNSUPPORTED_ACCESS 

0x06010000, Unsupported access to an object

CO_SDO_AB_WRITEONLY 

0x06010001, Attempt to read a write only object

CO_SDO_AB_READONLY 

0x06010002, Attempt to write a read only object

CO_SDO_AB_NOT_EXIST 

0x06020000, Object does not exist in the object dictionary

CO_SDO_AB_NO_MAP 

0x06040041, Object cannot be mapped to the PDO

CO_SDO_AB_MAP_LEN 

0x06040042, Number and length of object to be mapped exceeds PDO length

CO_SDO_AB_PRAM_INCOMPAT 

0x06040043, General parameter incompatibility reasons

CO_SDO_AB_DEVICE_INCOMPAT 

0x06040047, General internal incompatibility in device

CO_SDO_AB_HW 

0x06060000, Access failed due to hardware error

CO_SDO_AB_TYPE_MISMATCH 

0x06070010, Data type does not match, length of service parameter does not match

CO_SDO_AB_DATA_LONG 

0x06070012, Data type does not match, length of service parameter too high

CO_SDO_AB_DATA_SHORT 

0x06070013, Data type does not match, length of service parameter too short

CO_SDO_AB_SUB_UNKNOWN 

0x06090011, Sub index does not exist

CO_SDO_AB_INVALID_VALUE 

0x06090030, Invalid value for parameter (download only).

CO_SDO_AB_VALUE_HIGH 

0x06090031, Value range of parameter written too high

CO_SDO_AB_VALUE_LOW 

0x06090032, Value range of parameter written too low

CO_SDO_AB_MAX_LESS_MIN 

0x06090036, Maximum value is less than minimum value.

CO_SDO_AB_NO_RESOURCE 

0x060A0023, Resource not available: SDO connection

CO_SDO_AB_GENERAL 

0x08000000, General error

CO_SDO_AB_DATA_TRANSF 

0x08000020, Data cannot be transferred or stored to application

CO_SDO_AB_DATA_LOC_CTRL 

0x08000021, Data cannot be transferred or stored to application because of local control

CO_SDO_AB_DATA_DEV_STATE 

0x08000022, Data cannot be transferred or stored to application because of present device state

CO_SDO_AB_DATA_OD 

0x08000023, Object dictionary not present or dynamic generation fails

CO_SDO_AB_NO_DATA 

0x08000024, No data available

◆ CO_SDO_return_t

Return values from SDO server or client functions.

Enumerator
CO_SDO_RT_waitingLocalTransfer 

Waiting in client local transfer.

CO_SDO_RT_uploadDataBufferFull 

Data buffer is full.

SDO client: data must be read before next upload cycle begins.

CO_SDO_RT_transmittBufferFull 

CAN transmit buffer is full.

Waiting.

CO_SDO_RT_blockDownldInProgress 

Block download is in progress.

Sending train of messages.

CO_SDO_RT_blockUploadInProgress 

Block upload is in progress.

Receiving train of messages. SDO client: Data must not be read in this state.

CO_SDO_RT_waitingResponse 

Waiting server or client response.

CO_SDO_RT_ok_communicationEnd 

Success, end of communication.

SDO client: uploaded data must be read.

CO_SDO_RT_wrongArguments 

Error in arguments.

CO_SDO_RT_endedWithClientAbort 

Communication ended with client abort.

CO_SDO_RT_endedWithServerAbort 

Communication ended with server abort.

Function Documentation

◆ CO_SDOserver_init()

CO_ReturnError_t CO_SDOserver_init ( CO_SDOserver_t SDO,
const OD_t OD,
const OD_entry_t OD_1200_SDOsrvPar,
uint8_t  nodeId,
uint16_t  SDOtimeoutTime_ms,
CO_CANmodule_t CANdevRx,
uint16_t  CANdevRxIdx,
CO_CANmodule_t CANdevTx,
uint16_t  CANdevTxIdx 
)

Initialize SDO object.

Function must be called in the communication reset section.

Parameters
SDOThis object will be initialized.
ODObject Dictionary.
OD_1200_SDOsrvParOD entry for SDO server parameter (0x1200+), can be NULL for default single SDO server and must not be NULL for additional SDO servers. With additional SDO servers it may also have IO extension enabled, to allow dynamic configuration (see also CO_CONFIG_FLAG_OD_DYNAMIC).
nodeIdIf this is first SDO channel, then "nodeId" is CANopen Node ID of this device. In all additional channels "nodeId" is ignored.
SDOtimeoutTime_msTimeout time for SDO communication in milliseconds.
CANdevRxCAN device for SDO server reception.
CANdevRxIdxIndex of receive buffer in the above CAN device.
CANdevTxCAN device for SDO server transmission.
CANdevTxIdxIndex of transmit buffer in the above CAN device.
Returns
CO_ReturnError_t CO_ERROR_NO in case of success.

◆ CO_SDOserver_initCallbackPre()

void CO_SDOserver_initCallbackPre ( CO_SDOserver_t SDO,
void *  object,
void(*)(void *object)  pFunctSignalPre 
)

Initialize SDOrx callback function.

Function initializes optional callback function, which should immediately start processing of CO_SDOserver_process() function. Callback is called after SDOserver message is received from the CAN bus or when new call without delay is necessary (SDO block transfer is in progress).

Parameters
SDOThis object.
objectPointer to object, which will be passed to pFunctSignalPre(). Can be NULL
pFunctSignalPrePointer to the callback function. Not called if NULL.

◆ CO_SDOserver_process()

CO_SDO_return_t CO_SDOserver_process ( CO_SDOserver_t SDO,
bool_t  NMTisPreOrOperational,
uint32_t  timeDifference_us,
uint32_t timerNext_us 
)

Process SDO communication.

Function must be called cyclically.

Parameters
SDOThis object.
NMTisPreOrOperationalTrue if CO_NMT_internalState_t is NMT_PRE_OPERATIONAL or NMT_OPERATIONAL.
timeDifference_usTime difference from previous function call in [microseconds].
[out]timerNext_usinfo to OS - see CO_process().
Returns
CO_SDO_return_t