Fix CANopen terminology: “CAN messages” are actually “CAN frames”
Fix all documentation and comments according to CiA proposals: https://www.can-cia.org/services/publications/can-community-news/05-2025 CANopenNode was using "CAN message" in many places, but actually such term is incorrect. No code or variable names was changed.
This commit is contained in:
parent
891852ce39
commit
8c09a433ef
29 changed files with 207 additions and 203 deletions
|
|
@ -270,9 +270,9 @@ OD_write_statusBits(OD_stream_t* stream, const void* buf, OD_size_t count, OD_si
|
|||
|
||||
#if ((CO_CONFIG_EM)&CO_CONFIG_EM_CONSUMER) != 0
|
||||
/*
|
||||
* Read received message from CAN module.
|
||||
* Read received frame from CAN module.
|
||||
*
|
||||
* Function will be called (by CAN receive interrupt) every time, when CAN message with correct identifier
|
||||
* Function will be called (by CAN receive interrupt) every time, when CAN frame with correct identifier
|
||||
* will be received. For more information and description of parameters see file CO_driver.h.
|
||||
*/
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -180,8 +180,8 @@ extern "C" {
|
|||
*/
|
||||
#define CO_EM_NO_ERROR 0x00U /**< 0x00 Error Reset or No Error */
|
||||
#define CO_EM_CAN_BUS_WARNING 0x01U /**< 0x01 communication info CAN bus warning limit reached */
|
||||
#define CO_EM_RXMSG_WRONG_LENGTH 0x02U /**< 0x02 communication info Wrong data length of the received CAN message */
|
||||
#define CO_EM_RXMSG_OVERFLOW 0x03U /**< 0x03 communication info Previous received CAN message wasn't processed */
|
||||
#define CO_EM_RXMSG_WRONG_LENGTH 0x02U /**< 0x02 communication info Wrong data length of the received CAN frame */
|
||||
#define CO_EM_RXMSG_OVERFLOW 0x03U /**< 0x03 communication info Previous received CAN frame wasn't processed */
|
||||
#define CO_EM_RPDO_WRONG_LENGTH 0x04U /**< 0x04 communication info Wrong data length of received PDO */
|
||||
#define CO_EM_RPDO_OVERFLOW 0x05U /**< 0x05 communication info Previous received PDO wasn't processed yet */
|
||||
#define CO_EM_CAN_RX_BUS_PASSIVE 0x06U /**< 0x06 communication info CAN receive bus is passive */
|
||||
|
|
@ -281,7 +281,7 @@ typedef struct {
|
|||
#if (((CO_CONFIG_EM)&CO_CONFIG_EM_PRODUCER) != 0) || defined CO_DOXYGEN
|
||||
bool_t producerEnabled; /**< True, if emergency producer is enabled, from Object dictionary */
|
||||
uint8_t nodeId; /**< Copy of CANopen node ID, from CO_EM_init() */
|
||||
CO_CANtx_t* CANtxBuff; /**< CAN transmit buffer */
|
||||
CO_CANtx_t* CANtxBuff; /**< CAN transmit buffer inside CANdevTx */
|
||||
OD_extension_t OD_1014_extension; /**< Extension for OD object */
|
||||
#if (((CO_CONFIG_EM)&CO_CONFIG_EM_PROD_CONFIGURABLE) != 0) || defined CO_DOXYGEN
|
||||
uint16_t producerCanId; /**< COB ID of emergency message, from Object dictionary */
|
||||
|
|
|
|||
|
|
@ -29,9 +29,9 @@
|
|||
#endif
|
||||
|
||||
/*
|
||||
* Read received message from CAN module.
|
||||
* Read received frame from CAN module.
|
||||
*
|
||||
* Function will be called (by CAN receive interrupt) every time, when CAN message with correct identifier
|
||||
* Function will be called (by CAN receive interrupt) every time, when CAN frame with correct identifier
|
||||
* will be received. For more information and description of parameters see file CO_driver.h.
|
||||
*/
|
||||
static void
|
||||
|
|
@ -41,7 +41,7 @@ CO_HBcons_receive(void* object, void* msg) {
|
|||
const uint8_t* data = CO_CANrxMsg_readData(msg);
|
||||
|
||||
if (DLC == 1U) {
|
||||
/* copy data and set 'new message' flag. */
|
||||
/* copy data and set 'new frame' flag. */
|
||||
HBconsNode->NMTstate = (CO_NMT_internalState_t)data[0];
|
||||
CO_FLAG_SET(HBconsNode->CANrxNew);
|
||||
#if ((CO_CONFIG_HB_CONS)&CO_CONFIG_FLAG_CALLBACK_PRE) != 0
|
||||
|
|
@ -317,7 +317,7 @@ CO_HBconsumer_process(CO_HBconsumer_t* HBcons, bool_t NMTisPreOrOperational, uin
|
|||
/* continue, if node is not monitored */
|
||||
continue;
|
||||
}
|
||||
/* Verify if received message is heartbeat or bootup */
|
||||
/* Verify if received frame is heartbeat or bootup */
|
||||
if (CO_FLAG_READ(monitoredNode->CANrxNew)) {
|
||||
if (monitoredNode->NMTstate == CO_NMT_INITIALIZING) {
|
||||
/* bootup message */
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@
|
|||
#include "301/CO_NMT_Heartbeat.h"
|
||||
|
||||
/*
|
||||
* Read received message from CAN module.
|
||||
* Read received frame from CAN module.
|
||||
*
|
||||
* Function will be called (by CAN receive interrupt) every time, when CAN message with correct identifier
|
||||
* Function will be called (by CAN receive interrupt) every time, when CAN frame with correct identifier
|
||||
* will be received. For more information and description of parameters see file CO_driver.h.
|
||||
*/
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@
|
|||
#if ((CO_CONFIG_NODE_GUARDING)&CO_CONFIG_NODE_GUARDING_SLAVE_ENABLE) != 0
|
||||
|
||||
/*
|
||||
* Read received message from CAN module.
|
||||
* Read received frame from CAN module.
|
||||
*
|
||||
* Function will be called (by CAN receive interrupt) every time, when CAN message with correct identifier
|
||||
* Function will be called (by CAN receive interrupt) every time, when CAN frame with correct identifier
|
||||
* will be received. For more information and description of parameters see file CO_driver.h.
|
||||
*/
|
||||
static void
|
||||
|
|
@ -232,12 +232,12 @@ CO_nodeGuardingSlave_process(CO_nodeGuardingSlave_t* ngs, CO_NMT_internalState_t
|
|||
|
||||
#if ((CO_CONFIG_NODE_GUARDING)&CO_CONFIG_NODE_GUARDING_MASTER_ENABLE) != 0
|
||||
/*
|
||||
* Read received message from CAN module.
|
||||
* Read received frame from CAN module.
|
||||
*
|
||||
* Function will be called (by CAN receive interrupt) every time, when CAN message with correct identifier
|
||||
* Function will be called (by CAN receive interrupt) every time, when CAN frame with correct identifier
|
||||
* will be received. For more information and description of parameters see file CO_driver.h.
|
||||
*
|
||||
* Function receives messages from CAN identifier from 0x700 to 0x7FF. It
|
||||
* Function receives frames with CAN identifier from 0x700 to 0x7FF. It
|
||||
* searches matching node->ident from nodes array.
|
||||
*/
|
||||
static void
|
||||
|
|
@ -281,7 +281,7 @@ CO_nodeGuardingMaster_init(CO_nodeGuardingMaster_t* ngm, CO_EM_t* em, CO_CANmodu
|
|||
/* Configure object variables */
|
||||
ngm->em = em;
|
||||
|
||||
/* configure CAN reception. One buffer will receive all messages from CAN-id 0x700 to 0x7FF. */
|
||||
/* configure CAN reception. One buffer will receive all CAN frames from CAN-id 0x700 to 0x7FF. */
|
||||
ret = CO_CANrxBufferInit(CANdevRx, CANdevRxIdx, CO_CAN_ID_HEARTBEAT, 0x780, false, (void*)ngm, CO_ngm_receive);
|
||||
if (ret != CO_ERROR_NO) {
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ extern "C" {
|
|||
* @ingroup CO_CANopen_301
|
||||
* @{
|
||||
* Node guarding master pools each node guarding slave at time intervals, called guard time. Master sends a CAN RTR
|
||||
* message, and slave responds. Slave also monitors presence of RTR message from master and indicates error, if it
|
||||
* frame, and slave responds. Slave also monitors presence of RTR frame from master and indicates error, if it
|
||||
* wasn't received within life time. ('Life time' is 'Guard time' multiplied by 'Life time factor').
|
||||
*
|
||||
* Adding Node guarding to the project:
|
||||
|
|
@ -73,7 +73,7 @@ extern "C" {
|
|||
*/
|
||||
typedef struct {
|
||||
CO_EM_t* em; /**< From CO_nodeGuardingSlave_init() */
|
||||
volatile void* CANrxNew; /**< Indicates, if new rtr message received from CAN bus */
|
||||
volatile void* CANrxNew; /**< Indicates, if new NodeGuarding rtr message received from CAN bus */
|
||||
uint32_t guardTime_us; /**< Guard time in microseconds, calculated from OD_0x100C */
|
||||
uint32_t lifeTime_us; /**< Life time in microseconds, calculated from guardTime_us * lifeTimeFactor */
|
||||
uint32_t lifeTimer; /**< Timer for monitoring Life time, counting down from lifeTime_us. */
|
||||
|
|
@ -83,7 +83,7 @@ typedef struct {
|
|||
OD_extension_t OD_100C_extension; /**< Extension for OD object */
|
||||
OD_extension_t OD_100D_extension; /**< Extension for OD object */
|
||||
CO_CANmodule_t* CANdevTx; /**< From CO_nodeGuardingSlave_init() */
|
||||
CO_CANtx_t* CANtxBuff; /**< CAN transmit buffer for the message */
|
||||
CO_CANtx_t* CANtxBuff; /**< CAN transmit buffer inside CANdevTx */
|
||||
} CO_nodeGuardingSlave_t;
|
||||
|
||||
/**
|
||||
|
|
@ -95,7 +95,7 @@ typedef struct {
|
|||
* @param OD_100C_GuardTime OD entry for 0x100C -"Guard time", entry is required.
|
||||
* @param OD_100D_LifeTimeFactor OD entry for 0x100D -"Life time factor", entry is required.
|
||||
* @param em Emergency object.
|
||||
* @param CANidNodeGuarding CAN identifier for Node Guarding rtr and response message (usually CO_CAN_ID_HEARTBEAT +
|
||||
* @param CANidNodeGuarding CAN identifier for Node Guarding rtr and response CAN frame (usually CO_CAN_ID_HEARTBEAT +
|
||||
* nodeId).
|
||||
* @param CANdevRx CAN device for Node Guarding rtr reception.
|
||||
* @param CANdevRxIdx Index of the receive buffer in the above CAN device.
|
||||
|
|
@ -182,7 +182,7 @@ typedef struct {
|
|||
CO_EM_t* em; /**< From CO_nodeGuardingMaster_init() */
|
||||
CO_CANmodule_t* CANdevTx; /**< From CO_nodeGuardingMaster_init() */
|
||||
uint16_t CANdevTxIdx; /**< From CO_nodeGuardingMaster_init() */
|
||||
CO_CANtx_t* CANtxBuff; /**< CAN transmit buffer for the message */
|
||||
CO_CANtx_t* CANtxBuff; /**< CAN transmit buffer inside CANdevTx */
|
||||
bool_t allMonitoredActive; /**< True, if all monitored nodes are active or no node is monitored. Can be read by the
|
||||
application */
|
||||
bool_t allMonitoredOperational; /**< True, if all monitored nodes are NMT operational or no node is monitored. Can
|
||||
|
|
|
|||
18
301/CO_PDO.c
18
301/CO_PDO.c
|
|
@ -452,12 +452,12 @@ OD_read_PDO_commParam(OD_stream_t* stream, void* buf, OD_size_t count, OD_size_t
|
|||
/* @} */ /* CO_PDO_receiveErrors_t */
|
||||
|
||||
/*
|
||||
* Read received message from CAN module.
|
||||
* Read received frame from CAN module.
|
||||
*
|
||||
* Function will be called (by CAN receive interrupt) every time, when CAN message with correct identifier
|
||||
* Function will be called (by CAN receive interrupt) every time, when CAN frame with correct identifier
|
||||
* will be received. For more information and description of parameters see file CO_driver.h.
|
||||
* If new message arrives and previous message wasn't processed yet, then
|
||||
* previous message will be lost and overwritten by the new message.
|
||||
* If new CAN frame arrives and previous frame wasn't processed yet, then
|
||||
* previous frame will be lost and overwritten by the new frame.
|
||||
*/
|
||||
static void
|
||||
CO_PDO_receive(void* object, void* msg) {
|
||||
|
|
@ -488,7 +488,7 @@ CO_PDO_receive(void* object, void* msg) {
|
|||
}
|
||||
}
|
||||
|
||||
/* Determine, to which of the two rx buffers copy the message. */
|
||||
/* Determine, to which of the two rx buffers copy the data from the CAN frame. */
|
||||
uint8_t bufNo = 0;
|
||||
#if ((CO_CONFIG_PDO)&CO_CONFIG_PDO_SYNC_ENABLE) != 0
|
||||
if (RPDO->synchronous && (RPDO->SYNC != NULL) && RPDO->SYNC->CANrxToggle) {
|
||||
|
|
@ -496,7 +496,7 @@ CO_PDO_receive(void* object, void* msg) {
|
|||
}
|
||||
#endif
|
||||
|
||||
/* copy data into appropriate buffer and set 'new message' flag */
|
||||
/* copy data into appropriate buffer and set 'new frame' flag */
|
||||
(void)memcpy(RPDO->CANrxData[bufNo], data, CO_PDO_MAX_SIZE);
|
||||
CO_FLAG_SET(RPDO->CANrxNew[bufNo]);
|
||||
|
||||
|
|
@ -584,7 +584,7 @@ OD_write_14xx(OD_stream_t* stream, const void* buf, OD_size_t count, OD_size_t*
|
|||
}
|
||||
|
||||
bool_t synchronous = transmissionType <= (uint8_t)CO_PDO_TRANSM_TYPE_SYNC_240;
|
||||
/* Remove old message from the second buffer. */
|
||||
/* Remove old frame from the second buffer. */
|
||||
if (RPDO->synchronous != synchronous) {
|
||||
CO_FLAG_CLEAR(RPDO->CANrxNew[1]);
|
||||
}
|
||||
|
|
@ -756,7 +756,7 @@ CO_RPDO_process(CO_RPDO_t* RPDO,
|
|||
&& (syncWas || !RPDO->synchronous)
|
||||
#endif
|
||||
) {
|
||||
/* Verify errors in length of received RPDO CAN message */
|
||||
/* Verify errors in length of received RPDO message */
|
||||
if (RPDO->receiveError > CO_RPDO_RX_ACK) {
|
||||
bool_t setError = RPDO->receiveError != CO_RPDO_RX_OK;
|
||||
uint16_t code = (RPDO->receiveError == CO_RPDO_RX_SHORT) ? CO_EMC_PDO_LENGTH : CO_EMC_PDO_LENGTH_EXC;
|
||||
|
|
@ -764,7 +764,7 @@ CO_RPDO_process(CO_RPDO_t* RPDO,
|
|||
RPDO->receiveError = setError ? CO_RPDO_RX_ACK_ERROR : CO_RPDO_RX_ACK_NO_ERROR;
|
||||
}
|
||||
|
||||
/* Determine, which of the two rx buffers contains relevant message. */
|
||||
/* Determine, which of the two rx buffers contains relevant data. */
|
||||
uint8_t bufNo = 0;
|
||||
#if ((CO_CONFIG_PDO)&CO_CONFIG_PDO_SYNC_ENABLE) != 0
|
||||
if (RPDO->synchronous && (RPDO->SYNC != NULL) && !RPDO->SYNC->CANrxToggle) {
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ extern "C" {
|
|||
* ### CAN identifiers for PDO
|
||||
*
|
||||
* Each PDO can be configured with any valid 11-bit CAN identifier. Lower numbers have higher priorities on CAN bus. As
|
||||
* a general rule, each CAN message is identified with own CAN-ID, which must be unique and produced by single source.
|
||||
* a general rule, each CAN frame is identified with own CAN-ID, which must be unique and produced by single source.
|
||||
* The same is with PDO objects: Any TPDO produced on the CANopen network must have unique CAN-ID and there can be zero
|
||||
* to many RPDOs (from different devices) configured to match the CAN-ID of the TPDO of interest.
|
||||
*
|
||||
|
|
@ -196,7 +196,7 @@ typedef struct {
|
|||
******************************************************************************/
|
||||
#if (((CO_CONFIG_PDO)&CO_CONFIG_RPDO_ENABLE) != 0) || defined CO_DOXYGEN
|
||||
/**
|
||||
* Number of buffers for received CAN message for RPDO
|
||||
* Number of buffers for received CAN frame for RPDO
|
||||
*/
|
||||
#if (((CO_CONFIG_PDO)&CO_CONFIG_PDO_SYNC_ENABLE) != 0) || defined CO_DOXYGEN
|
||||
#define CO_RPDO_CAN_BUFFERS_COUNT 2
|
||||
|
|
|
|||
|
|
@ -48,9 +48,9 @@
|
|||
#endif
|
||||
|
||||
/*
|
||||
* Read received message from CAN module.
|
||||
* Read received frame from CAN module.
|
||||
*
|
||||
* Function will be called (by CAN receive interrupt) every time, when CAN message with correct identifier
|
||||
* Function will be called (by CAN receive interrupt) every time, when CAN frame with correct identifier
|
||||
* will be received. For more information and description of parameters see file CO_driver.h.
|
||||
*/
|
||||
static void
|
||||
|
|
@ -59,8 +59,8 @@ CO_SDOclient_receive(void* object, void* msg) {
|
|||
uint8_t DLC = CO_CANrxMsg_readDLC(msg);
|
||||
const uint8_t* data = CO_CANrxMsg_readData(msg);
|
||||
|
||||
/* Ignore messages in idle state and messages with wrong length. Ignore
|
||||
* message also if previous message was not processed yet and not abort */
|
||||
/* Ignore frames in idle state and frames with wrong length. Ignore
|
||||
* frame also if previous frame was not processed yet and not abort */
|
||||
if ((SDO_C->state != CO_SDO_ST_IDLE) && (DLC == 8U) && (!CO_FLAG_READ(SDO_C->CANrxNew) || (data[0] == 0x80U))) {
|
||||
#if ((CO_CONFIG_SDO_CLI)&CO_CONFIG_SDO_CLI_BLOCK) != 0
|
||||
bool_t state_not_upload_blk_sublock_sreq = (SDO_C->state != CO_SDO_ST_UPLOAD_BLK_SUBBLOCK_SREQ);
|
||||
|
|
@ -68,7 +68,7 @@ CO_SDOclient_receive(void* object, void* msg) {
|
|||
if ((data[0] == 0x80U) /* abort from server */
|
||||
|| (state_not_upload_blk_sublock_sreq && state_not_upload_blk_sublock_crsp)) {
|
||||
#endif
|
||||
/* copy data and set 'new message' flag */
|
||||
/* copy data and set 'new frame' flag */
|
||||
(void)memcpy((void*)&SDO_C->CANrxData[0], (const void*)&data[0], 8);
|
||||
CO_FLAG_SET(SDO_C->CANrxNew);
|
||||
#if ((CO_CONFIG_SDO_CLI)&CO_CONFIG_FLAG_CALLBACK_PRE) != 0
|
||||
|
|
@ -108,7 +108,7 @@ CO_SDOclient_receive(void* object, void* msg) {
|
|||
}
|
||||
}
|
||||
}
|
||||
/* If message is duplicate or sequence didn't start yet, ignore it. Otherwise seqno is wrong,
|
||||
/* If CAN frame is duplicate or sequence didn't start yet, ignore it. Otherwise seqno is wrong,
|
||||
* so break sub-block. Data after last good seqno will be re-transmitted. */
|
||||
else if ((seqno != SDO_C->block_seqno) && (SDO_C->block_seqno != 0U)) {
|
||||
state = CO_SDO_ST_UPLOAD_BLK_SUBBLOCK_CRSP;
|
||||
|
|
@ -844,7 +844,7 @@ CO_SDOclientDownload(CO_SDOclient_t* SDO_C, uint32_t timeDifference_us, bool_t s
|
|||
#endif
|
||||
}
|
||||
|
||||
/* reset timeout timer and send message */
|
||||
/* reset timeout timer and send CAN frame */
|
||||
SDO_C->timeoutTimer = 0;
|
||||
(void)CO_CANsend(SDO_C->CANdevTx, SDO_C->CANtxBuff);
|
||||
SDO_C->state = CO_SDO_ST_DOWNLOAD_INITIATE_RSP;
|
||||
|
|
@ -879,7 +879,7 @@ CO_SDOclientDownload(CO_SDOclient_t* SDO_C, uint32_t timeDifference_us, bool_t s
|
|||
SDO_C->finished = true;
|
||||
}
|
||||
|
||||
/* reset timeout timer and send message */
|
||||
/* reset timeout timer and send CAN frame */
|
||||
SDO_C->timeoutTimer = 0;
|
||||
(void)CO_CANsend(SDO_C->CANdevTx, SDO_C->CANtxBuff);
|
||||
SDO_C->state = CO_SDO_ST_DOWNLOAD_SEGMENT_RSP;
|
||||
|
|
@ -901,7 +901,7 @@ CO_SDOclientDownload(CO_SDOclient_t* SDO_C, uint32_t timeDifference_us, bool_t s
|
|||
(void)memcpy((void*)(&SDO_C->CANtxBuff->data[4]), (const void*)(&size), sizeof(size));
|
||||
}
|
||||
|
||||
/* reset timeout timer and send message */
|
||||
/* reset timeout timer and send CAN frame */
|
||||
SDO_C->timeoutTimer = 0;
|
||||
(void)CO_CANsend(SDO_C->CANdevTx, SDO_C->CANtxBuff);
|
||||
SDO_C->state = CO_SDO_ST_DOWNLOAD_BLK_INITIATE_RSP;
|
||||
|
|
@ -952,7 +952,7 @@ CO_SDOclientDownload(CO_SDOclient_t* SDO_C, uint32_t timeDifference_us, bool_t s
|
|||
}
|
||||
}
|
||||
#endif
|
||||
/* reset timeout timer and send message */
|
||||
/* reset timeout timer and send CAN frame */
|
||||
SDO_C->timeoutTimer = 0;
|
||||
(void)CO_CANsend(SDO_C->CANdevTx, SDO_C->CANtxBuff);
|
||||
break;
|
||||
|
|
@ -963,7 +963,7 @@ CO_SDOclientDownload(CO_SDOclient_t* SDO_C, uint32_t timeDifference_us, bool_t s
|
|||
SDO_C->CANtxBuff->data[1] = (uint8_t)SDO_C->block_crc;
|
||||
SDO_C->CANtxBuff->data[2] = (uint8_t)(SDO_C->block_crc >> 8);
|
||||
|
||||
/* reset timeout timer and send message */
|
||||
/* reset timeout timer and send CAN frame */
|
||||
SDO_C->timeoutTimer = 0;
|
||||
(void)CO_CANsend(SDO_C->CANdevTx, SDO_C->CANtxBuff);
|
||||
SDO_C->state = CO_SDO_ST_DOWNLOAD_BLK_END_RSP;
|
||||
|
|
@ -1544,7 +1544,7 @@ CO_SDOclientUpload(CO_SDOclient_t* SDO_C, uint32_t timeDifference_us, bool_t sen
|
|||
SDO_C->CANtxBuff->data[2] = (uint8_t)(SDO_C->index >> 8);
|
||||
SDO_C->CANtxBuff->data[3] = SDO_C->subIndex;
|
||||
|
||||
/* reset timeout timer and send message */
|
||||
/* reset timeout timer and send CAN frame */
|
||||
SDO_C->timeoutTimer = 0;
|
||||
(void)CO_CANsend(SDO_C->CANdevTx, SDO_C->CANtxBuff);
|
||||
SDO_C->state = CO_SDO_ST_UPLOAD_INITIATE_RSP;
|
||||
|
|
@ -1560,7 +1560,7 @@ CO_SDOclientUpload(CO_SDOclient_t* SDO_C, uint32_t timeDifference_us, bool_t sen
|
|||
}
|
||||
SDO_C->CANtxBuff->data[0] = 0x60U | SDO_C->toggle;
|
||||
|
||||
/* reset timeout timer and send message */
|
||||
/* reset timeout timer and send CAN frame */
|
||||
SDO_C->timeoutTimer = 0;
|
||||
(void)CO_CANsend(SDO_C->CANdevTx, SDO_C->CANtxBuff);
|
||||
SDO_C->state = CO_SDO_ST_UPLOAD_SEGMENT_RSP;
|
||||
|
|
@ -1589,7 +1589,7 @@ CO_SDOclientUpload(CO_SDOclient_t* SDO_C, uint32_t timeDifference_us, bool_t sen
|
|||
SDO_C->CANtxBuff->data[4] = SDO_C->block_blksize;
|
||||
SDO_C->CANtxBuff->data[5] = CO_CONFIG_SDO_CLI_PST;
|
||||
|
||||
/* reset timeout timer and send message */
|
||||
/* reset timeout timer and send CAN frame */
|
||||
SDO_C->timeoutTimer = 0;
|
||||
(void)CO_CANsend(SDO_C->CANdevTx, SDO_C->CANtxBuff);
|
||||
SDO_C->state = CO_SDO_ST_UPLOAD_BLK_INITIATE_RSP;
|
||||
|
|
@ -1599,7 +1599,7 @@ CO_SDOclientUpload(CO_SDOclient_t* SDO_C, uint32_t timeDifference_us, bool_t sen
|
|||
case CO_SDO_ST_UPLOAD_BLK_INITIATE_REQ2: {
|
||||
SDO_C->CANtxBuff->data[0] = 0xA3;
|
||||
|
||||
/* reset timeout timers, seqno and send message */
|
||||
/* reset timeout timers, seqno and send CAN frame */
|
||||
SDO_C->timeoutTimer = 0;
|
||||
SDO_C->block_timeoutTimer = 0;
|
||||
SDO_C->block_seqno = 0;
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ typedef struct {
|
|||
uint16_t CANdevRxIdx; /**< From CO_SDOclient_init() */
|
||||
CO_CANmodule_t* CANdevTx; /**< From CO_SDOclient_init() */
|
||||
uint16_t CANdevTxIdx; /**< From CO_SDOclient_init() */
|
||||
CO_CANtx_t* CANtxBuff; /**< CAN transmit buffer inside CANdevTx for CAN tx message */
|
||||
CO_CANtx_t* CANtxBuff; /**< CAN transmit buffer inside CANdevTx */
|
||||
#if (((CO_CONFIG_SDO_CLI)&CO_CONFIG_FLAG_OD_DYNAMIC) != 0) || defined CO_DOXYGEN
|
||||
|
||||
uint32_t COB_IDClientToServer; /**< Copy of CANopen COB_ID Client -> Server, meaning of the specific bits:
|
||||
|
|
|
|||
|
|
@ -42,9 +42,9 @@
|
|||
#endif
|
||||
|
||||
/*
|
||||
* Read received message from CAN module.
|
||||
* Read received frame from CAN module.
|
||||
*
|
||||
* Function will be called (by CAN receive interrupt) every time, when CAN message with correct identifier
|
||||
* Function will be called (by CAN receive interrupt) every time, when CAN frame with correct identifier
|
||||
* will be received. For more information and description of parameters see file CO_driver.h.
|
||||
*/
|
||||
static void
|
||||
|
|
@ -53,13 +53,13 @@ CO_SDO_receive(void* object, void* msg) {
|
|||
uint8_t DLC = CO_CANrxMsg_readDLC(msg);
|
||||
const uint8_t* data = CO_CANrxMsg_readData(msg);
|
||||
|
||||
/* ignore messages with wrong length */
|
||||
/* ignore frames with wrong length */
|
||||
if (DLC == 8U) {
|
||||
if (data[0] == 0x80U) {
|
||||
/* abort from client, just make idle */
|
||||
SDO->state = CO_SDO_ST_IDLE;
|
||||
} else if (CO_FLAG_READ(SDO->CANrxNew)) {
|
||||
/* ignore message if previous message was not processed yet */
|
||||
/* ignore frame if previous frame was not processed yet */
|
||||
}
|
||||
#if ((CO_CONFIG_SDO_SRV)&CO_CONFIG_SDO_SRV_BLOCK) != 0
|
||||
else if (SDO->state == CO_SDO_ST_UPLOAD_BLK_END_CRSP && data[0] == 0xA1) {
|
||||
|
|
@ -93,7 +93,7 @@ CO_SDO_receive(void* object, void* msg) {
|
|||
state = CO_SDO_ST_DOWNLOAD_BLK_SUBBLOCK_RSP;
|
||||
}
|
||||
}
|
||||
/* If message is duplicate or sequence didn't start yet, ignore it. Otherwise seqno is wrong,
|
||||
/* If CAN frame is duplicate or sequence didn't start yet, ignore it. Otherwise seqno is wrong,
|
||||
* so break sub-block. Data after last good seqno will be re-transmitted. */
|
||||
else if (seqno != SDO->block_seqno && SDO->block_seqno != 0U) {
|
||||
state = CO_SDO_ST_DOWNLOAD_BLK_SUBBLOCK_RSP;
|
||||
|
|
@ -129,7 +129,7 @@ CO_SDO_receive(void* object, void* msg) {
|
|||
}
|
||||
#endif /* (CO_CONFIG_SDO_SRV) & CO_CONFIG_SDO_SRV_BLOCK */
|
||||
else {
|
||||
/* copy data and set 'new message' flag, data will be processed in CO_SDOserver_process() */
|
||||
/* copy data and set 'new frame' flag, data will be processed in CO_SDOserver_process() */
|
||||
(void)memcpy(SDO->CANrxData, data, DLC);
|
||||
CO_FLAG_SET(SDO->CANrxNew);
|
||||
#if ((CO_CONFIG_SDO_SRV)&CO_CONFIG_FLAG_CALLBACK_PRE) != 0
|
||||
|
|
@ -1129,7 +1129,7 @@ CO_SDOserver_process(CO_SDOserver_t* SDO, bool_t NMTisPreOrOperational, uint32_t
|
|||
SDO->CANtxBuff->data[2] = (uint8_t)(SDO->index >> 8);
|
||||
SDO->CANtxBuff->data[3] = SDO->subIndex;
|
||||
|
||||
/* reset timeout timer and send message */
|
||||
/* reset timeout timer and send CAN frame */
|
||||
#if ((CO_CONFIG_SDO_SRV)&CO_CONFIG_SDO_SRV_SEGMENTED) != 0
|
||||
SDO->timeoutTimer = 0;
|
||||
#endif
|
||||
|
|
@ -1157,7 +1157,7 @@ CO_SDOserver_process(CO_SDOserver_t* SDO, bool_t NMTisPreOrOperational, uint32_t
|
|||
SDO->CANtxBuff->data[0] = 0x20U | SDO->toggle;
|
||||
SDO->toggle = (SDO->toggle == 0x00U) ? 0x10U : 0x00U;
|
||||
|
||||
/* reset timeout timer and send message */
|
||||
/* reset timeout timer and send CAN frame */
|
||||
SDO->timeoutTimer = 0;
|
||||
(void)CO_CANsend(SDO->CANdevTx, SDO->CANtxBuff);
|
||||
if (SDO->finished) {
|
||||
|
|
@ -1226,7 +1226,7 @@ CO_SDOserver_process(CO_SDOserver_t* SDO, bool_t NMTisPreOrOperational, uint32_t
|
|||
ret = CO_SDO_RT_ok_communicationEnd;
|
||||
#endif /* (CO_CONFIG_SDO_SRV) & CO_CONFIG_SDO_SRV_SEGMENTED */
|
||||
|
||||
/* send message */
|
||||
/* send CAN frame */
|
||||
SDO->CANtxBuff->data[1] = (uint8_t)SDO->index;
|
||||
SDO->CANtxBuff->data[2] = (uint8_t)(SDO->index >> 8);
|
||||
SDO->CANtxBuff->data[3] = SDO->subIndex;
|
||||
|
|
@ -1258,7 +1258,7 @@ CO_SDOserver_process(CO_SDOserver_t* SDO, bool_t NMTisPreOrOperational, uint32_t
|
|||
count = 7;
|
||||
}
|
||||
|
||||
/* copy data segment to CAN message */
|
||||
/* copy data segment to CAN frame */
|
||||
(void)memcpy(&SDO->CANtxBuff->data[1], SDO->buf + SDO->bufOffsetRd, count);
|
||||
SDO->bufOffsetRd += count;
|
||||
SDO->sizeTran += count;
|
||||
|
|
@ -1278,7 +1278,7 @@ CO_SDOserver_process(CO_SDOserver_t* SDO, bool_t NMTisPreOrOperational, uint32_t
|
|||
}
|
||||
}
|
||||
|
||||
/* send message */
|
||||
/* send CAN frame */
|
||||
(void)CO_CANsend(SDO->CANdevTx, SDO->CANtxBuff);
|
||||
break;
|
||||
}
|
||||
|
|
@ -1391,7 +1391,7 @@ CO_SDOserver_process(CO_SDOserver_t* SDO, bool_t NMTisPreOrOperational, uint32_t
|
|||
(void)memcpy(&SDO->CANtxBuff->data[4], &size, sizeof(size));
|
||||
}
|
||||
|
||||
/* reset timeout timer and send message */
|
||||
/* reset timeout timer and send CAN frame */
|
||||
SDO->timeoutTimer = 0;
|
||||
(void)CO_CANsend(SDO->CANdevTx, SDO->CANtxBuff);
|
||||
SDO->state = CO_SDO_ST_UPLOAD_BLK_INITIATE_REQ2;
|
||||
|
|
@ -1409,7 +1409,7 @@ CO_SDOserver_process(CO_SDOserver_t* SDO, bool_t NMTisPreOrOperational, uint32_t
|
|||
count = 7;
|
||||
}
|
||||
|
||||
/* copy data segment to CAN message */
|
||||
/* copy data segment to CAN frame */
|
||||
(void)memcpy(&SDO->CANtxBuff->data[1], SDO->buf + SDO->bufOffsetRd, count);
|
||||
SDO->bufOffsetRd += count;
|
||||
SDO->block_noData = (uint8_t)(7 - count);
|
||||
|
|
@ -1440,7 +1440,7 @@ CO_SDOserver_process(CO_SDOserver_t* SDO, bool_t NMTisPreOrOperational, uint32_t
|
|||
}
|
||||
}
|
||||
#endif
|
||||
/* reset timeout timer and send message */
|
||||
/* reset timeout timer and send CAN frame */
|
||||
SDO->timeoutTimer = 0;
|
||||
(void)CO_CANsend(SDO->CANdevTx, SDO->CANtxBuff);
|
||||
break;
|
||||
|
|
@ -1451,7 +1451,7 @@ CO_SDOserver_process(CO_SDOserver_t* SDO, bool_t NMTisPreOrOperational, uint32_t
|
|||
SDO->CANtxBuff->data[1] = (uint8_t)SDO->block_crc;
|
||||
SDO->CANtxBuff->data[2] = (uint8_t)(SDO->block_crc >> 8);
|
||||
|
||||
/* reset timeout timer and send message */
|
||||
/* reset timeout timer and send CAN frame */
|
||||
SDO->timeoutTimer = 0;
|
||||
(void)CO_CANsend(SDO->CANdevTx, SDO->CANtxBuff);
|
||||
SDO->state = CO_SDO_ST_UPLOAD_BLK_END_CRSP;
|
||||
|
|
|
|||
|
|
@ -358,7 +358,7 @@ typedef enum {
|
|||
*/
|
||||
typedef struct {
|
||||
CO_CANmodule_t* CANdevTx; /**< From CO_SDOserver_init() */
|
||||
CO_CANtx_t* CANtxBuff; /**< CAN transmit buffer inside CANdevTx for CAN tx message */
|
||||
CO_CANtx_t* CANtxBuff; /**< CAN transmit buffer inside CANdevTx */
|
||||
OD_t* OD; /**< From CO_SDOserver_init() */
|
||||
uint8_t nodeId; /**< From CO_SDOserver_init() */
|
||||
bool_t valid; /**< If true, SDO channel is valid */
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@
|
|||
#if ((CO_CONFIG_SYNC)&CO_CONFIG_SYNC_ENABLE) != 0
|
||||
|
||||
/*
|
||||
* Read received message from CAN module.
|
||||
* Read received frame from CAN module.
|
||||
*
|
||||
* Function will be called (by CAN receive interrupt) every time, when CAN message with correct identifier
|
||||
* Function will be called (by CAN receive interrupt) every time, when CAN frame with correct identifier
|
||||
* will be received. For more information and description of parameters see file CO_driver.h.
|
||||
*/
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -25,9 +25,9 @@
|
|||
#if ((CO_CONFIG_TIME)&CO_CONFIG_TIME_ENABLE) != 0
|
||||
|
||||
/*
|
||||
* Read received message from CAN module.
|
||||
* Read received frame from CAN module.
|
||||
*
|
||||
* Function will be called (by CAN receive interrupt) every time, when CAN message with correct identifier
|
||||
* Function will be called (by CAN receive interrupt) every time, when CAN frame with correct identifier
|
||||
* will be received. For more information and description of parameters see file CO_driver.h.
|
||||
*/
|
||||
static void
|
||||
|
|
@ -119,7 +119,7 @@ CO_TIME_init(CO_TIME_t* TIME, OD_entry_t* OD_1012_cobIdTimeStamp, CO_CANmodule_t
|
|||
TIME->isProducer = (cobIdTimeStamp & 0x40000000UL) != 0U;
|
||||
CO_FLAG_CLEAR(TIME->CANrxNew);
|
||||
|
||||
/* configure TIME consumer message reception */
|
||||
/* configure TIME consumer frame reception */
|
||||
if (TIME->isConsumer) {
|
||||
CO_ReturnError_t ret = CO_CANrxBufferInit(CANdevRx, CANdevRxIdx, cobId, 0x7FF, false, (void*)TIME,
|
||||
CO_TIME_receive);
|
||||
|
|
@ -129,7 +129,7 @@ CO_TIME_init(CO_TIME_t* TIME, OD_entry_t* OD_1012_cobIdTimeStamp, CO_CANmodule_t
|
|||
}
|
||||
|
||||
#if ((CO_CONFIG_TIME)&CO_CONFIG_TIME_PRODUCER) != 0
|
||||
/* configure TIME producer message transmission */
|
||||
/* configure TIME producer frame transmission */
|
||||
TIME->CANdevTx = CANdevTx;
|
||||
TIME->CANtxBuff = CO_CANtxBufferInit(CANdevTx, CANdevTxIdx, cobId, false, CO_TIME_MSG_LENGTH, false);
|
||||
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ typedef struct {
|
|||
uint32_t producerInterval_ms; /**< Interval for time producer in milli seconds */
|
||||
uint32_t producerTimer_ms; /**< Sync producer timer */
|
||||
CO_CANmodule_t* CANdevTx; /**< From CO_TIME_init() */
|
||||
CO_CANtx_t* CANtxBuff; /**< CAN transmit buffer */
|
||||
CO_CANtx_t* CANtxBuff; /**< CAN transmit buffer inside CANdevTx */
|
||||
#endif
|
||||
#if (((CO_CONFIG_TIME)&CO_CONFIG_FLAG_CALLBACK_PRE) != 0) || defined CO_DOXYGEN
|
||||
void (*pFunctSignalPre)(void* object); /**< From CO_TIME_initCallbackPre() or NULL */
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ extern "C" {
|
|||
* objects. Callbacks can optionally be registered by application, which
|
||||
* configures threads in operating system. Callbacks are called after something
|
||||
* has been preprocessed by higher priority thread and must be further
|
||||
* processed by lower priority thread. For example when CAN message is received
|
||||
* processed by lower priority thread. For example when CAN frame is received
|
||||
* and preprocessed, callback should wake up mainline processing function.
|
||||
* See also @ref CO_process() function.
|
||||
*
|
||||
|
|
@ -130,7 +130,7 @@ extern "C" {
|
|||
* CO_NMT_initCallbackChanged().
|
||||
* - CO_CONFIG_NMT_MASTER - Enable simple NMT master
|
||||
* - #CO_CONFIG_FLAG_CALLBACK_PRE - Enable custom callback after preprocessing
|
||||
* received NMT CAN message.
|
||||
* received NMT CANopen message.
|
||||
* Callback is configured by CO_NMT_initCallbackPre().
|
||||
* - #CO_CONFIG_FLAG_TIMERNEXT - Enable calculation of timerNext_us variable
|
||||
* inside CO_NMT_process().
|
||||
|
|
@ -158,7 +158,7 @@ extern "C" {
|
|||
* - CO_CONFIG_HB_CONS_QUERY_FUNCT - Enable functions for query HB state or
|
||||
* NMT state of the specific monitored node.
|
||||
* - #CO_CONFIG_FLAG_CALLBACK_PRE - Enable custom callback after preprocessing
|
||||
* received heartbeat CAN message.
|
||||
* received heartbeat CANopen message.
|
||||
* Callback is configured by CO_HBconsumer_initCallbackPre().
|
||||
* - #CO_CONFIG_FLAG_TIMERNEXT - Enable calculation of timerNext_us variable
|
||||
* inside CO_HBconsumer_process().
|
||||
|
|
@ -345,7 +345,7 @@ extern "C" {
|
|||
* - CO_CONFIG_SDO_SRV_BLOCK - Enable SDO server block transfer. If set, then
|
||||
* CO_CONFIG_SDO_SRV_SEGMENTED must also be set.
|
||||
* - #CO_CONFIG_FLAG_CALLBACK_PRE - Enable custom callback after preprocessing
|
||||
* received SDO CAN message.
|
||||
* received SDO CANopen message.
|
||||
* Callback is configured by CO_SDOserver_initCallbackPre().
|
||||
* - #CO_CONFIG_FLAG_TIMERNEXT - Enable calculation of timerNext_us variable
|
||||
* inside CO_SDOserver_process().
|
||||
|
|
@ -384,7 +384,7 @@ extern "C" {
|
|||
* server is the same as node-ID of the SDO client. (SDO client is the same
|
||||
* device as SDO server.) Transfer data directly without communication on CAN.
|
||||
* - #CO_CONFIG_FLAG_CALLBACK_PRE - Enable custom callback after preprocessing
|
||||
* received SDO CAN message.
|
||||
* received SDO CANopen message.
|
||||
* Callback is configured by CO_SDOclient_initCallbackPre().
|
||||
* - #CO_CONFIG_FLAG_TIMERNEXT - Enable calculation of timerNext_us variable
|
||||
* inside CO_SDOclientDownloadInitiate(), CO_SDOclientDownload(),
|
||||
|
|
@ -428,7 +428,7 @@ extern "C" {
|
|||
* - CO_CONFIG_TIME_ENABLE - Enable TIME object and TIME consumer.
|
||||
* - CO_CONFIG_TIME_PRODUCER - Enable TIME producer.
|
||||
* - #CO_CONFIG_FLAG_CALLBACK_PRE - Enable custom callback after preprocessing
|
||||
* received TIME CAN message.
|
||||
* received TIME CANopen message.
|
||||
* Callback is configured by CO_TIME_initCallbackPre().
|
||||
* - #CO_CONFIG_FLAG_OD_DYNAMIC - Enable dynamic configuration - writing to
|
||||
* object 0x1012 enables / disables time producer or consumer.
|
||||
|
|
@ -452,7 +452,7 @@ extern "C" {
|
|||
* - CO_CONFIG_SYNC_ENABLE - Enable SYNC object and SYNC consumer.
|
||||
* - CO_CONFIG_SYNC_PRODUCER - Enable SYNC producer.
|
||||
* - #CO_CONFIG_FLAG_CALLBACK_PRE - Enable custom callback after preprocessing
|
||||
* received SYNC CAN message.
|
||||
* received SYNC CANopen message.
|
||||
* Callback is configured by CO_SYNC_initCallbackPre().
|
||||
* - #CO_CONFIG_FLAG_TIMERNEXT - Enable calculation of timerNext_us variable
|
||||
* inside CO_SYNC_process().
|
||||
|
|
@ -488,7 +488,7 @@ extern "C" {
|
|||
* this field stores the number of bits mapped to the PDO. Bitwise PDO mapping
|
||||
* is not possible without CO_CONFIG_PDO_OD_IO_ACCESS
|
||||
* - #CO_CONFIG_FLAG_CALLBACK_PRE - Enable custom callback after preprocessing
|
||||
* received RPDO CAN message.
|
||||
* received RPDO CANopen message.
|
||||
* Callback is configured by CO_RPDO_initCallbackPre().
|
||||
* - #CO_CONFIG_FLAG_TIMERNEXT - Enable calculation of timerNext_us variable
|
||||
* inside CO_TPDO_process().
|
||||
|
|
@ -572,7 +572,7 @@ extern "C" {
|
|||
* - CO_CONFIG_SRDO_ENABLE - Enable the SRDO object.
|
||||
* - CO_CONFIG_SRDO_CHECK_TX - Enable checking data before sending.
|
||||
* - #CO_CONFIG_FLAG_CALLBACK_PRE - Enable custom callback after preprocessing
|
||||
* received RSRDO CAN message.
|
||||
* received RSRDO CANopen message.
|
||||
* Callback is configured by CO_SRDO_initCallbackPre().
|
||||
* - #CO_CONFIG_FLAG_TIMERNEXT - Enable calculation of timerNext_us variable
|
||||
* inside CO_SRDO_process() (Tx SRDO only).
|
||||
|
|
@ -586,8 +586,7 @@ extern "C" {
|
|||
/**
|
||||
* SRDO Tx time delay
|
||||
*
|
||||
* minimum time between the first and second SRDO (Tx) message
|
||||
* in us
|
||||
* minimum time between the first and second SRDO (Tx) CANopen message in us
|
||||
*/
|
||||
#ifdef CO_DOXYGEN
|
||||
#define CO_CONFIG_SRDO_MINIMUM_DELAY 0
|
||||
|
|
@ -608,7 +607,7 @@ extern "C" {
|
|||
* directly from CO_LSSslave_receive() function.
|
||||
* - CO_CONFIG_LSS_MASTER - Enable LSS master
|
||||
* - #CO_CONFIG_FLAG_CALLBACK_PRE - Enable custom callback after preprocessing
|
||||
* received CAN message.
|
||||
* received CAN frame.
|
||||
* Callback is configured by CO_LSSmaster_initCallbackPre().
|
||||
*/
|
||||
#ifdef CO_DOXYGEN
|
||||
|
|
@ -664,8 +663,8 @@ extern "C" {
|
|||
/**
|
||||
* Number of loops of #CO_SDOclientDownload() in case of block download
|
||||
*
|
||||
* If SDO clint has block download in progress and OS has buffer for CAN tx
|
||||
* messages, then #CO_SDOclientDownload() functionion can be called multiple
|
||||
* If SDO client has block download in progress and OS has buffer for CAN tx
|
||||
* frames, then #CO_SDOclientDownload() function can be called multiple
|
||||
* times within own loop (up to 127). This can speed-up SDO block transfer.
|
||||
*/
|
||||
#ifdef CO_DOXYGEN
|
||||
|
|
|
|||
121
301/CO_driver.h
121
301/CO_driver.h
|
|
@ -59,7 +59,7 @@ extern "C" {
|
|||
* @ingroup CO_CANopen_301
|
||||
* @{
|
||||
* CANopenNode is designed for speed and portability. It runs efficiently on devices from simple 16-bit microcontrollers
|
||||
* to PC computers. It can run in multiple threads. Reception of CAN messages is pre-processed with very fast functions.
|
||||
* to PC computers. It can run in multiple threads. Reception of CAN frames is pre-processed with very fast functions.
|
||||
* Time critical objects, such as PDO or SYNC are processed in real-time thread and other objects are processed in
|
||||
* normal thread. See Flowchart in [README.md](index.html) for more information.
|
||||
*
|
||||
|
|
@ -69,8 +69,13 @@ extern "C" {
|
|||
* Heartbeat, etc. Code is written in C language and tries to be object oriented. So each CANopenNode Object is
|
||||
* implemented in a pair of .h/.c files. It basically contains a structure with all necessary variables and some
|
||||
* functions which operates on it. CANopenNode Object is usually connected with one or more CAN receive or transmit
|
||||
* Message Objects. (CAN message Object is a CAN message with specific 11-bit CAN identifier (usually one fixed or a
|
||||
* range).)
|
||||
* frames.
|
||||
*
|
||||
* #### Terminology
|
||||
* - **CAN frame** is a single CAN frame, which is transmitted or received on the CAN bus. By default it consists of
|
||||
* 11-bit identifier, 0-8 bytes of data, and some control bits.
|
||||
* - **CANopen message** is an application-layer message in the CANopen protocol that defines the meaning of a CAN frame
|
||||
* (e.g., PDO, SDO, NMT, EMCY) and represents structured communication between devices on top of the CAN bus.
|
||||
*
|
||||
* #### Hardware interface of CANopenNode
|
||||
* It consists of minimum three files:
|
||||
|
|
@ -137,35 +142,35 @@ typedef double float64_t; /**< REAL64 in CANopen (0011h), double precision float
|
|||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup CO_CAN_Message_reception Reception of CAN messages
|
||||
* @defgroup CO_CAN_Frame_reception Reception of CAN frames
|
||||
* @{
|
||||
*
|
||||
* Target specific definitions and description of CAN message reception
|
||||
* Target specific definitions and description of CAN frame reception
|
||||
*
|
||||
* CAN messages in CANopenNode are usually received by its own thread or higher priority interrupt. Received CAN
|
||||
* messages are first filtered by hardware or by software. Thread then examines its 11-bit CAN-id and mask and
|
||||
* CAN frames in CANopenNode are usually received by its own thread or higher priority interrupt. Received CAN
|
||||
* frames are first filtered by hardware or by software. Thread then examines its 11-bit CAN-id and mask and
|
||||
* determines, to which \ref CO_obj "CANopenNode Object" it belongs to. After that it calls predefined CANrx_callback()
|
||||
* function, which quickly pre-processes the message and fetches the relevant data. CANrx_callback() function is defined
|
||||
* function, which quickly pre-processes the frame and fetches the relevant data. CANrx_callback() function is defined
|
||||
* by each \ref CO_obj "CANopenNode Object" separately. Pre-processed fetched data are later processed in another
|
||||
* thread.
|
||||
*
|
||||
* If \ref CO_obj "CANopenNode Object" reception of specific CAN message, it must first configure its own CO_CANrx_t
|
||||
* If \ref CO_obj "CANopenNode Object" reception of specific CAN frame, it must first configure its own CO_CANrx_t
|
||||
* object with the CO_CANrxBufferInit() function.
|
||||
*/
|
||||
|
||||
/**
|
||||
* CAN receive callback function which pre-processes received CAN message
|
||||
* CAN receive callback function which pre-processes received CAN frame
|
||||
*
|
||||
* It is called by fast CAN receive thread. Each \ref CO_obj "CANopenNode Object" defines its own and registers it with
|
||||
* CO_CANrxBufferInit(), by passing function pointer.
|
||||
*
|
||||
* @param object pointer to specific \ref CO_obj "CANopenNode Object", registered with CO_CANrxBufferInit()
|
||||
* @param rxMsg pointer to received CAN message
|
||||
* @param rxMsg pointer to received CAN frame
|
||||
*/
|
||||
void CANrx_callback(void* object, void* rxMsg);
|
||||
|
||||
/**
|
||||
* CANrx_callback() can read CAN identifier from received CAN message
|
||||
* CANrx_callback() can read CAN identifier from received CAN frame
|
||||
*
|
||||
* Must be defined in the **CO_driver_target.h** file.
|
||||
*
|
||||
|
|
@ -173,7 +178,7 @@ void CANrx_callback(void* object, void* rxMsg);
|
|||
* inline function or macro. `rxMsg` parameter should cast to a pointer to structure. For best efficiency structure may
|
||||
* have the same alignment as CAN registers inside CAN module.
|
||||
*
|
||||
* @param rxMsg Pointer to received message
|
||||
* @param rxMsg Pointer to received frame
|
||||
* @return 11-bit CAN standard identifier.
|
||||
*/
|
||||
static inline uint16_t
|
||||
|
|
@ -182,11 +187,11 @@ CO_CANrxMsg_readIdent(void* rxMsg) {
|
|||
}
|
||||
|
||||
/**
|
||||
* CANrx_callback() can read Data Length Code from received CAN message
|
||||
* CANrx_callback() can read Data Length Code from received CAN frame
|
||||
*
|
||||
* See also CO_CANrxMsg_readIdent():
|
||||
*
|
||||
* @param rxMsg Pointer to received message
|
||||
* @param rxMsg Pointer to received CAN frame
|
||||
* @return data length in bytes (0 to 8)
|
||||
*/
|
||||
static inline uint8_t
|
||||
|
|
@ -195,11 +200,11 @@ CO_CANrxMsg_readDLC(void* rxMsg) {
|
|||
}
|
||||
|
||||
/**
|
||||
* CANrx_callback() can read pointer to data from received CAN message
|
||||
* CANrx_callback() can read pointer to data from received CAN frame
|
||||
*
|
||||
* See also CO_CANrxMsg_readIdent():
|
||||
*
|
||||
* @param rxMsg Pointer to received message
|
||||
* @param rxMsg Pointer to received frame
|
||||
* @return pointer to data buffer
|
||||
*/
|
||||
static inline const uint8_t*
|
||||
|
|
@ -208,7 +213,7 @@ CO_CANrxMsg_readData(void* rxMsg) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Configuration object for CAN received message for specific \ref CO_obj "CANopenNode Object".
|
||||
* Configuration object for received CAN frame for specific \ref CO_obj "CANopenNode Object".
|
||||
*
|
||||
* Must be defined in the **CO_driver_target.h** file.
|
||||
*
|
||||
|
|
@ -226,21 +231,21 @@ typedef struct {
|
|||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup CO_CAN_Message_transmission Transmission of CAN messages
|
||||
* @defgroup CO_CAN_Frame_transmission Transmission of CAN frames
|
||||
* @{
|
||||
*
|
||||
* Target specific definitions and description of CAN message transmission
|
||||
* Target specific definitions and description of CAN frame transmission
|
||||
*
|
||||
* If \ref CO_obj "CANopenNode Object" needs transmitting CAN message, it must first configure its own CO_CANtx_t object
|
||||
* with the CO_CANtxBufferInit() function. CAN message can then be sent with CO_CANsend() function. If at that moment
|
||||
* CAN transmit buffer inside microcontroller's CAN module is free, message is copied directly to the CAN module.
|
||||
* Otherwise CO_CANsend() function sets _bufferFull_ flag to true. Message will be then sent by CAN TX interrupt as soon
|
||||
* as CAN module is freed. Until message is not copied to CAN module, its contents must not change. If there are
|
||||
* If \ref CO_obj "CANopenNode Object" needs transmitting CAN frame, it must first configure its own CO_CANtx_t object
|
||||
* with the CO_CANtxBufferInit() function. CAN frame can then be sent with CO_CANsend() function. If at that moment
|
||||
* CAN transmit buffer inside microcontroller's CAN module is free, frame is copied directly to the CAN module.
|
||||
* Otherwise CO_CANsend() function sets _bufferFull_ flag to true. Frame will be then sent by CAN TX interrupt as soon
|
||||
* as CAN module is freed. Until frame is not copied to CAN module, its contents must not change. If there are
|
||||
* multiple CO_CANtx_t objects with _bufferFull_ flag set to true, then CO_CANtx_t with lower index will be sent first.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Configuration object for CAN transmit message for specific \ref CO_obj "CANopenNode Object".
|
||||
* Configuration object for transmit CAN frame for specific \ref CO_obj "CANopenNode Object".
|
||||
*
|
||||
* Must be defined in the **CO_driver_target.h** file.
|
||||
*
|
||||
|
|
@ -249,10 +254,10 @@ typedef struct {
|
|||
*/
|
||||
typedef struct {
|
||||
uint32_t ident; /**< CAN identifier as aligned in CAN module */
|
||||
uint8_t DLC; /**< Length of CAN message */
|
||||
uint8_t DLC; /**< Length of CAN frame */
|
||||
uint8_t data[8]; /**< 8 data bytes */
|
||||
volatile bool_t bufferFull; /**< True if previous message is still in the buffer */
|
||||
volatile bool_t syncFlag; /**< Synchronous PDO messages has this flag set. It prevents them to be sent outside the
|
||||
volatile bool_t bufferFull; /**< True if previous frame is still in the buffer */
|
||||
volatile bool_t syncFlag; /**< Synchronous PDO frames has this flag set. It prevents them to be sent outside the
|
||||
synchronous window */
|
||||
} CO_CANtx_t;
|
||||
|
||||
|
|
@ -275,14 +280,14 @@ typedef struct {
|
|||
volatile bool_t CANnormal; /**< CAN module is in normal mode */
|
||||
volatile bool_t useCANrxFilters; /**< Value different than zero indicates, that CAN module hardware filters are used
|
||||
for CAN reception. If there is not enough hardware filters, they won't be used.
|
||||
In this case will be *all* received CAN messages processed by software. */
|
||||
volatile bool_t bufferInhibitFlag; /**< If flag is true, then message in transmit buffer is synchronous PDO message,
|
||||
In this case will be *all* received CAN frames processed by software. */
|
||||
volatile bool_t bufferInhibitFlag; /**< If flag is true, then frame in transmit buffer is synchronous PDO message,
|
||||
which will be aborted, if CO_clearPendingSyncPDOs() function will be called by
|
||||
application. This may be necessary if Synchronous window time was expired. */
|
||||
volatile bool_t
|
||||
firstCANtxMessage; /**< Equal to 1, when the first transmitted message (bootup message) is in CAN TX buffers */
|
||||
firstCANtxMessage; /**< Equal to 1, when the first transmitted frame (bootup message) is in CAN TX buffers */
|
||||
volatile uint16_t
|
||||
CANtxCount; /**< Number of messages in transmit buffer, which are waiting to be copied to the CAN module */
|
||||
CANtxCount; /**< Number of frames in transmit buffer, which are waiting to be copied to the CAN module */
|
||||
uint32_t errOld; /**< Previous state of CAN errors */
|
||||
} CO_CANmodule_t;
|
||||
|
||||
|
|
@ -344,10 +349,10 @@ typedef struct {
|
|||
* (e.g. when using a RTOS), you should always lock the OD.
|
||||
*
|
||||
* #### Synchronization functions for CAN receive
|
||||
* After CAN message is received, it is pre-processed in CANrx_callback(), which copies some data into appropriate
|
||||
* object and at the end sets **new_message** flag. This flag is then pooled in another thread, which further processes
|
||||
* the message. The problem is, that compiler optimization may shuffle memory operations, so it is necessary to ensure,
|
||||
* that **new_message** flag is surely set at the end. It is necessary to use [Memory
|
||||
* After CAN frame is received, it is pre-processed in CANrx_callback(), which copies some data into appropriate
|
||||
* object and at the end sets **new_frame** flag. This flag is then pooled in another thread, which further processes
|
||||
* the data. The problem is, that compiler optimization may shuffle memory operations, so it is necessary to ensure,
|
||||
* that **new_frame** flag is surely set at the end. It is necessary to use [Memory
|
||||
* barrier](https://en.wikipedia.org/wiki/Memory_barrier).
|
||||
*
|
||||
* If receive function runs inside IRQ, no further synchronization is needed. Otherwise, some kind of synchronization
|
||||
|
|
@ -362,15 +367,15 @@ typedef struct {
|
|||
#define CO_LOCK_OD(CAN_MODULE) /**< Lock critical section when accessing Object Dictionary */
|
||||
#define CO_UNLOCK_OD(CAN_MODULE) /**< Unock critical section when accessing Object Dictionary */
|
||||
|
||||
/** Check if new message has arrived */
|
||||
/** Check if new CAN frame has arrived */
|
||||
#define CO_FLAG_READ(rxNew) ((rxNew) != NULL)
|
||||
/** Set new message flag */
|
||||
/** Set new CAN frame flag */
|
||||
#define CO_FLAG_SET(rxNew) \
|
||||
{ \
|
||||
__sync_synchronize(); \
|
||||
rxNew = (void*)1L; \
|
||||
}
|
||||
/** Clear new message flag */
|
||||
/** Clear new CAN frame flag */
|
||||
#define CO_FLAG_CLEAR(rxNew) \
|
||||
{ \
|
||||
__sync_synchronize(); \
|
||||
|
|
@ -384,7 +389,7 @@ typedef struct {
|
|||
* @defgroup CO_Default_CAN_ID_t Default CANopen identifiers
|
||||
* @{
|
||||
*
|
||||
* Default CANopen identifiers for CANopen communication objects. Same as 11-bit addresses of CAN messages. These are
|
||||
* Default CANopen identifiers for CANopen communication objects. Same as 11-bit addresses of CAN frames. These are
|
||||
* default identifiers and can be changed in CANopen. Especially PDO identifiers are configured in PDO linking phase of
|
||||
* the CANopen network configuration.
|
||||
*/
|
||||
|
|
@ -401,7 +406,7 @@ typedef struct {
|
|||
#define CO_CAN_ID_TPDO_3 0x380U /**< 0x380 Default TPDO3 (+nodeID) */
|
||||
#define CO_CAN_ID_RPDO_3 0x400U /**< 0x400 Default RPDO3 (+nodeID) */
|
||||
#define CO_CAN_ID_TPDO_4 0x480U /**< 0x480 Default TPDO4 (+nodeID) */
|
||||
#define CO_CAN_ID_RPDO_4 0x500U /**< 0x500 Default RPDO5 (+nodeID) */
|
||||
#define CO_CAN_ID_RPDO_4 0x500U /**< 0x500 Default RPDO4 (+nodeID) */
|
||||
#define CO_CAN_ID_SDO_SRV 0x580U /**< 0x580 SDO response from server (+nodeID) */
|
||||
#define CO_CAN_ID_SDO_CLI 0x600U /**< 0x600 SDO request from client (+nodeID) */
|
||||
#define CO_CAN_ID_HEARTBEAT 0x700U /**< 0x700 Heartbeat message */
|
||||
|
|
@ -452,11 +457,11 @@ typedef enum {
|
|||
CO_ERROR_OUT_OF_MEMORY = -2, /**< Memory allocation failed */
|
||||
CO_ERROR_TIMEOUT = -3, /**< Function timeout */
|
||||
CO_ERROR_ILLEGAL_BAUDRATE = -4, /**< Illegal baudrate passed to function CO_CANmodule_init() */
|
||||
CO_ERROR_RX_OVERFLOW = -5, /**< Previous message was not processed yet */
|
||||
CO_ERROR_RX_OVERFLOW = -5, /**< Previous CAN frame was not processed yet */
|
||||
CO_ERROR_RX_PDO_OVERFLOW = -6, /**< previous PDO was not processed yet */
|
||||
CO_ERROR_RX_MSG_LENGTH = -7, /**< Wrong receive message length */
|
||||
CO_ERROR_RX_MSG_LENGTH = -7, /**< Wrong receive CAN frame length */
|
||||
CO_ERROR_RX_PDO_LENGTH = -8, /**< Wrong receive PDO length */
|
||||
CO_ERROR_TX_OVERFLOW = -9, /**< Previous message is still waiting, buffer full */
|
||||
CO_ERROR_TX_OVERFLOW = -9, /**< Previous CAN frame is still waiting, buffer full */
|
||||
CO_ERROR_TX_PDO_WINDOW = -10, /**< Synchronous TPDO is outside window */
|
||||
CO_ERROR_TX_UNCONFIGURED = -11, /**< Transmit buffer was not configured properly */
|
||||
CO_ERROR_OD_PARAMETERS = -12, /**< Error in Object Dictionary parameters */
|
||||
|
|
@ -491,9 +496,9 @@ void CO_CANsetNormalMode(CO_CANmodule_t* CANmodule);
|
|||
*
|
||||
* @param CANmodule This object will be initialized.
|
||||
* @param CANptr Pointer to CAN device.
|
||||
* @param rxArray Array for handling received CAN messages
|
||||
* @param rxArray Array for handling received CAN frames
|
||||
* @param rxSize Size of the above array. Must be equal to number of receiving CAN objects.
|
||||
* @param txArray Array for handling transmitting CAN messages
|
||||
* @param txArray Array for handling transmitting CAN frames
|
||||
* @param txSize Size of the above array. Must be equal to number of transmitting CAN objects.
|
||||
* @param CANbitRate Valid values are (in kbps): 10, 20, 50, 125, 250, 500, 800, 1000. If value is illegal, bitrate
|
||||
* defaults to 125.
|
||||
|
|
@ -511,7 +516,7 @@ CO_ReturnError_t CO_CANmodule_init(CO_CANmodule_t* CANmodule, void* CANptr, CO_C
|
|||
void CO_CANmodule_disable(CO_CANmodule_t* CANmodule);
|
||||
|
||||
/**
|
||||
* Configure CAN message receive buffer.
|
||||
* Configure CAN frame receive buffer.
|
||||
*
|
||||
* Function configures specific CAN receive buffer. It sets CAN identifier and connects buffer with specific object.
|
||||
* Function must be called for each member in _rxArray_ from CO_CANmodule_t.
|
||||
|
|
@ -520,12 +525,12 @@ void CO_CANmodule_disable(CO_CANmodule_t* CANmodule);
|
|||
* @param index Index of the specific buffer in _rxArray_.
|
||||
* @param ident 11-bit standard CAN Identifier. If two or more CANrx buffers have the same _ident_, then buffer with
|
||||
* lowest _index_ has precedence and other CANrx buffers will be ignored.
|
||||
* @param mask 11-bit mask for identifier. Most usually set to 0x7FF. Received message (rcvMsg) will be accepted if the
|
||||
* following condition is true: (((rcvMsgId ^ ident) & mask) == 0).
|
||||
* @param rtr If true, 'Remote Transmit Request' messages will be accepted.
|
||||
* @param mask 11-bit mask for identifier. Most usually set to 0x7FF. Received CAN frame (rcvMsg) will be accepted
|
||||
* if the following condition is true: (((rcvMsgId ^ ident) & mask) == 0).
|
||||
* @param rtr If true, 'Remote Transmit Request' CAN frames will be accepted.
|
||||
* @param object CANopen object, to which buffer is connected. It will be used as an argument to CANrx_callback. Its
|
||||
* type is (void), CANrx_callback will change its type back to the correct object type.
|
||||
* @param CANrx_callback Pointer to function, which will be called, if received CAN message matches the identifier. It
|
||||
* @param CANrx_callback Pointer to function, which will be called, if received CAN frame matches the identifier. It
|
||||
* must be fast function.
|
||||
*
|
||||
* Return #CO_ReturnError_t: CO_ERROR_NO CO_ERROR_ILLEGAL_ARGUMENT or CO_ERROR_OUT_OF_MEMORY (not enough masks for
|
||||
|
|
@ -535,7 +540,7 @@ CO_ReturnError_t CO_CANrxBufferInit(CO_CANmodule_t* CANmodule, uint16_t index, u
|
|||
bool_t rtr, void* object, void (*CANrx_callback)(void* object, void* message));
|
||||
|
||||
/**
|
||||
* Configure CAN message transmit buffer.
|
||||
* Configure CAN frame transmit buffer.
|
||||
*
|
||||
* Function configures specific CAN transmit buffer. Function must be called for each member in _txArray_ from
|
||||
* CO_CANmodule_t.
|
||||
|
|
@ -543,19 +548,19 @@ CO_ReturnError_t CO_CANrxBufferInit(CO_CANmodule_t* CANmodule, uint16_t index, u
|
|||
* @param CANmodule This object.
|
||||
* @param index Index of the specific buffer in _txArray_.
|
||||
* @param ident 11-bit standard CAN Identifier.
|
||||
* @param rtr If true, 'Remote Transmit Request' messages will be transmitted.
|
||||
* @param noOfBytes Length of CAN message in bytes (0 to 8 bytes).
|
||||
* @param syncFlag This flag bit is used for synchronous TPDO messages. If it is set, message will not be sent, if
|
||||
* @param rtr If true, 'Remote Transmit Request' CAN frames will be transmitted.
|
||||
* @param noOfBytes Length of CAN frame in bytes (0 to 8 bytes).
|
||||
* @param syncFlag This flag bit is used for synchronous TPDO messages. If it is set, CAN frame will not be sent, if
|
||||
* current time is outside synchronous window.
|
||||
*
|
||||
* @return Pointer to CAN transmit message buffer. 8 bytes data array inside buffer should be written, before
|
||||
* @return Pointer to transmit CAN frame buffer. 8 bytes data array inside buffer should be written, before
|
||||
* CO_CANsend() function is called. Zero is returned in case of wrong arguments.
|
||||
*/
|
||||
CO_CANtx_t* CO_CANtxBufferInit(CO_CANmodule_t* CANmodule, uint16_t index, uint16_t ident, bool_t rtr, uint8_t noOfBytes,
|
||||
bool_t syncFlag);
|
||||
|
||||
/**
|
||||
* Send CAN message.
|
||||
* Send CAN frame.
|
||||
*
|
||||
* @param CANmodule This object.
|
||||
* @param buffer Pointer to transmit buffer, returned by CO_CANtxBufferInit(). Data bytes must be written in buffer
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ CO_SRDO_receive_normal(void* object, void* msg) {
|
|||
const uint8_t* data = CO_CANrxMsg_readData(msg);
|
||||
|
||||
if ((SRDO->informationDirection == CO_SRDO_RX) && (DLC >= SRDO->dataLength) && !CO_FLAG_READ(SRDO->CANrxNew[1])) {
|
||||
/* copy data into appropriate buffer and set 'new message' flag */
|
||||
/* copy data into appropriate buffer and set 'new frame' flag */
|
||||
(void)memcpy(SRDO->CANrxData[0], data, sizeof(SRDO->CANrxData[0]));
|
||||
CO_FLAG_SET(SRDO->CANrxNew[0]);
|
||||
|
||||
|
|
@ -74,7 +74,7 @@ CO_SRDO_receive_inverted(void* object, void* msg) {
|
|||
const uint8_t* data = CO_CANrxMsg_readData(msg);
|
||||
|
||||
if ((SRDO->informationDirection == CO_SRDO_RX) && (DLC >= SRDO->dataLength) && CO_FLAG_READ(SRDO->CANrxNew[0])) {
|
||||
/* copy data into appropriate buffer and set 'new message' flag */
|
||||
/* copy data into appropriate buffer and set 'new frame' flag */
|
||||
(void)memcpy(SRDO->CANrxData[1], data, sizeof(SRDO->CANrxData[1]));
|
||||
CO_FLAG_SET(SRDO->CANrxNew[1]);
|
||||
|
||||
|
|
@ -893,7 +893,7 @@ CO_SRDO_process(CO_SRDO_t* SRDO, uint32_t timeDifference_us, uint32_t* timerNext
|
|||
}
|
||||
}
|
||||
|
||||
/* copy data from CAN messages into mapped data from Object Dictionary */
|
||||
/* copy data from CAN frames into mapped data from Object Dictionary */
|
||||
if (data_ok) {
|
||||
size_t verifyLength[2] = {0, 0};
|
||||
for (uint8_t i = 0; i < SRDO->mappedObjectsCount; i++) {
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ typedef enum {
|
|||
CO_SRDO_state_error_internal = -10, /**< internal software error */
|
||||
CO_SRDO_state_error_configuration = -9, /**< error in parameters, emergency message was sent */
|
||||
CO_SRDO_state_error_txNotInverted = -6, /**< Transmitting SRDO messages was not inverted */
|
||||
CO_SRDO_state_error_txFail = -5, /**< SRDO CAN message transmission failed */
|
||||
CO_SRDO_state_error_txFail = -5, /**< SRDO message transmission failed */
|
||||
CO_SRDO_state_error_rxTimeoutSRVT = -4, /**< SRDO message didn't receive inside SRVT time */
|
||||
CO_SRDO_state_error_rxTimeoutSCT = -3, /**< SRDO inverted message didn't receive inside SCT time */
|
||||
CO_SRDO_state_error_rxNotInverted = -2, /**< Received SRDO messages was not inverted */
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ extern "C" {
|
|||
* @{
|
||||
*
|
||||
* The LSS protocols are executed between the LSS master device and the LSS slave device(s) to implement the LSS
|
||||
* services. Some LSS protocols require a sequence of CAN messages.
|
||||
* services. Some LSS protocols require a sequence of CAN frames.
|
||||
*
|
||||
* As identifying method only "LSS fastscan" is supported.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -64,9 +64,9 @@
|
|||
/* @} */ /* CO_LSSmaster_fs_t */
|
||||
|
||||
/*
|
||||
* Read received message from CAN module.
|
||||
* Read received frame from CAN module.
|
||||
*
|
||||
* Function will be called (by CAN receive interrupt) every time, when CAN message with correct identifier
|
||||
* Function will be called (by CAN receive interrupt) every time, when CAN frame with correct identifier
|
||||
* will be received. For more information and description of parameters see file CO_driver.h.
|
||||
*/
|
||||
static void
|
||||
|
|
@ -77,10 +77,10 @@ CO_LSSmaster_receive(void* object, void* msg) {
|
|||
|
||||
LSSmaster = (CO_LSSmaster_t*)object; /* this is the correct pointer type of the first argument */
|
||||
|
||||
/* verify message length and message overflow (previous message was not processed yet). */
|
||||
/* verify frame length and frame overflow (previous frame was not processed yet). */
|
||||
if ((DLC == 8U) && !CO_FLAG_READ(LSSmaster->CANrxNew) && (LSSmaster->command != CO_LSSmaster_COMMAND_WAITING)) {
|
||||
|
||||
/* copy data and set 'new message' flag */
|
||||
/* copy data and set 'new frame' flag */
|
||||
(void)memcpy(LSSmaster->CANrxData, data, sizeof(LSSmaster->CANrxData));
|
||||
|
||||
CO_FLAG_SET(LSSmaster->CANrxNew);
|
||||
|
|
@ -134,11 +134,11 @@ CO_LSSmaster_init(CO_LSSmaster_t* LSSmaster, uint16_t timeout_ms, CO_CANmodule_t
|
|||
LSSmaster->functSignalObject = NULL;
|
||||
#endif
|
||||
|
||||
/* configure LSS CAN Slave response message reception */
|
||||
/* configure LSS CANopen Slave response message reception */
|
||||
ret = CO_CANrxBufferInit(CANdevRx, CANdevRxIdx, CANidLssSlave, 0x7FF, false, (void*)LSSmaster,
|
||||
CO_LSSmaster_receive);
|
||||
|
||||
/* configure LSS CAN Master message transmission */
|
||||
/* configure LSS CANopen Master message transmission */
|
||||
LSSmaster->CANdevTx = CANdevTx;
|
||||
LSSmaster->TXbuff = CO_CANtxBufferInit(CANdevTx, CANdevTxIdx, CANidLssMaster, false, 8, false);
|
||||
|
||||
|
|
|
|||
|
|
@ -34,9 +34,9 @@
|
|||
#define CO_LSS_BIT_TIMING_VALID(index) ((index != 5U) && (index <= CO_LSS_BIT_TIMING_AUTO))
|
||||
|
||||
/*
|
||||
* Read received message from CAN module.
|
||||
* Read received frame from CAN module.
|
||||
*
|
||||
* Function will be called (by CAN receive interrupt) every time, when CAN message with correct identifier
|
||||
* Function will be called (by CAN receive interrupt) every time, when CAN frame with correct identifier
|
||||
* will be received. For more information and description of parameters see file CO_driver.h.
|
||||
*/
|
||||
static void
|
||||
|
|
@ -205,10 +205,10 @@ CO_LSSslave_init(CO_LSSslave_t* LSSslave, CO_LSS_address_t* lssAddress, uint16_t
|
|||
LSSslave->activeNodeID = *pendingNodeID;
|
||||
CO_FLAG_CLEAR(LSSslave->sendResponse);
|
||||
|
||||
/* configure LSS CAN Master message reception */
|
||||
/* configure LSS CANopen Master message reception */
|
||||
ret = CO_CANrxBufferInit(CANdevRx, CANdevRxIdx, CANidLssMaster, 0x7FF, false, (void*)LSSslave, CO_LSSslave_receive);
|
||||
|
||||
/* configure LSS CAN Slave response message transmission */
|
||||
/* configure LSS CANopen Slave response message transmission */
|
||||
LSSslave->CANdevTx = CANdevTx;
|
||||
LSSslave->TXbuff = CO_CANtxBufferInit(CANdevTx, CANdevTxIdx, CANidLssSlave, false, 8, false);
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ extern "C" {
|
|||
* or stdio in OS or sockets, etc.
|
||||
*
|
||||
* For example, one wants to read 'Heartbeat producer time' parameter (0x1017,0) on remote node (with id=4). Parameter
|
||||
* is 16-bit integer. He can can enter command string: `[1] 4 read 0x1017 0 i16`. CANopenNode will use SDO client, send
|
||||
* is 16-bit integer. He can enter command string: `[1] 4 read 0x1017 0 i16`. CANopenNode will use SDO client, send
|
||||
* request to remote node via CAN, wait for response via CAN and prints `[1] OK` to output stream on success.
|
||||
*
|
||||
* This module is usually initialized and processed in CANopen.c file. Application should register own callback function
|
||||
|
|
|
|||
|
|
@ -34,10 +34,10 @@
|
|||
|
||||
/* Verify parameters from "OD.h" and calculate necessary values for each object:
|
||||
* - verify OD_CNT_xx or set default
|
||||
* - calculate number of CANrx and CYNtx messages: CO_RX_CNT_xx and CO_TX_CNT_xx
|
||||
* - calculate number of CANrx and CANtx frames: CO_RX_CNT_xx and CO_TX_CNT_xx
|
||||
* - set optional undefined OD_ENTRY_Hxxxx to NULL.
|
||||
* - calculate indexes: CO_RX_IDX_xx and CO_TX_IDX_xx
|
||||
* - calculate total count of CAN message buffers: CO_CNT_ALL_RX_MSGS and CO_CNT_ALL_TX_MSGS. */
|
||||
* - calculate total count of CAN frame buffers: CO_CNT_ALL_RX_MSGS and CO_CNT_ALL_TX_MSGS. */
|
||||
#if OD_CNT_NMT != 1
|
||||
#error OD_CNT_NMT from OD.h not correct!
|
||||
#endif
|
||||
|
|
@ -347,9 +347,9 @@ CO_new(CO_config_t* config, uint32_t* heapMemoryUsed) {
|
|||
* - allocate memory, verify allocation and calculate size of heap used
|
||||
* - if CO_MULTIPLE_OD is defined:
|
||||
* - use config structure
|
||||
* - calculate number of CANrx and CYNtx messages: RX_CNT_xx and TX_CNT_xx
|
||||
* - calculate number of CANrx and CANtx frames: RX_CNT_xx and TX_CNT_xx
|
||||
* - calculate indexes: RX_IDX_xx and TX_IDX_xx
|
||||
* - calculate total count of CAN message buffers: CNT_ALL_RX_MSGS and CNT_ALL_TX_MSGS. */
|
||||
* - calculate total count of CAN frame buffers: CNT_ALL_RX_MSGS and CNT_ALL_TX_MSGS. */
|
||||
do {
|
||||
#ifdef CO_MULTIPLE_OD
|
||||
/* verify arguments */
|
||||
|
|
|
|||
|
|
@ -243,11 +243,11 @@ typedef struct {
|
|||
CO_config_t* config; /**< Remember the configuration parameters */
|
||||
#endif
|
||||
CO_CANmodule_t* CANmodule; /**< One CAN module object, initialised by @ref CO_CANmodule_init() */
|
||||
CO_CANrx_t* CANrx; /**< CAN receive message objects */
|
||||
CO_CANtx_t* CANtx; /**< CAN transmit message objects */
|
||||
CO_CANrx_t* CANrx; /**< CAN frame receive objects */
|
||||
CO_CANtx_t* CANtx; /**< CAN frame transmit objects */
|
||||
#if defined CO_MULTIPLE_OD || defined CO_DOXYGEN
|
||||
uint16_t CNT_ALL_RX_MSGS; /**< Number of all CAN receive message objects. */
|
||||
uint16_t CNT_ALL_TX_MSGS; /**< Number of all CAN transmit message objects. */
|
||||
uint16_t CNT_ALL_RX_MSGS; /**< Number of all CAN frame receive objects. */
|
||||
uint16_t CNT_ALL_TX_MSGS; /**< Number of all CAN frame transmit objects. */
|
||||
#endif
|
||||
CO_NMT_t* NMT; /**< NMT and heartbeat object, initialised by @ref CO_NMT_init() */
|
||||
#if defined CO_MULTIPLE_OD || defined CO_DOXYGEN
|
||||
|
|
|
|||
10
README.md
10
README.md
|
|
@ -93,11 +93,11 @@ Flowchart of a typical CANopenNode implementation:
|
|||
| - Fast response. | | - Realtime thread with | | - Processing of time |
|
||||
| - Detect CAN ID. | | constant interval, | | consuming tasks |
|
||||
| - Partially process | | typically 1ms. | | in CANopen objects: |
|
||||
| messages and copy | | - Network synchronized | | - SDO server, |
|
||||
| data to target | | - Copy inputs (RPDOs, | | - Emergency, |
|
||||
| CANopen objects. | | HW) to Object Dict. | | - Network state, |
|
||||
| | | - May call application | | - Heartbeat. |
|
||||
| | | for some processing. | | - LSS slave |
|
||||
| CAN frames and | | - Network synchronized | | - SDO server, |
|
||||
| copy data to | | - Copy inputs (RPDOs, | | - Emergency, |
|
||||
| the target | | HW) to Object Dict. | | - Network state, |
|
||||
| CANopenNode | | - May call application | | - Heartbeat. |
|
||||
| objects. | | for some processing. | | - LSS slave |
|
||||
| | | - Copy variables from | | - Gateway (optional): |
|
||||
| | | Object Dictionary to | | - NMT master |
|
||||
| | | outputs (TPDOs, HW). | | - SDO client |
|
||||
|
|
|
|||
|
|
@ -77,11 +77,11 @@ CO_CANmodule_init(CO_CANmodule_t* CANmodule, void* CANptr, CO_CANrx_t rxArray[],
|
|||
/* CAN module filters are used, they will be configured with */
|
||||
/* CO_CANrxBufferInit() functions, called by separate CANopen */
|
||||
/* init functions. */
|
||||
/* Configure all masks so, that received message must match filter */
|
||||
/* Configure all masks so, that received CAN frame must match filter */
|
||||
} else {
|
||||
/* CAN module filters are not used, all messages with standard 11-bit */
|
||||
/* CAN module filters are not used, all CAN frames with standard 11-bit */
|
||||
/* identifier will be received */
|
||||
/* Configure mask 0 so, that all messages with standard identifier are accepted */
|
||||
/* Configure mask 0 so, that all CAN frames with standard identifier are accepted */
|
||||
}
|
||||
|
||||
/* configure CAN interrupt registers */
|
||||
|
|
@ -159,12 +159,12 @@ CO_CANsend(CO_CANmodule_t* CANmodule, CO_CANtx_t* buffer) {
|
|||
}
|
||||
|
||||
CO_LOCK_CAN_SEND(CANmodule);
|
||||
/* if CAN TX buffer is free, copy message to it */
|
||||
/* if CAN TX buffer is free, copy data to it */
|
||||
if (1 && CANmodule->CANtxCount == 0) {
|
||||
CANmodule->bufferInhibitFlag = buffer->syncFlag;
|
||||
/* copy message and txRequest */
|
||||
/* copy data and txRequest */
|
||||
}
|
||||
/* if no buffer is free, message will be sent by interrupt */
|
||||
/* if no buffer is free, CAN frame will be sent by interrupt */
|
||||
else {
|
||||
/* Only increment count if buffer wasn't already full */
|
||||
if (!buffer->bufferFull) {
|
||||
|
|
@ -182,9 +182,9 @@ CO_CANclearPendingSyncPDOs(CO_CANmodule_t* CANmodule) {
|
|||
uint32_t tpdoDeleted = 0U;
|
||||
|
||||
CO_LOCK_CAN_SEND(CANmodule);
|
||||
/* Abort message from CAN module, if there is synchronous TPDO.
|
||||
/* Abort frame from CAN module, if there is synchronous TPDO.
|
||||
* Take special care with this functionality. */
|
||||
if (/* messageIsOnCanBuffer && */ CANmodule->bufferInhibitFlag) {
|
||||
if (/* CAN frameIsOnCanBuffer && */ CANmodule->bufferInhibitFlag) {
|
||||
/* clear TXREQ */
|
||||
CANmodule->bufferInhibitFlag = false;
|
||||
tpdoDeleted = 1U;
|
||||
|
|
@ -274,17 +274,17 @@ CO_CANinterrupt(CO_CANmodule_t* CANmodule) {
|
|||
|
||||
/* receive interrupt */
|
||||
if (1) {
|
||||
CO_CANrxMsg_t* rcvMsg; /* pointer to received message in CAN module */
|
||||
uint16_t index; /* index of received message */
|
||||
uint32_t rcvMsgIdent; /* identifier of the received message */
|
||||
CO_CANrx_t* buffer = NULL; /* receive message buffer from CO_CANmodule_t object. */
|
||||
CO_CANrxMsg_t* rcvMsg; /* pointer to received CAN frame in CAN module */
|
||||
uint16_t index; /* index of received CAN frame */
|
||||
uint32_t rcvMsgIdent; /* identifier of the received CAN frame */
|
||||
CO_CANrx_t* buffer = NULL; /* receive CAN frame buffer from CO_CANmodule_t object. */
|
||||
bool_t msgMatched = false;
|
||||
|
||||
rcvMsg = 0; /* get message from module here */
|
||||
rcvMsg = 0; /* get CAN frame from module here */
|
||||
rcvMsgIdent = rcvMsg->ident;
|
||||
if (CANmodule->useCANrxFilters) {
|
||||
/* CAN module filters are used. Message with known 11-bit identifier has been received */
|
||||
index = 0; /* get index of the received message here. Or something similar */
|
||||
/* CAN module filters are used. CAN frame with known 11-bit identifier has been received */
|
||||
index = 0; /* get index of the received CAN frame here. Or something similar */
|
||||
if (index < CANmodule->rxSize) {
|
||||
buffer = &CANmodule->rxArray[index];
|
||||
/* verify also RTR */
|
||||
|
|
@ -293,7 +293,7 @@ CO_CANinterrupt(CO_CANmodule_t* CANmodule) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
/* CAN module filters are not used, message with any standard 11-bit identifier */
|
||||
/* CAN module filters are not used, CAN frame with any standard 11-bit identifier */
|
||||
/* has been received. Search rxArray form CANmodule for the same CAN-ID. */
|
||||
buffer = &CANmodule->rxArray[0];
|
||||
for (index = CANmodule->rxSize; index > 0U; index--) {
|
||||
|
|
@ -305,7 +305,7 @@ CO_CANinterrupt(CO_CANmodule_t* CANmodule) {
|
|||
}
|
||||
}
|
||||
|
||||
/* Call specific function, which will process the message */
|
||||
/* Call specific function, which will process the CAN frame */
|
||||
if (msgMatched && (buffer != NULL) && (buffer->CANrx_callback != NULL)) {
|
||||
buffer->CANrx_callback(buffer->object, (void*)rcvMsg);
|
||||
}
|
||||
|
|
@ -317,24 +317,24 @@ CO_CANinterrupt(CO_CANmodule_t* CANmodule) {
|
|||
else if (0) {
|
||||
/* Clear interrupt flag */
|
||||
|
||||
/* First CAN message (bootup) was sent successfully */
|
||||
/* First CAN frame (bootup) was sent successfully */
|
||||
CANmodule->firstCANtxMessage = false;
|
||||
/* clear flag from previous message */
|
||||
/* clear flag from previous CAN frame */
|
||||
CANmodule->bufferInhibitFlag = false;
|
||||
/* Are there any new messages waiting to be send */
|
||||
/* Are there any new CAN frames waiting to be send */
|
||||
if (CANmodule->CANtxCount > 0U) {
|
||||
uint16_t i; /* index of transmitting message */
|
||||
uint16_t i; /* index of transmitting CAN frame */
|
||||
|
||||
/* first buffer */
|
||||
CO_CANtx_t* buffer = &CANmodule->txArray[0];
|
||||
/* search through whole array of pointers to transmit message buffers. */
|
||||
/* search through whole array of pointers to transmit CAN frame buffers. */
|
||||
for (i = CANmodule->txSize; i > 0U; i--) {
|
||||
/* if message buffer is full, send it. */
|
||||
/* if CAN frame buffer is full, send it. */
|
||||
if (buffer->bufferFull) {
|
||||
buffer->bufferFull = false;
|
||||
CANmodule->CANtxCount--;
|
||||
|
||||
/* Copy message to CAN buffer */
|
||||
/* Copy CAN frame to CAN buffer */
|
||||
CANmodule->bufferInhibitFlag = buffer->syncFlag;
|
||||
/* canSend... */
|
||||
break; /* exit for loop */
|
||||
|
|
@ -342,7 +342,7 @@ CO_CANinterrupt(CO_CANmodule_t* CANmodule) {
|
|||
buffer++;
|
||||
} /* end of for loop */
|
||||
|
||||
/* Clear counter if no more messages */
|
||||
/* Clear counter if no more CAN frames */
|
||||
if (i == 0U) {
|
||||
CANmodule->CANtxCount = 0U;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,12 +49,12 @@ typedef uint_fast8_t bool_t;
|
|||
typedef float float32_t;
|
||||
typedef double float64_t;
|
||||
|
||||
/* Access to received CAN message */
|
||||
/* Access to received CAN frame */
|
||||
#define CO_CANrxMsg_readIdent(msg) ((uint16_t)0)
|
||||
#define CO_CANrxMsg_readDLC(msg) ((uint8_t)0)
|
||||
#define CO_CANrxMsg_readData(msg) ((const uint8_t*)NULL)
|
||||
|
||||
/* Received message object */
|
||||
/* Received frame object */
|
||||
typedef struct {
|
||||
uint16_t ident;
|
||||
uint16_t mask;
|
||||
|
|
@ -62,7 +62,7 @@ typedef struct {
|
|||
void (*CANrx_callback)(void* object, void* message);
|
||||
} CO_CANrx_t;
|
||||
|
||||
/* Transmit message object */
|
||||
/* Transmit frame object */
|
||||
typedef struct {
|
||||
uint32_t ident;
|
||||
uint8_t DLC;
|
||||
|
|
@ -109,7 +109,7 @@ typedef struct {
|
|||
#define CO_LOCK_OD(CAN_MODULE)
|
||||
#define CO_UNLOCK_OD(CAN_MODULE)
|
||||
|
||||
/* Synchronization between CAN receive and message processing threads. */
|
||||
/* Synchronization between CAN receive and data processing threads. */
|
||||
#define CO_MemoryBarrier()
|
||||
#define CO_FLAG_READ(rxNew) ((rxNew) != NULL)
|
||||
#define CO_FLAG_SET(rxNew) \
|
||||
|
|
|
|||
|
|
@ -237,7 +237,7 @@ tmrTask_thread(void) {
|
|||
}
|
||||
}
|
||||
|
||||
/* CAN interrupt function executes on received CAN message ********************/
|
||||
/* CAN interrupt function executes on received CAN frame **********************/
|
||||
void /* interrupt */
|
||||
CO_CAN1InterruptHandler(void) {
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue