1
0
Fork 0

Merge pull request #2 from temi54c1l8/fix_srdo_verified_on_operational_change

Fix SRDO problem with PCL Codesys on configuration runtime without reset
This commit is contained in:
temi54c1l8 2024-07-04 13:53:13 +02:00 committed by GitHub
commit cf6885b23e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 156 additions and 110 deletions

View file

@ -106,7 +106,6 @@ configurationValidUnset(CO_SRDOGuard_t* SRDOGuard) {
OD_size_t dummy; OD_size_t dummy;
SRDOGuard->configurationValid = false; SRDOGuard->configurationValid = false;
SRDOGuard->privateConfigValid = false;
OD_IO->write(&OD_IO->stream, &val, sizeof(val), &dummy); OD_IO->write(&OD_IO->stream, &val, sizeof(val), &dummy);
} }
@ -316,6 +315,13 @@ OD_write_13FE(OD_stream_t* stream, const void* buf, OD_size_t count, OD_size_t*
/* Data cannot be transferred or stored to the application because of the present device state. */ /* Data cannot be transferred or stored to the application because of the present device state. */
return ODR_DATA_DEV_STATE; return ODR_DATA_DEV_STATE;
} }
uint8_t configurationValid = CO_getUint8(buf);
if( configurationValid == CO_SRDO_VALID_MAGIC ) {
SRDOGuard->configurationValid = true;
} else {
SRDOGuard->configurationValid = false;
}
/* write value to the original location in the Object Dictionary */ /* write value to the original location in the Object Dictionary */
return OD_writeOriginal(stream, buf, count, countWritten); return OD_writeOriginal(stream, buf, count, countWritten);
@ -352,7 +358,7 @@ CO_SRDO_initCallbackPre(CO_SRDO_t* SRDO, void* object, void (*pFunctSignalPre)(v
#endif #endif
CO_ReturnError_t CO_ReturnError_t
CO_SRDO_init_start(CO_SRDOGuard_t* SRDOGuard, OD_entry_t* OD_13FE_configurationValid, CO_SRDOGuard_init(CO_SRDOGuard_t* SRDOGuard, OD_entry_t* OD_13FE_configurationValid,
OD_entry_t* OD_13FF_safetyConfigurationSignature, uint32_t* errInfo) { OD_entry_t* OD_13FF_safetyConfigurationSignature, uint32_t* errInfo) {
ODR_t odRet; ODR_t odRet;
uint8_t configurationValid; uint8_t configurationValid;
@ -364,6 +370,9 @@ CO_SRDO_init_start(CO_SRDOGuard_t* SRDOGuard, OD_entry_t* OD_13FE_configurationV
/* clear object */ /* clear object */
(void)memset(SRDOGuard, 0, sizeof(CO_SRDOGuard_t)); (void)memset(SRDOGuard, 0, sizeof(CO_SRDOGuard_t));
SRDOGuard->OD_13FE_entry = OD_13FE_configurationValid;
SRDOGuard->OD_13FF_entry = OD_13FF_safetyConfigurationSignature;
/* Configure Object dictionary extensions */ /* Configure Object dictionary extensions */
SRDOGuard->OD_13FE_extension.object = SRDOGuard; SRDOGuard->OD_13FE_extension.object = SRDOGuard;
@ -385,28 +394,22 @@ CO_SRDO_init_start(CO_SRDOGuard_t* SRDOGuard, OD_entry_t* OD_13FE_configurationV
} }
return CO_ERROR_OD_PARAMETERS; return CO_ERROR_OD_PARAMETERS;
} }
if (OD_get_u8(OD_13FE_configurationValid, 0, &configurationValid, true) != ODR_OK) { if (OD_get_u8(OD_13FE_configurationValid, 0, &configurationValid, true) != ODR_OK) {
*errInfo = (((uint32_t)OD_getIndex(OD_13FE_configurationValid)) << 8) | 1U; *errInfo = (((uint32_t)OD_getIndex(OD_13FE_configurationValid)) << 8) | 1U;
return CO_ERROR_OD_PARAMETERS; return CO_ERROR_OD_PARAMETERS;
} }
if( configurationValid == CO_SRDO_VALID_MAGIC ) {
if (configurationValid == CO_SRDO_VALID_MAGIC) { SRDOGuard->configurationValid = true;
/* Private variable, erroneous SRDO initialization will clear this. */ } else {
SRDOGuard->privateConfigValid = true; SRDOGuard->configurationValid = false;
} }
return CO_ERROR_NO; return CO_ERROR_NO;
} }
CO_ReturnError_t CO_ReturnError_t
CO_SRDO_init(CO_SRDO_t* SRDO, uint8_t SRDO_Index, CO_SRDOGuard_t* SRDOGuard, OD_t* OD, CO_EM_t* em, uint8_t nodeId, CO_SRDO_config( CO_SRDO_t* SRDO, uint8_t SRDO_Index, CO_SRDOGuard_t* SRDOGuard, uint32_t* errInfo) {
uint16_t defaultCOB_ID, OD_entry_t* OD_130x_SRDOCommPar, OD_entry_t* OD_138x_SRDOMapPar,
OD_entry_t* OD_13FE_configurationValid, OD_entry_t* OD_13FF_safetyConfigurationSignature,
CO_CANmodule_t* CANdevRxNormal, CO_CANmodule_t* CANdevRxInverted, uint16_t CANdevRxIdxNormal,
uint16_t CANdevRxIdxInverted, CO_CANmodule_t* CANdevTxNormal, CO_CANmodule_t* CANdevTxInverted,
uint16_t CANdevTxIdxNormal, uint16_t CANdevTxIdxInverted, uint32_t* errInfo) {
CO_ReturnError_t ret = CO_ERROR_NO; CO_ReturnError_t ret = CO_ERROR_NO;
uint32_t err = 0; uint32_t err = 0;
bool_t configurationInProgress = false; bool_t configurationInProgress = false;
@ -424,73 +427,41 @@ CO_SRDO_init(CO_SRDO_t* SRDO, uint8_t SRDO_Index, CO_SRDOGuard_t* SRDOGuard, OD_
uint8_t mappedObjectsCount = 0; uint8_t mappedObjectsCount = 0;
uint32_t mapping[CO_SRDO_MAX_MAPPED_ENTRIES]; uint32_t mapping[CO_SRDO_MAX_MAPPED_ENTRIES];
/* verify arguments */
if ((SRDO == NULL) || (SRDOGuard == NULL) || (OD == NULL) || (em == NULL) || (OD_130x_SRDOCommPar == NULL)
|| (OD_138x_SRDOMapPar == NULL) || (OD_13FE_configurationValid == NULL) || (OD_13FF_safetyConfigurationSignature == NULL)
|| (CANdevRxNormal == NULL) || (CANdevRxInverted == NULL) || (CANdevTxNormal == NULL) || (CANdevTxInverted == NULL)) {
ret = CO_ERROR_ILLEGAL_ARGUMENT;
err = 1;
}
/* clear object and configure some object variables */
if (err == 0U) {
(void)memset(SRDO, 0, sizeof(CO_SRDO_t));
SRDO->SRDOGuard = SRDOGuard;
SRDO->em = em;
SRDO->defaultCOB_ID = defaultCOB_ID;
SRDO->nodeId = nodeId;
SRDO->CANdevTx[0] = CANdevTxNormal;
SRDO->CANdevTx[1] = CANdevTxInverted;
/* Configure Object dictionary entry at index 0x1301+ */
SRDO->OD_communicationParam_ext.object = SRDO;
SRDO->OD_communicationParam_ext.read = OD_read_SRDO_communicationParam;
SRDO->OD_communicationParam_ext.write = OD_write_SRDO_communicationParam;
(void)OD_extension_init(OD_130x_SRDOCommPar, &SRDO->OD_communicationParam_ext);
/* Configure Object dictionary entry at index 0x1381+ */
SRDO->OD_mappingParam_extension.object = SRDO;
SRDO->OD_mappingParam_extension.read = OD_readOriginal;
SRDO->OD_mappingParam_extension.write = OD_write_SRDO_mappingParam;
(void)OD_extension_init(OD_138x_SRDOMapPar, &SRDO->OD_mappingParam_extension);
}
/* Get variables from object Dictionary and verify it's structure. */ /* Get variables from object Dictionary and verify it's structure. */
if (err == 0U) { if (err == 0U) {
if (OD_get_u8(OD_130x_SRDOCommPar, 0, &cp_highestSubindexSupported, true) != ODR_OK) { if (OD_get_u8(SRDOGuard->OD_13FE_entry, 0, &configurationValid, true) != ODR_OK) {
err = ERR_INFO(0x1301UL + SRDO_Index, 0, 1);
}
else if (OD_get_u8(OD_130x_SRDOCommPar, 1, &informationDirection, true) != ODR_OK) {
err = ERR_INFO(0x1301UL + SRDO_Index, 1, 1);
}
else if (OD_get_u16(OD_130x_SRDOCommPar, 2, &safetyCycleTime, true) != ODR_OK) {
err = ERR_INFO(0x1301UL + SRDO_Index, 2, 1);
}
else if (OD_get_u8(OD_130x_SRDOCommPar, 3, &safetyRelatedValidationTime, true) != ODR_OK) {
err = ERR_INFO(0x1301UL + SRDO_Index, 3, 1);
}
else if (OD_get_u8(OD_130x_SRDOCommPar, 4, &transmissionType, true) != ODR_OK) {
err = ERR_INFO(0x1301UL + SRDO_Index, 4, 1);
}
else if (OD_get_u32(OD_130x_SRDOCommPar, 5, &COB_ID1_normal, true) != ODR_OK) {
err = ERR_INFO(0x1301UL + SRDO_Index, 5, 1);
}
else if (OD_get_u32(OD_130x_SRDOCommPar, 6, &COB_ID2_inverted, true) != ODR_OK) {
err = ERR_INFO(0x1301UL + SRDO_Index, 6, 1);
}
else if (OD_get_u8(OD_13FE_configurationValid, 0, &configurationValid, true) != ODR_OK) {
err = ERR_INFO(0x13FEUL, 0, 1); err = ERR_INFO(0x13FEUL, 0, 1);
} }
else if (OD_get_u16(OD_13FF_safetyConfigurationSignature, SRDO_Index + 1U, &crcSignatureFromOD, true) != ODR_OK) { else if (OD_get_u16(SRDOGuard->OD_13FF_entry, SRDO_Index + 1U, &crcSignatureFromOD, true) != ODR_OK) {
err = ERR_INFO(0x13FFUL, SRDO_Index + 1UL, 1); err = ERR_INFO(0x13FFUL, SRDO_Index + 1UL, 1);
} }
else if (OD_get_u8(OD_138x_SRDOMapPar, 0, &mappedObjectsCount, true) != ODR_OK) { else if (OD_get_u8(SRDO->OD_communicationParam_entry, 0, &cp_highestSubindexSupported, true) != ODR_OK) {
err = ERR_INFO(0x1301UL + SRDO_Index, 0, 1);
}
else if (OD_get_u8(SRDO->OD_communicationParam_entry, 1, &informationDirection, true) != ODR_OK) {
err = ERR_INFO(0x1301UL + SRDO_Index, 1, 1);
}
else if (OD_get_u16(SRDO->OD_communicationParam_entry, 2, &safetyCycleTime, true) != ODR_OK) {
err = ERR_INFO(0x1301UL + SRDO_Index, 2, 1);
}
else if (OD_get_u8(SRDO->OD_communicationParam_entry, 3, &safetyRelatedValidationTime, true) != ODR_OK) {
err = ERR_INFO(0x1301UL + SRDO_Index, 3, 1);
}
else if (OD_get_u8(SRDO->OD_communicationParam_entry, 4, &transmissionType, true) != ODR_OK) {
err = ERR_INFO(0x1301UL + SRDO_Index, 4, 1);
}
else if (OD_get_u32(SRDO->OD_communicationParam_entry, 5, &COB_ID1_normal, true) != ODR_OK) {
err = ERR_INFO(0x1301UL + SRDO_Index, 5, 1);
}
else if (OD_get_u32(SRDO->OD_communicationParam_entry, 6, &COB_ID2_inverted, true) != ODR_OK) {
err = ERR_INFO(0x1301UL + SRDO_Index, 6, 1);
}
else if (OD_get_u8(SRDO->OD_mappingParam_entry, 0, &mappedObjectsCount, true) != ODR_OK) {
err = ERR_INFO(0x1381UL + SRDO_Index, 0, 1); err = ERR_INFO(0x1381UL + SRDO_Index, 0, 1);
} }
else { else {
for (uint8_t i = 0; i < mappedObjectsCount; i++) { for (uint8_t i = 0; i < mappedObjectsCount; i++) {
if (OD_get_u32(OD_138x_SRDOMapPar, i+1U, &mapping[i], true) != ODR_OK) { if (OD_get_u32(SRDO->OD_mappingParam_entry, i+1U, &mapping[i], true) != ODR_OK) {
err = ERR_INFO(0x1381UL + SRDO_Index, i+1UL, 1); err = ERR_INFO(0x1381UL + SRDO_Index, i+1UL, 1);
break; break;
} }
@ -498,7 +469,7 @@ CO_SRDO_init(CO_SRDO_t* SRDO, uint8_t SRDO_Index, CO_SRDOGuard_t* SRDOGuard, OD_
} }
/* if OD contains default COB_IDs, add node-id */ /* if OD contains default COB_IDs, add node-id */
if ((COB_ID1_normal == defaultCOB_ID) && (COB_ID2_inverted == ((uint32_t)defaultCOB_ID + 1UL)) && (nodeId <= 64U)) { if ((COB_ID1_normal == SRDO->defaultCOB_ID) && (COB_ID2_inverted == ((uint32_t)SRDO->defaultCOB_ID + 1UL)) && (SRDO->nodeId <= 64U)) {
uint32_t add = (uint32_t)SRDO->nodeId * 2U; uint32_t add = (uint32_t)SRDO->nodeId * 2U;
COB_ID1_normal += add; COB_ID1_normal += add;
COB_ID2_inverted += add; COB_ID2_inverted += add;
@ -602,7 +573,7 @@ CO_SRDO_init(CO_SRDO_t* SRDO, uint8_t SRDO_Index, CO_SRDOGuard_t* SRDOGuard, OD_
/* find entry in the Object Dictionary */ /* find entry in the Object Dictionary */
else { else {
OD_IO_t OD_IOcopy; OD_IO_t OD_IOcopy;
OD_entry_t *entry = OD_find(OD, index); OD_entry_t *entry = OD_find(SRDO->OD, index);
ODR_t odRet = OD_getSub(entry, subIndex, &OD_IOcopy, false); ODR_t odRet = OD_getSub(entry, subIndex, &OD_IOcopy, false);
if (odRet != ODR_OK) { if (odRet != ODR_OK) {
err = ERR_INFO(0x1381UL + SRDO_Index, i + 1UL, 5); err = ERR_INFO(0x1381UL + SRDO_Index, i + 1UL, 5);
@ -644,9 +615,9 @@ CO_SRDO_init(CO_SRDO_t* SRDO, uint8_t SRDO_Index, CO_SRDOGuard_t* SRDOGuard, OD_
/* Configure CAN tx buffers */ /* Configure CAN tx buffers */
if ((err == 0U) && configurationInProgress && (informationDirection == CO_SRDO_TX)) { if ((err == 0U) && configurationInProgress && (informationDirection == CO_SRDO_TX)) {
/* Normal Configuration */
SRDO->CANtxBuff[0] = CO_CANtxBufferInit(CANdevTxNormal, /* CAN device */ SRDO->CANtxBuff[0] = CO_CANtxBufferInit(SRDO->CANdevTx[0], /* CAN device */
CANdevTxIdxNormal, /* index of specific buffer inside CAN module */ SRDO->CANdevTxIdx[0], /* index of specific buffer inside CAN module */
(uint16_t)COB_ID1_normal, /* CAN identifier */ (uint16_t)COB_ID1_normal, /* CAN identifier */
false, /* rtr */ false, /* rtr */
SRDO->dataLength, /* number of data bytes */ SRDO->dataLength, /* number of data bytes */
@ -656,8 +627,9 @@ CO_SRDO_init(CO_SRDO_t* SRDO, uint8_t SRDO_Index, CO_SRDOGuard_t* SRDOGuard, OD_
err = ERR_INFO(0x1301UL + SRDO_Index, 5, 10); err = ERR_INFO(0x1301UL + SRDO_Index, 5, 10);
} }
SRDO->CANtxBuff[1] = CO_CANtxBufferInit(CANdevTxInverted, /* CAN device */ /* Inverted Configuration */
CANdevTxIdxInverted, /* index of specific buffer inside CAN module */ SRDO->CANtxBuff[1] = CO_CANtxBufferInit(SRDO->CANdevTx[1], /* CAN device */
SRDO->CANdevTxIdx[1], /* index of specific buffer inside CAN module */
(uint16_t)COB_ID2_inverted, /* CAN identifier */ (uint16_t)COB_ID2_inverted, /* CAN identifier */
false, /* rtr */ false, /* rtr */
SRDO->dataLength, /* number of data bytes */ SRDO->dataLength, /* number of data bytes */
@ -670,9 +642,9 @@ CO_SRDO_init(CO_SRDO_t* SRDO, uint8_t SRDO_Index, CO_SRDOGuard_t* SRDOGuard, OD_
/* Configure CAN rx buffers */ /* Configure CAN rx buffers */
if ((err == 0U) && configurationInProgress && (informationDirection == CO_SRDO_RX)) { if ((err == 0U) && configurationInProgress && (informationDirection == CO_SRDO_RX)) {
/* Normal Configuration */
ret = CO_CANrxBufferInit(CANdevRxNormal, /* CAN device */ ret = CO_CANrxBufferInit(SRDO->CANdevRx[0], /* CAN device */
CANdevRxIdxNormal, /* rx buffer index */ SRDO->CANdevRxIdx[0], /* rx buffer index */
(uint16_t)COB_ID1_normal, /* CAN identifier */ (uint16_t)COB_ID1_normal, /* CAN identifier */
0x7FF, /* mask */ 0x7FF, /* mask */
false, /* rtr */ false, /* rtr */
@ -683,8 +655,9 @@ CO_SRDO_init(CO_SRDO_t* SRDO, uint8_t SRDO_Index, CO_SRDOGuard_t* SRDOGuard, OD_
err = ERR_INFO(0x1301UL + SRDO_Index, 5, 11); err = ERR_INFO(0x1301UL + SRDO_Index, 5, 11);
} }
ret = CO_CANrxBufferInit(CANdevRxInverted, /* CAN device */ /* Inverted Configuration */
CANdevRxIdxInverted, /* rx buffer index */ ret = CO_CANrxBufferInit(SRDO->CANdevRx[1], /* CAN device */
SRDO->CANdevRxIdx[1], /* rx buffer index */
(uint16_t)COB_ID2_inverted, /* CAN identifier */ (uint16_t)COB_ID2_inverted, /* CAN identifier */
0x7FF, /* mask */ 0x7FF, /* mask */
false, /* rtr */ false, /* rtr */
@ -704,11 +677,12 @@ CO_SRDO_init(CO_SRDO_t* SRDO, uint8_t SRDO_Index, CO_SRDOGuard_t* SRDOGuard, OD_
} }
else { else {
if (ret == CO_ERROR_NO) { if (ret == CO_ERROR_NO) {
CO_errorReport(em, CO_EM_SRDO_CONFIGURATION, CO_EMC_DATA_SET, err); CO_errorReport(SRDO->em, CO_EM_SRDO_CONFIGURATION, CO_EMC_DATA_SET, err);
configurationValidUnset(SRDO->SRDOGuard); configurationValidUnset(SRDO->SRDOGuard);
} }
} }
if (errInfo != NULL) { if (errInfo != NULL) {
*errInfo = err; *errInfo = err;
} }
@ -716,6 +690,62 @@ CO_SRDO_init(CO_SRDO_t* SRDO, uint8_t SRDO_Index, CO_SRDOGuard_t* SRDOGuard, OD_
return ret; return ret;
} }
CO_ReturnError_t
CO_SRDO_init(CO_SRDO_t* SRDO, uint8_t SRDO_Index, CO_SRDOGuard_t* SRDOGuard, OD_t* OD, CO_EM_t* em, uint8_t nodeId,
uint16_t defaultCOB_ID, OD_entry_t* OD_130x_SRDOCommPar, OD_entry_t* OD_138x_SRDOMapPar,
CO_CANmodule_t* CANdevRxNormal, CO_CANmodule_t* CANdevRxInverted, uint16_t CANdevRxIdxNormal,
uint16_t CANdevRxIdxInverted, CO_CANmodule_t* CANdevTxNormal, CO_CANmodule_t* CANdevTxInverted,
uint16_t CANdevTxIdxNormal, uint16_t CANdevTxIdxInverted, uint32_t* errInfo) {
CO_ReturnError_t ret = CO_ERROR_NO;
/* verify arguments */
if ((SRDO == NULL) || (SRDOGuard == NULL) || (OD == NULL) || (em == NULL)
|| (OD_130x_SRDOCommPar == NULL) || (OD_138x_SRDOMapPar == NULL)
|| (CANdevRxNormal == NULL) || (CANdevRxInverted == NULL)
|| (CANdevTxNormal == NULL) || (CANdevTxInverted == NULL)) {
ret = CO_ERROR_ILLEGAL_ARGUMENT;
}
/* clear object and configure some object variables */
else {
(void)memset(SRDO, 0, sizeof(CO_SRDO_t));
SRDO->SRDOGuard = SRDOGuard;
SRDO->OD = OD;
SRDO->em = em;
SRDO->defaultCOB_ID = defaultCOB_ID;
SRDO->nodeId = nodeId;
SRDO->CANdevTx[0] = CANdevTxNormal;
SRDO->CANdevTx[1] = CANdevTxInverted;
SRDO->CANdevRx[0] = CANdevRxNormal;
SRDO->CANdevRx[1] = CANdevRxInverted;
SRDO->CANdevTxIdx[0] = CANdevTxIdxNormal;
SRDO->CANdevTxIdx[1] = CANdevTxIdxInverted;
SRDO->CANdevRxIdx[0] = CANdevRxIdxNormal;
SRDO->CANdevRxIdx[1] = CANdevRxIdxInverted;
SRDO->OD_communicationParam_entry = OD_130x_SRDOCommPar;
SRDO->OD_mappingParam_entry = OD_138x_SRDOMapPar;
/* Configure Object dictionary entry at index 0x1301+ */
SRDO->OD_communicationParam_ext.object = SRDO;
SRDO->OD_communicationParam_ext.read = OD_read_SRDO_communicationParam;
SRDO->OD_communicationParam_ext.write = OD_write_SRDO_communicationParam;
(void)OD_extension_init(OD_130x_SRDOCommPar, &SRDO->OD_communicationParam_ext);
/* Configure Object dictionary entry at index 0x1381+ */
SRDO->OD_mappingParam_extension.object = SRDO;
SRDO->OD_mappingParam_extension.read = OD_readOriginal;
SRDO->OD_mappingParam_extension.write = OD_write_SRDO_mappingParam;
(void)OD_extension_init(OD_138x_SRDOMapPar, &SRDO->OD_mappingParam_extension);
ret = CO_SRDO_config(SRDO, SRDO_Index, SRDOGuard, errInfo);
}
return ret;
}
CO_ReturnError_t CO_ReturnError_t
CO_SRDO_requestSend(CO_SRDO_t* SRDO) { CO_SRDO_requestSend(CO_SRDO_t* SRDO) {
CO_ReturnError_t ret; CO_ReturnError_t ret;

View file

@ -126,11 +126,13 @@ typedef struct {
/** True if all SRDO objects are properly configured. Set after successful /** True if all SRDO objects are properly configured. Set after successful
* finish of all @CO_SRDO_init() functions. Cleared on configuration change. */ * finish of all @CO_SRDO_init() functions. Cleared on configuration change. */
bool_t configurationValid; bool_t configurationValid;
/** Private helper variable set on the start of SRDO configuration */
bool_t privateConfigValid;
/** Object for input / output on the OD variable 13FE:00. Configuration /** Object for input / output on the OD variable 13FE:00. Configuration
* of any of the the SRDO parameters will write 0 to that variable. */ * of any of the the SRDO parameters will write 0 to that variable. */
OD_IO_t OD_IO_configurationValid; OD_IO_t OD_IO_configurationValid;
OD_entry_t* OD_13FE_entry;
OD_entry_t* OD_13FF_entry;
/** Extension for OD object */ /** Extension for OD object */
OD_extension_t OD_13FE_extension; OD_extension_t OD_13FE_extension;
/** Extension for OD object */ /** Extension for OD object */
@ -141,11 +143,15 @@ typedef struct {
* SRDO object. * SRDO object.
*/ */
typedef struct { typedef struct {
CO_SRDOGuard_t* SRDOGuard; /**< From CO_SRDO_init() */ CO_SRDOGuard_t* SRDOGuard; /**< From CO_SRDO_init() */
CO_EM_t* em; /**< From CO_SRDO_init() */ OD_t *OD; /**< From CO_SRDO_init() */
uint16_t defaultCOB_ID; /**< From CO_SRDO_init() */ CO_EM_t* em; /**< From CO_SRDO_init() */
uint8_t nodeId; /**< From CO_SRDO_init() */ uint16_t defaultCOB_ID; /**< From CO_SRDO_init() */
CO_CANmodule_t* CANdevTx[2];/**< From CO_SRDO_init() */ uint8_t nodeId; /**< From CO_SRDO_init() */
CO_CANmodule_t* CANdevTx[2]; /**< From CO_SRDO_init() */
uint16_t CANdevTxIdx[2]; /**< From CO_SRDO_init() */
CO_CANmodule_t* CANdevRx[2]; /**< From CO_SRDO_init() */
uint16_t CANdevRxIdx[2]; /**< From CO_SRDO_init() */
/** Internal state of this SRDO. */ /** Internal state of this SRDO. */
CO_SRDO_state_t internalState; CO_SRDO_state_t internalState;
/** Copy of variable, internal usage. */ /** Copy of variable, internal usage. */
@ -183,6 +189,10 @@ typedef struct {
uint8_t CANrxData[2][CO_SRDO_MAX_SIZE]; uint8_t CANrxData[2][CO_SRDO_MAX_SIZE];
/** If true, next processed SRDO message is normal (not inverted) */ /** If true, next processed SRDO message is normal (not inverted) */
bool_t nextIsNormal; bool_t nextIsNormal;
OD_entry_t* OD_communicationParam_entry;/**< From CO_SRDO_init() */
OD_entry_t* OD_mappingParam_entry;/**< From CO_SRDO_init() */
/** Extension for OD object */ /** Extension for OD object */
OD_extension_t OD_communicationParam_ext; OD_extension_t OD_communicationParam_ext;
/** Extension for OD object */ /** Extension for OD object */
@ -209,19 +219,9 @@ typedef struct {
* *
* @return #CO_ReturnError_t: CO_ERROR_NO or CO_ERROR_ILLEGAL_ARGUMENT. * @return #CO_ReturnError_t: CO_ERROR_NO or CO_ERROR_ILLEGAL_ARGUMENT.
*/ */
CO_ReturnError_t CO_SRDO_init_start(CO_SRDOGuard_t* SRDOGuard, OD_entry_t* OD_13FE_configurationValid, CO_ReturnError_t CO_SRDOGuard_init(CO_SRDOGuard_t* SRDOGuard, OD_entry_t* OD_13FE_configurationValid,
OD_entry_t* OD_13FF_safetyConfigurationSignature, uint32_t* errInfo); OD_entry_t* OD_13FF_safetyConfigurationSignature, uint32_t* errInfo);
/**
* Finalize SRDOGuard object.
*
* Function must be called in the communication reset section after @CO_SRDO_init functions.
*
* @param SRDOGuard This object will be finalized.
*/
static inline void CO_SRDO_init_end(CO_SRDOGuard_t* SRDOGuard) {
SRDOGuard->configurationValid = SRDOGuard->privateConfigValid;
}
/** /**
* Initialize SRDO object. * Initialize SRDO object.
@ -255,8 +255,7 @@ static inline void CO_SRDO_init_end(CO_SRDOGuard_t* SRDOGuard) {
*/ */
CO_ReturnError_t CO_SRDO_init(CO_SRDO_t* SRDO, uint8_t SRDO_Index, CO_SRDOGuard_t* SRDOGuard, OD_t* OD, CO_EM_t* em, CO_ReturnError_t CO_SRDO_init(CO_SRDO_t* SRDO, uint8_t SRDO_Index, CO_SRDOGuard_t* SRDOGuard, OD_t* OD, CO_EM_t* em,
uint8_t nodeId, uint16_t defaultCOB_ID, OD_entry_t* OD_130x_SRDOCommPar, uint8_t nodeId, uint16_t defaultCOB_ID, OD_entry_t* OD_130x_SRDOCommPar,
OD_entry_t* OD_138x_SRDOMapPar, OD_entry_t* OD_13FE_configurationValid, OD_entry_t* OD_138x_SRDOMapPar, CO_CANmodule_t* CANdevRxNormal,
OD_entry_t* OD_13FF_safetyConfigurationSignature, CO_CANmodule_t* CANdevRxNormal,
CO_CANmodule_t* CANdevRxInverted, uint16_t CANdevRxIdxNormal, uint16_t CANdevRxIdxInverted, CO_CANmodule_t* CANdevRxInverted, uint16_t CANdevRxIdxNormal, uint16_t CANdevRxIdxInverted,
CO_CANmodule_t* CANdevTxNormal, CO_CANmodule_t* CANdevTxInverted, CO_CANmodule_t* CANdevTxNormal, CO_CANmodule_t* CANdevTxInverted,
uint16_t CANdevTxIdxNormal, uint16_t CANdevTxIdxInverted, uint32_t* errInfo); uint16_t CANdevTxIdxNormal, uint16_t CANdevTxIdxInverted, uint32_t* errInfo);
@ -288,6 +287,9 @@ void CO_SRDO_initCallbackPre(CO_SRDO_t* SRDO, void* object, void (*pFunctSignalP
*/ */
CO_ReturnError_t CO_SRDO_requestSend(CO_SRDO_t* SRDO); CO_ReturnError_t CO_SRDO_requestSend(CO_SRDO_t* SRDO);
CO_ReturnError_t CO_SRDO_config( CO_SRDO_t* SRDO, uint8_t SRDO_Index, CO_SRDOGuard_t* SRDOGuard, uint32_t* errInfo);
/** /**
* Process transmitting/receiving individual SRDO message. * Process transmitting/receiving individual SRDO message.
* *

View file

@ -723,6 +723,7 @@ void CO_delete(CO_t *co) {
CO_free(co->em_fifo); CO_free(co->em_fifo);
#endif #endif
#if ((CO_CONFIG_NODE_GUARDING) & CO_CONFIG_NODE_GUARDING_SLAVE_ENABLE) != 0 #if ((CO_CONFIG_NODE_GUARDING) & CO_CONFIG_NODE_GUARDING_SLAVE_ENABLE) != 0
CO_free(co->NGslave); CO_free(co->NGslave);
#endif #endif
@ -1366,7 +1367,7 @@ CO_ReturnError_t CO_CANopenInitSRDO(CO_t *co,
#if ((CO_CONFIG_SRDO) & CO_CONFIG_SRDO_ENABLE) != 0 #if ((CO_CONFIG_SRDO) & CO_CONFIG_SRDO_ENABLE) != 0
if (CO_GET_CNT(SRDO) > 0U) { if (CO_GET_CNT(SRDO) > 0U) {
CO_ReturnError_t err; CO_ReturnError_t err;
err = CO_SRDO_init_start(co->SRDOGuard, err = CO_SRDOGuard_init(co->SRDOGuard,
OD_GET(H13FE, OD_H13FE_SRDO_VALID), OD_GET(H13FE, OD_H13FE_SRDO_VALID),
OD_GET(H13FF, OD_H13FF_SRDO_CHECKSUM), OD_GET(H13FF, OD_H13FF_SRDO_CHECKSUM),
errInfo); errInfo);
@ -1387,8 +1388,6 @@ CO_ReturnError_t CO_CANopenInitSRDO(CO_t *co,
((i == 0U) ? CO_CAN_ID_SRDO_1 : 0U), ((i == 0U) ? CO_CAN_ID_SRDO_1 : 0U),
SRDOcomm, SRDOcomm,
SRDOmap, SRDOmap,
OD_GET(H13FE, OD_H13FE_SRDO_VALID),
OD_GET(H13FF, OD_H13FF_SRDO_CHECKSUM),
co->CANmodule, co->CANmodule,
co->CANmodule, co->CANmodule,
CANdevRxIdx, CANdevRxIdx,
@ -1402,8 +1401,6 @@ CO_ReturnError_t CO_CANopenInitSRDO(CO_t *co,
SRDOcomm++; SRDOcomm++;
SRDOmap++; SRDOmap++;
} }
CO_SRDO_init_end(co->SRDOGuard);
} }
#endif #endif
@ -1641,6 +1638,10 @@ CO_SRDO_state_t CO_process_SRDO(CO_t *co,
uint32_t timeDifference_us, uint32_t timeDifference_us,
uint32_t *timerNext_us) uint32_t *timerNext_us)
{ {
static bool_t NMTisOperationalPrevius = false;
uint8_t i;
CO_ReturnError_t err;
if (co->nodeIdUnconfigured) { if (co->nodeIdUnconfigured) {
return CO_SRDO_state_unknown; return CO_SRDO_state_unknown;
} }
@ -1649,9 +1650,22 @@ CO_SRDO_state_t CO_process_SRDO(CO_t *co,
CO_NMT_getInternalState(co->NMT) == CO_NMT_OPERATIONAL; CO_NMT_getInternalState(co->NMT) == CO_NMT_OPERATIONAL;
if( NMTisOperationalPrevius != NMTisOperational ) {
NMTisOperationalPrevius = NMTisOperational;
if( NMTisOperational ) {
for (i = 0; i < CO_GET_CNT(SRDO); i++) {
err = CO_SRDO_config( &co->SRDO[i],
i,
co->SRDOGuard, NULL );
if (err != CO_ERROR_NO) { return CO_SRDO_state_error_internal; }
}
}
}
CO_SRDO_state_t lowestState = CO_SRDO_state_deleted; CO_SRDO_state_t lowestState = CO_SRDO_state_deleted;
for (uint16_t i = 0; i < CO_GET_CNT(SRDO); i++) { for (i = 0; i < CO_GET_CNT(SRDO); i++) {
CO_SRDO_state_t state = CO_SRDO_process(&co->SRDO[i], CO_SRDO_state_t state = CO_SRDO_process(&co->SRDO[i],
timeDifference_us, timeDifference_us,
timerNext_us, timerNext_us,