Verify for restricted CAN-IDs in SYNC, TIME, EMCY, PDO and SDO COB-ID configuration.
This commit is contained in:
parent
5338f110e1
commit
fe3777b781
7 changed files with 66 additions and 30 deletions
|
|
@ -94,7 +94,7 @@ static ODR_t OD_write_1014(OD_stream_t *stream, const void *buf,
|
|||
uint16_t curCanId = em->producerCanId == CO_CAN_ID_EMERGENCY ?
|
||||
CO_CAN_ID_EMERGENCY + em->nodeId : em->producerCanId;
|
||||
bool_t newEnabled = (COB_IDEmergency32 & 0x80000000) == 0 && newCanId != 0;
|
||||
if ((COB_IDEmergency32 & 0x7FFFF800) != 0
|
||||
if ((COB_IDEmergency32 & 0x7FFFF800)!=0 || CO_IS_RESTRICTED_CAN_ID(newCanId)
|
||||
|| (em->producerEnabled && newEnabled && newCanId != curCanId)
|
||||
) {
|
||||
return ODR_INVALID_VALUE;
|
||||
|
|
|
|||
|
|
@ -540,7 +540,7 @@ static ODR_t OD_write_14xx(OD_stream_t *stream, const void *buf,
|
|||
* enabling the PDO */
|
||||
if ((COB_ID & 0x3FFFF800) != 0
|
||||
|| (valid && PDO->valid && CAN_ID != PDO->configuredCanId)
|
||||
|| (valid && CAN_ID == 0)
|
||||
|| (valid && CO_IS_RESTRICTED_CAN_ID(CAN_ID))
|
||||
|| (valid && PDO->mappedObjectsCount == 0)
|
||||
) {
|
||||
return ODR_INVALID_VALUE;
|
||||
|
|
@ -965,7 +965,7 @@ static ODR_t OD_write_18xx(OD_stream_t *stream, const void *buf,
|
|||
* enabling the PDO */
|
||||
if ((COB_ID & 0x3FFFF800) != 0
|
||||
|| (valid && PDO->valid && CAN_ID != PDO->configuredCanId)
|
||||
|| (valid && CAN_ID == 0)
|
||||
|| (valid && CO_IS_RESTRICTED_CAN_ID(CAN_ID))
|
||||
|| (valid && PDO->mappedObjectsCount == 0)
|
||||
) {
|
||||
return ODR_INVALID_VALUE;
|
||||
|
|
|
|||
|
|
@ -182,20 +182,21 @@ static ODR_t OD_write_1280(OD_stream_t *stream, const void *buf,
|
|||
}
|
||||
|
||||
CO_SDOclient_t *SDO_C = (CO_SDOclient_t *)stream->object;
|
||||
uint32_t COB_ID;
|
||||
uint8_t nodeId;
|
||||
|
||||
switch (stream->subIndex) {
|
||||
case 0: /* Highest sub-index supported */
|
||||
return ODR_READONLY;
|
||||
|
||||
case 1: /* COB-ID client -> server */
|
||||
COB_ID = CO_getUint32(buf);
|
||||
case 1: { /* COB-ID client -> server */
|
||||
uint32_t COB_ID = CO_getUint32(buf);
|
||||
uint16_t CAN_ID = (uint16_t)(COB_ID & 0x7FF);
|
||||
uint16_t CAN_ID_cur = (uint16_t)(SDO_C->COB_IDClientToServer&0x7FF);
|
||||
bool_t valid = (COB_ID & 0x80000000) == 0;
|
||||
|
||||
/* SDO client must not be valid when changing COB_ID */
|
||||
if ((COB_ID & 0x3FFFF800) != 0
|
||||
|| ((uint16_t)COB_ID != (uint16_t)SDO_C->COB_IDClientToServer
|
||||
&& SDO_C->valid && (COB_ID & 0x80000000) == 0)
|
||||
|| (valid && SDO->valid && CAN_ID != CAN_ID_cur)
|
||||
|| (valid && CO_IS_RESTRICTED_CAN_ID(CAN_ID))
|
||||
) {
|
||||
return ODR_INVALID_VALUE;
|
||||
}
|
||||
|
|
@ -204,14 +205,18 @@ static ODR_t OD_write_1280(OD_stream_t *stream, const void *buf,
|
|||
SDO_C->COB_IDServerToClient,
|
||||
SDO_C->nodeIDOfTheSDOServer);
|
||||
break;
|
||||
}
|
||||
|
||||
case 2: /* COB-ID server -> client */
|
||||
COB_ID = CO_getUint32(buf);
|
||||
case 2: { /* COB-ID server -> client */
|
||||
uint32_t COB_ID = CO_getUint32(buf);
|
||||
uint16_t CAN_ID = (uint16_t)(COB_ID & 0x7FF);
|
||||
uint16_t CAN_ID_cur = (uint16_t)(SDO_C->COB_IDServerToClient&0x7FF);
|
||||
bool_t valid = (COB_ID & 0x80000000) == 0;
|
||||
|
||||
/* SDO client must not be valid when changing COB_ID */
|
||||
if ((COB_ID & 0x3FFFF800) != 0
|
||||
|| ((uint16_t)COB_ID != (uint16_t)SDO_C->COB_IDServerToClient
|
||||
&& SDO_C->valid && (COB_ID & 0x80000000) == 0)
|
||||
|| (valid && SDO->valid && CAN_ID != CAN_ID_cur)
|
||||
|| (valid && CO_IS_RESTRICTED_CAN_ID(CAN_ID))
|
||||
) {
|
||||
return ODR_INVALID_VALUE;
|
||||
}
|
||||
|
|
@ -220,14 +225,16 @@ static ODR_t OD_write_1280(OD_stream_t *stream, const void *buf,
|
|||
COB_ID,
|
||||
SDO_C->nodeIDOfTheSDOServer);
|
||||
break;
|
||||
}
|
||||
|
||||
case 3: /* Node-ID of the SDO server */
|
||||
nodeId = CO_getUint8(buf);
|
||||
case 3: { /* Node-ID of the SDO server */
|
||||
uint8_t nodeId = CO_getUint8(buf);
|
||||
if (nodeId > 127) {
|
||||
return ODR_INVALID_VALUE;
|
||||
}
|
||||
SDO_C->nodeIDOfTheSDOServer = nodeId;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return ODR_SUB_NOT_EXIST;
|
||||
|
|
|
|||
|
|
@ -241,20 +241,21 @@ static ODR_t OD_write_1201_additional(OD_stream_t *stream, const void *buf,
|
|||
}
|
||||
|
||||
CO_SDOserver_t *SDO = (CO_SDOserver_t *)stream->object;
|
||||
uint32_t COB_ID;
|
||||
uint8_t nodeId;
|
||||
|
||||
switch (stream->subIndex) {
|
||||
case 0: /* Highest sub-index supported */
|
||||
return ODR_READONLY;
|
||||
|
||||
case 1: /* COB-ID client -> server */
|
||||
COB_ID = CO_getUint32(buf);
|
||||
case 1: { /* COB-ID client -> server */
|
||||
uint32_t COB_ID = CO_getUint32(buf);
|
||||
uint16_t CAN_ID = (uint16_t)(COB_ID & 0x7FF);
|
||||
uint16_t CAN_ID_cur = (uint16_t)(SDO->COB_IDClientToServer & 0x7FF);
|
||||
bool_t valid = (COB_ID & 0x80000000) == 0;
|
||||
|
||||
/* SDO client must not be valid when changing COB_ID */
|
||||
if ((COB_ID & 0x3FFFF800) != 0
|
||||
|| ((uint16_t)COB_ID != (uint16_t)SDO->COB_IDClientToServer
|
||||
&& SDO->valid && (COB_ID & 0x80000000))
|
||||
|| (valid && SDO->valid && CAN_ID != CAN_ID_cur)
|
||||
|| (valid && CO_IS_RESTRICTED_CAN_ID(CAN_ID))
|
||||
) {
|
||||
return ODR_INVALID_VALUE;
|
||||
}
|
||||
|
|
@ -265,14 +266,18 @@ static ODR_t OD_write_1201_additional(OD_stream_t *stream, const void *buf,
|
|||
COB_ID,
|
||||
SDO->COB_IDServerToClient);
|
||||
break;
|
||||
}
|
||||
|
||||
case 2: /* COB-ID server -> client */
|
||||
COB_ID = CO_getUint32(buf);
|
||||
case 2: { /* COB-ID server -> client */
|
||||
uint32_t COB_ID = CO_getUint32(buf);
|
||||
uint16_t CAN_ID = (uint16_t)(COB_ID & 0x7FF);
|
||||
uint16_t CAN_ID_cur = (uint16_t)(SDO->COB_IDServerToClient & 0x7FF);
|
||||
bool_t valid = (COB_ID & 0x80000000) == 0;
|
||||
|
||||
/* SDO client must not be valid when changing COB_ID */
|
||||
if ((COB_ID & 0x3FFFF800) != 0
|
||||
|| ((uint16_t)COB_ID != (uint16_t)SDO->COB_IDServerToClient
|
||||
&& SDO->valid && (COB_ID & 0x80000000))
|
||||
|| (valid && SDO->valid && CAN_ID != CAN_ID_cur)
|
||||
|| (valid && CO_IS_RESTRICTED_CAN_ID(CAN_ID))
|
||||
) {
|
||||
return ODR_INVALID_VALUE;
|
||||
}
|
||||
|
|
@ -283,16 +288,18 @@ static ODR_t OD_write_1201_additional(OD_stream_t *stream, const void *buf,
|
|||
SDO->COB_IDClientToServer,
|
||||
COB_ID);
|
||||
break;
|
||||
}
|
||||
|
||||
case 3: /* Node-ID of the SDO server */
|
||||
case 3: { /* Node-ID of the SDO server */
|
||||
if (count != 1) {
|
||||
return ODR_TYPE_MISMATCH;
|
||||
}
|
||||
nodeId = CO_getUint8(buf);
|
||||
uint8_t nodeId = CO_getUint8(buf);
|
||||
if (nodeId < 1 || nodeId > 127) {
|
||||
return ODR_INVALID_VALUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return ODR_SUB_NOT_EXIST;
|
||||
|
|
|
|||
|
|
@ -96,13 +96,13 @@ static ODR_t OD_write_1005(OD_stream_t *stream, const void *buf,
|
|||
/* verify written value */
|
||||
#if (CO_CONFIG_SYNC) & CO_CONFIG_SYNC_PRODUCER
|
||||
bool_t isProducer = (cobIdSync & 0x40000000) != 0;
|
||||
if ((cobIdSync & 0xBFFF8000) != 0
|
||||
if ((cobIdSync & 0xBFFFF800) != 0 || CO_IS_RESTRICTED_CAN_ID(CAN_ID)
|
||||
|| (SYNC->isProducer && isProducer && CAN_ID != SYNC->CAN_ID)
|
||||
) {
|
||||
return ODR_INVALID_VALUE;
|
||||
}
|
||||
#else
|
||||
if ((cobIdSync & 0xFFFF8000) != 0) {
|
||||
if ((cobIdSync & 0xFFFFF800) != 0 || CO_IS_RESTRICTED_CAN_ID(CAN_ID)) {
|
||||
return ODR_INVALID_VALUE;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -72,8 +72,14 @@ static ODR_t OD_write_1012(OD_stream_t *stream, const void *buf,
|
|||
|
||||
CO_TIME_t *TIME = stream->object;
|
||||
|
||||
/* update object */
|
||||
/* verify written value */
|
||||
uint32_t cobIdTimeStamp = CO_getUint32(buf);
|
||||
uint16_t CAN_ID = cobIdTimeStamp & 0x7FF;
|
||||
if ((cobIdTimeStamp & 0x3FFFF800) != 0 || CO_IS_RESTRICTED_CAN_ID(CAN_ID)) {
|
||||
return ODR_INVALID_VALUE;
|
||||
}
|
||||
|
||||
/* update object */
|
||||
TIME->isConsumer = (cobIdTimeStamp & 0x80000000L) != 0;
|
||||
TIME->isProducer = (cobIdTimeStamp & 0x40000000L) != 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -500,6 +500,22 @@ typedef enum {
|
|||
} CO_Default_CAN_ID_t;
|
||||
|
||||
|
||||
/**
|
||||
* Restricted CAN-IDs
|
||||
*
|
||||
* Macro for verifying 'Restricted CAN-IDs', as specified by standard CiA301.
|
||||
* They shall not be used for SYNC, TIME, EMCY, PDO and SDO.
|
||||
*/
|
||||
#ifndef CO_IS_RESTRICTED_CAN_ID
|
||||
#define CO_IS_RESTRICTED_CAN_ID(CAN_ID) ((CAN_ID) <= 0x7F \
|
||||
|| ((CAN_ID) >= 0x101 && (CAN_ID) <= 0x180) \
|
||||
|| ((CAN_ID) >= 0x581 && (CAN_ID) <= 0x5FF) \
|
||||
|| ((CAN_ID) >= 0x601 && (CAN_ID) <= 0x67F) \
|
||||
|| ((CAN_ID) >= 0x6E0 && (CAN_ID) <= 0x6FF) \
|
||||
|| (CAN_ID) >= 0x701)
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* CAN error status bitmasks.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in a new issue