Some updates in OD interface.
It matches newly generated OD.h and OD.c files from libedssharp
This commit is contained in:
parent
f73025ef65
commit
cf9fb2a547
8 changed files with 293 additions and 247 deletions
|
|
@ -457,7 +457,7 @@ typedef struct {
|
|||
* Emergency object has own memory buffer for this entry. Entry is optional,
|
||||
* IO extension is required.
|
||||
* @param OD_statusBits Custom OD entry for accessing errorStatusBits from
|
||||
* @ref CO_EM_t. Entry must have bytestring_t of size
|
||||
* @ref CO_EM_t. Entry must have variable of size
|
||||
* (CO_CONFIG_EM_ERR_STATUS_BITS_COUNT/8) bytes available for read/write access
|
||||
* on subindex 0. Emergency object has own memory buffer for this entry. Entry
|
||||
* is optional, IO extension is required.
|
||||
|
|
|
|||
|
|
@ -201,7 +201,6 @@ ODR_t OD_getSub(const OD_entry_t *entry, uint8_t subIndex,
|
|||
OD_subEntry_t *subEntry, OD_stream_t *stream, bool_t odOrig)
|
||||
{
|
||||
if (entry == NULL || entry->odObject == NULL) return ODR_IDX_NOT_EXIST;
|
||||
else if (subIndex > entry->maxSubIndex) return ODR_SUB_NOT_EXIST;
|
||||
else if (subEntry == NULL || stream == NULL) return ODR_DEV_INCOMPAT;
|
||||
|
||||
const void *odObjectOrig = entry->odObject;
|
||||
|
|
@ -218,13 +217,13 @@ ODR_t OD_getSub(const OD_entry_t *entry, uint8_t subIndex,
|
|||
/* common properties */
|
||||
subEntry->index = entry->index;
|
||||
subEntry->subIndex = subIndex;
|
||||
subEntry->maxSubIndex = entry->maxSubIndex;
|
||||
subEntry->storageGroup = entry->storageGroup;
|
||||
subEntry->subEntriesCount = entry->subEntriesCount;
|
||||
subEntry->flagsPDO = (odObjectExt != NULL ) ? odObjectExt->flagsPDO : NULL;
|
||||
stream->dataOffset = 0;
|
||||
|
||||
/* attribute, dataObjectOriginal and dataLength, depends on object type */
|
||||
if (odBasicType == ODT_VAR) {
|
||||
if (subIndex > 0) return ODR_SUB_NOT_EXIST;
|
||||
const OD_obj_var_t *odo = (const OD_obj_var_t *)odObjectOrig;
|
||||
|
||||
subEntry->attribute = odo->attribute;
|
||||
|
|
@ -232,6 +231,7 @@ ODR_t OD_getSub(const OD_entry_t *entry, uint8_t subIndex,
|
|||
stream->dataLength = odo->dataLength;
|
||||
}
|
||||
else if (odBasicType == ODT_ARR) {
|
||||
if (subIndex >= entry->subEntriesCount) return ODR_SUB_NOT_EXIST;
|
||||
const OD_obj_array_t *odo = (const OD_obj_array_t *)odObjectOrig;
|
||||
|
||||
if (subIndex == 0) {
|
||||
|
|
@ -240,18 +240,28 @@ ODR_t OD_getSub(const OD_entry_t *entry, uint8_t subIndex,
|
|||
stream->dataLength = 1;
|
||||
}
|
||||
else {
|
||||
char *data = (char *)odo->data;
|
||||
int i = subIndex - 1;
|
||||
|
||||
subEntry->attribute = odo->attribute;
|
||||
if (data == NULL) return ODR_DEV_INCOMPAT;
|
||||
stream->dataObjectOriginal = data + odo->dataElementSizeof * i;
|
||||
if (odo->data == NULL) {
|
||||
stream->dataObjectOriginal = NULL;
|
||||
}
|
||||
else {
|
||||
char *data = (char *)odo->data;
|
||||
int i = subIndex - 1;
|
||||
stream->dataObjectOriginal = data + odo->dataElementSizeof * i;
|
||||
}
|
||||
stream->dataLength = odo->dataElementLength;
|
||||
}
|
||||
}
|
||||
else if (odBasicType == ODT_REC) {
|
||||
const OD_obj_var_t *odo_rec = (const OD_obj_var_t *)odObjectOrig;
|
||||
const OD_obj_var_t *odo = &odo_rec[subIndex];
|
||||
const OD_obj_record_t *odoArr = (const OD_obj_record_t *)odObjectOrig;
|
||||
const OD_obj_record_t *odo = NULL;
|
||||
for (int i; i< entry->subEntriesCount; i++) {
|
||||
if (odoArr[i].subIndex == subIndex) {
|
||||
odo = &odoArr[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (odo == NULL) return ODR_SUB_NOT_EXIST;
|
||||
|
||||
subEntry->attribute = odo->attribute;
|
||||
stream->dataObjectOriginal = odo->data;
|
||||
|
|
|
|||
|
|
@ -196,9 +196,9 @@ typedef enum {
|
|||
* Structure is initialized with @ref OD_getSub() function.
|
||||
*/
|
||||
typedef struct {
|
||||
/** Pointer to original data object, defined by Object Dictionary. If
|
||||
* memory for data object is not specified by Object Dictionary, then
|
||||
* dataObjectOriginal is NULL. Default read/write functions operate on it.
|
||||
/** Pointer to original data object, defined by Object Dictionary. Default
|
||||
* read/write functions operate on it. If memory for data object is not
|
||||
* specified by Object Dictionary, then dataObjectOriginal is NULL.
|
||||
*/
|
||||
void *dataObjectOriginal;
|
||||
/** Pointer to object, passed by @ref OD_extensionIO_init(). Can be used
|
||||
|
|
@ -224,10 +224,10 @@ typedef struct {
|
|||
uint16_t index;
|
||||
/** Object Dictionary sub-index */
|
||||
uint8_t subIndex;
|
||||
/** Maximum sub-index in the OD object */
|
||||
uint8_t maxSubIndex;
|
||||
/** Group for non-volatile storage of the OD object */
|
||||
uint8_t storageGroup;
|
||||
/** Number of sub-entries in OD object. For VAR is 1, for ARRAY is
|
||||
* maxSubIndex + 1, for RECORD maxSubIndex may be larger, if there is a gap
|
||||
* between sub-indexes. */
|
||||
uint8_t subEntriesCount;
|
||||
/** Attribute bit-field of the OD sub-object, see @ref OD_attributes_t */
|
||||
OD_attr_t attribute;
|
||||
/**
|
||||
|
|
@ -337,16 +337,14 @@ typedef struct {
|
|||
* Object Dictionary entry for one OD object.
|
||||
*
|
||||
* OD entries are collected inside OD_t as array (list). Each OD entry contains
|
||||
* basic information about OD object (index, maxSubIndex and storageGroup) and
|
||||
* basic information about OD object (index and subEntriesCount) and
|
||||
* access function together with a pointer to other details of the OD object.
|
||||
*/
|
||||
typedef struct {
|
||||
/** Object Dictionary index */
|
||||
uint16_t index;
|
||||
/** Maximum sub-index in the OD object */
|
||||
uint8_t maxSubIndex;
|
||||
/** Group for non-volatile storage of the OD object */
|
||||
uint8_t storageGroup;
|
||||
uint8_t subEntriesCount;
|
||||
/** Type of the odObject, indicated by @ref OD_objectTypes_t enumerator. */
|
||||
uint8_t odObjectType;
|
||||
/** OD object of type indicated by odObjectType, from which @ref OD_getSub()
|
||||
|
|
@ -432,18 +430,6 @@ static inline uint16_t OD_getIndex(const OD_entry_t *entry) {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return maxSubIndex from OD entry
|
||||
*
|
||||
* @param entry OD entry returned by @ref OD_find().
|
||||
*
|
||||
* @return OD maxSubIndex
|
||||
*/
|
||||
static inline uint8_t OD_getMaxSubIndex(const OD_entry_t *entry) {
|
||||
return entry->maxSubIndex;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Restart read or write operation on OD variable
|
||||
*
|
||||
|
|
@ -692,7 +678,7 @@ typedef enum {
|
|||
} OD_objectTypes_t;
|
||||
|
||||
/**
|
||||
* Object for single OD variable, used for "VAR" and "RECORD" type OD objects
|
||||
* Object for single OD variable, used for "VAR" type OD objects
|
||||
*/
|
||||
typedef struct {
|
||||
void *data; /**< Pointer to data */
|
||||
|
|
@ -713,6 +699,16 @@ typedef struct {
|
|||
OD_size_t dataElementSizeof; /**< Sizeof one array element in bytes */
|
||||
} OD_obj_array_t;
|
||||
|
||||
/**
|
||||
* Object for OD sub-elements, used in "RECORD" type OD objects
|
||||
*/
|
||||
typedef struct {
|
||||
void *data; /**< Pointer to data */
|
||||
uint8_t subIndex; /**< Sub index of element. */
|
||||
OD_attr_t attribute; /**< Attribute bitfield, see @ref OD_attributes_t */
|
||||
OD_size_t dataLength; /**< Data length in bytes */
|
||||
} OD_obj_record_t;
|
||||
|
||||
/**
|
||||
* Object pointed by @ref OD_obj_extended_t contains application specified
|
||||
* parameters for extended OD object
|
||||
|
|
@ -733,10 +729,10 @@ typedef struct {
|
|||
* @ref OD_extensionIO_init() function
|
||||
*/
|
||||
typedef struct {
|
||||
/** Pointer to PDO flags bit-field, see @ref OD_subEntry_t, may be NULL. */
|
||||
OD_flagsPDO_t *flagsPDO;
|
||||
/** Pointer to application specified IO extension, may be NULL. */
|
||||
OD_extensionIO_t *extIO;
|
||||
/** Pointer to PDO flags bit-field, see @ref OD_subEntry_t, may be NULL. */
|
||||
OD_flagsPDO_t *flagsPDO;
|
||||
/** Pointer to original odObject, see @ref OD_entry_t. */
|
||||
const void *odObjectOriginal;
|
||||
} OD_obj_extended_t;
|
||||
|
|
|
|||
176
CANopen.c
176
CANopen.c
|
|
@ -34,52 +34,52 @@
|
|||
#else
|
||||
#include "OD.h"
|
||||
#define CO_GET_CO(obj) CO_##obj
|
||||
#define CO_GET_CNT(obj) CO_CNT_##obj
|
||||
#define CO_GET_CNT(obj) OD_CNT_##obj
|
||||
#define OD_GET(entry, index) OD_ENTRY_##entry
|
||||
|
||||
/* Verify parameters from "OD.h" and calculate necessary values for each object:
|
||||
* - verify CO_CNT_xx or set default
|
||||
* - verify OD_CNT_xx or set default
|
||||
* - calculate number of CANrx and CYNtx messages: 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. */
|
||||
#if CO_CNT_NMT != 1
|
||||
#error CO_CNT_NMT from OD.h not correct!
|
||||
#if OD_CNT_NMT != 1
|
||||
#error OD_CNT_NMT from OD.h not correct!
|
||||
#endif
|
||||
#define CO_RX_CNT_NMT_SLV CO_CNT_NMT
|
||||
#define CO_RX_CNT_NMT_SLV OD_CNT_NMT
|
||||
#if (CO_CONFIG_NMT) & CO_CONFIG_NMT_MASTER
|
||||
#define CO_TX_CNT_NMT_MST 1
|
||||
#else
|
||||
#define CO_TX_CNT_NMT_MST 0
|
||||
#endif
|
||||
|
||||
#if CO_CNT_HB_PROD != 1
|
||||
#error CO_CNT_HB_PROD from OD.h not correct!
|
||||
#if OD_CNT_HB_PROD != 1
|
||||
#error OD_CNT_HB_PROD from OD.h not correct!
|
||||
#endif
|
||||
#define CO_TX_CNT_HB_PROD CO_CNT_HB_PROD
|
||||
#if !defined CO_CNT_HB_CONS
|
||||
#define CO_CNT_HB_CONS 0
|
||||
#elif CO_CNT_HB_CONS < 0 || CO_CNT_HB_CONS > 1
|
||||
#error CO_CNT_HB_CONS from OD.h not correct!
|
||||
#define CO_TX_CNT_HB_PROD OD_CNT_HB_PROD
|
||||
#if !defined OD_CNT_HB_CONS
|
||||
#define OD_CNT_HB_CONS 0
|
||||
#elif OD_CNT_HB_CONS < 0 || OD_CNT_HB_CONS > 1
|
||||
#error OD_CNT_HB_CONS from OD.h not correct!
|
||||
#endif
|
||||
#if ((CO_CONFIG_HB_CONS) & CO_CONFIG_HB_CONS_ENABLE) && CO_CNT_HB_CONS == 1
|
||||
#if ((CO_CONFIG_HB_CONS) & CO_CONFIG_HB_CONS_ENABLE) && OD_CNT_HB_CONS == 1
|
||||
#define CO_RX_CNT_HB_CONS CO_CONFIG_HB_CONS_SIZE
|
||||
#else
|
||||
#define CO_RX_CNT_HB_CONS 0
|
||||
#endif
|
||||
|
||||
#if CO_CNT_EM != 1
|
||||
#error CO_CNT_EM from OD.h not correct!
|
||||
#if OD_CNT_EM != 1
|
||||
#error OD_CNT_EM from OD.h not correct!
|
||||
#endif
|
||||
#ifndef OD_ENTRY_H1003
|
||||
#define OD_ENTRY_H1003 NULL
|
||||
#endif
|
||||
#if (CO_CONFIG_EM) & CO_CONFIG_EM_PRODUCER
|
||||
#if CO_CNT_EM_PROD == 1
|
||||
#define CO_TX_CNT_EM_PROD CO_CNT_EM_PROD
|
||||
#if OD_CNT_EM_PROD == 1
|
||||
#define CO_TX_CNT_EM_PROD OD_CNT_EM_PROD
|
||||
#else
|
||||
#error wrong CO_CNT_EM_PROD
|
||||
#error wrong OD_CNT_EM_PROD
|
||||
#endif
|
||||
#ifndef OD_ENTRY_H1015
|
||||
#define OD_ENTRY_H1015 NULL
|
||||
|
|
@ -93,39 +93,39 @@
|
|||
#define CO_RX_CNT_EM_CONS 0
|
||||
#endif
|
||||
|
||||
#if !defined CO_CNT_SDO_SRV
|
||||
#define CO_CNT_SDO_SRV 1
|
||||
#if !defined OD_CNT_SDO_SRV
|
||||
#define OD_CNT_SDO_SRV 1
|
||||
#define OD_ENTRY_H1200 NULL
|
||||
#elif CO_CNT_SDO_SRV < 1 || CO_CNT_SDO_SRV > 128
|
||||
#error CO_CNT_SDO_SRV from OD.h not correct!
|
||||
#elif OD_CNT_SDO_SRV < 1 || OD_CNT_SDO_SRV > 128
|
||||
#error OD_CNT_SDO_SRV from OD.h not correct!
|
||||
#endif
|
||||
#define CO_RX_CNT_SDO_SRV CO_CNT_SDO_SRV
|
||||
#define CO_TX_CNT_SDO_SRV CO_CNT_SDO_SRV
|
||||
#define CO_RX_CNT_SDO_SRV OD_CNT_SDO_SRV
|
||||
#define CO_TX_CNT_SDO_SRV OD_CNT_SDO_SRV
|
||||
|
||||
#if (CO_CONFIG_SDO_CLI) & CO_CONFIG_SDO_CLI_ENABLE
|
||||
#if !defined CO_CNT_SDO_CLI
|
||||
#define CO_CNT_SDO_CLI 0
|
||||
#if !defined OD_CNT_SDO_CLI
|
||||
#define OD_CNT_SDO_CLI 0
|
||||
#define OD_ENTRY_H1280 NULL
|
||||
#elif CO_CNT_SDO_CLI < 0 || CO_CNT_SDO_CLI > 128
|
||||
#error CO_CNT_SDO_CLI from OD.h not correct!
|
||||
#elif OD_CNT_SDO_CLI < 0 || OD_CNT_SDO_CLI > 128
|
||||
#error OD_CNT_SDO_CLI from OD.h not correct!
|
||||
#endif
|
||||
#define CO_RX_CNT_SDO_CLI CO_CNT_SDO_CLI
|
||||
#define CO_TX_CNT_SDO_CLI CO_CNT_SDO_CLI
|
||||
#define CO_RX_CNT_SDO_CLI OD_CNT_SDO_CLI
|
||||
#define CO_TX_CNT_SDO_CLI OD_CNT_SDO_CLI
|
||||
#else
|
||||
#define CO_RX_CNT_SDO_CLI 0
|
||||
#define CO_TX_CNT_SDO_CLI 0
|
||||
#endif
|
||||
|
||||
#if (CO_CONFIG_TIME) & CO_CONFIG_TIME_ENABLE
|
||||
#if !defined CO_CNT_TIME
|
||||
#define CO_CNT_TIME 0
|
||||
#if !defined OD_CNT_TIME
|
||||
#define OD_CNT_TIME 0
|
||||
#define OD_ENTRY_H1012 NULL
|
||||
#elif CO_CNT_TIME < 0 || CO_CNT_TIME > 1
|
||||
#error CO_CNT_TIME from OD.h not correct!
|
||||
#elif OD_CNT_TIME < 0 || OD_CNT_TIME > 1
|
||||
#error OD_CNT_TIME from OD.h not correct!
|
||||
#endif
|
||||
#define CO_RX_CNT_TIME CO_CNT_TIME
|
||||
#define CO_RX_CNT_TIME OD_CNT_TIME
|
||||
#if (CO_CONFIG_TIME) & CO_CONFIG_TIME_PRODUCER
|
||||
#define CO_TX_CNT_TIME CO_CNT_TIME
|
||||
#define CO_TX_CNT_TIME OD_CNT_TIME
|
||||
#else
|
||||
#define CO_TX_CNT_TIME 0
|
||||
#endif
|
||||
|
|
@ -135,16 +135,16 @@
|
|||
#endif
|
||||
|
||||
#if (CO_CONFIG_SYNC) & CO_CONFIG_SYNC_ENABLE
|
||||
#if !defined CO_CNT_SYNC
|
||||
#define CO_CNT_SYNC 0
|
||||
#if !defined OD_CNT_SYNC
|
||||
#define OD_CNT_SYNC 0
|
||||
#define OD_ENTRY_H1005 NULL
|
||||
#define OD_ENTRY_H1006 NULL
|
||||
#elif CO_CNT_SYNC < 0 || CO_CNT_SYNC > 1
|
||||
#error CO_CNT_SYNC from OD.h not correct!
|
||||
#elif OD_CNT_SYNC < 0 || OD_CNT_SYNC > 1
|
||||
#error OD_CNT_SYNC from OD.h not correct!
|
||||
#endif
|
||||
#define CO_RX_CNT_SYNC CO_CNT_SYNC
|
||||
#define CO_RX_CNT_SYNC OD_CNT_SYNC
|
||||
#if (CO_CONFIG_SYNC) & CO_CONFIG_SYNC_PRODUCER
|
||||
#define CO_TX_CNT_SYNC CO_CNT_SYNC
|
||||
#define CO_TX_CNT_SYNC OD_CNT_SYNC
|
||||
#else
|
||||
#define CO_TX_CNT_SYNC 0
|
||||
#endif
|
||||
|
|
@ -160,91 +160,91 @@
|
|||
#endif
|
||||
|
||||
#if (CO_CONFIG_PDO) & CO_CONFIG_RPDO_ENABLE
|
||||
#if !defined CO_CNT_RPDO
|
||||
#define CO_CNT_RPDO 0
|
||||
#if !defined OD_CNT_RPDO
|
||||
#define OD_CNT_RPDO 0
|
||||
#define OD_ENTRY_H1400 NULL
|
||||
#define OD_ENTRY_H1600 NULL
|
||||
#elif CO_CNT_RPDO < 0 || CO_CNT_RPDO > 0x200
|
||||
#error CO_CNT_RPDO from OD.h not correct!
|
||||
#elif OD_CNT_RPDO < 0 || OD_CNT_RPDO > 0x200
|
||||
#error OD_CNT_RPDO from OD.h not correct!
|
||||
#endif
|
||||
#define CO_RX_CNT_RPDO CO_CNT_RPDO
|
||||
#define CO_RX_CNT_RPDO OD_CNT_RPDO
|
||||
#else
|
||||
#define CO_RX_CNT_RPDO 0
|
||||
#endif
|
||||
|
||||
#if (CO_CONFIG_PDO) & CO_CONFIG_TPDO_ENABLE
|
||||
#if !defined CO_CNT_TPDO
|
||||
#define CO_CNT_TPDO 0
|
||||
#if !defined OD_CNT_TPDO
|
||||
#define OD_CNT_TPDO 0
|
||||
#define OD_ENTRY_H1800 NULL
|
||||
#define OD_ENTRY_H1A00 NULL
|
||||
#elif CO_CNT_TPDO < 0 || CO_CNT_TPDO > 0x200
|
||||
#error CO_CNT_TPDO from OD.h not correct!
|
||||
#elif OD_CNT_TPDO < 0 || OD_CNT_TPDO > 0x200
|
||||
#error OD_CNT_TPDO from OD.h not correct!
|
||||
#endif
|
||||
#define CO_TX_CNT_TPDO CO_CNT_TPDO
|
||||
#define CO_TX_CNT_TPDO OD_CNT_TPDO
|
||||
#else
|
||||
#define CO_TX_CNT_TPDO 0
|
||||
#endif
|
||||
|
||||
#if (CO_CONFIG_LEDS) & CO_CONFIG_LEDS_ENABLE
|
||||
#define CO_CNT_LEDS 1
|
||||
#define OD_CNT_LEDS 1
|
||||
#endif
|
||||
|
||||
#if (CO_CONFIG_GFC) & CO_CONFIG_GFC_ENABLE
|
||||
#if !defined CO_CNT_GFC
|
||||
#define CO_CNT_GFC 0
|
||||
#if !defined OD_CNT_GFC
|
||||
#define OD_CNT_GFC 0
|
||||
#define OD_ENTRY_H1300 NULL
|
||||
#elif CO_CNT_GFC < 0 || CO_CNT_GFC > 1
|
||||
#error CO_CNT_GFC from OD.h not correct!
|
||||
#elif OD_CNT_GFC < 0 || OD_CNT_GFC > 1
|
||||
#error OD_CNT_GFC from OD.h not correct!
|
||||
#endif
|
||||
#define CO_RX_CNT_GFC CO_CNT_GFC
|
||||
#define CO_TX_CNT_GFC CO_CNT_GFC
|
||||
#define CO_RX_CNT_GFC OD_CNT_GFC
|
||||
#define CO_TX_CNT_GFC OD_CNT_GFC
|
||||
#else
|
||||
#define CO_RX_CNT_GFC 0
|
||||
#define CO_TX_CNT_GFC 0
|
||||
#endif
|
||||
|
||||
#if (CO_CONFIG_SRDO) & CO_CONFIG_SRDO_ENABLE
|
||||
#if !defined CO_CNT_SRDO
|
||||
#define CO_CNT_SRDO 0
|
||||
#if !defined OD_CNT_SRDO
|
||||
#define OD_CNT_SRDO 0
|
||||
#define OD_ENTRY_H1301 NULL
|
||||
#define OD_ENTRY_H1381 NULL
|
||||
#define OD_ENTRY_H13FE NULL
|
||||
#define OD_ENTRY_H13FF NULL
|
||||
#elif CO_CNT_SRDO < 0 || CO_CNT_SRDO > 64
|
||||
#error CO_CNT_SRDO from OD.h not correct!
|
||||
#elif OD_CNT_SRDO < 0 || OD_CNT_SRDO > 64
|
||||
#error OD_CNT_SRDO from OD.h not correct!
|
||||
#endif
|
||||
#define CO_RX_CNT_SRDO CO_CNT_SRDO
|
||||
#define CO_TX_CNT_SRDO CO_CNT_SRDO
|
||||
#define CO_RX_CNT_SRDO OD_CNT_SRDO
|
||||
#define CO_TX_CNT_SRDO OD_CNT_SRDO
|
||||
#else
|
||||
#define CO_RX_CNT_SRDO 0
|
||||
#define CO_TX_CNT_SRDO 0
|
||||
#endif
|
||||
|
||||
#if (CO_CONFIG_LSS) & CO_CONFIG_LSS_SLAVE
|
||||
#define CO_CNT_LSS_SLV 1
|
||||
#define OD_CNT_LSS_SLV 1
|
||||
#else
|
||||
#define CO_CNT_LSS_SLV 0
|
||||
#define OD_CNT_LSS_SLV 0
|
||||
#endif
|
||||
#define CO_RX_CNT_LSS_SLV CO_CNT_LSS_SLV
|
||||
#define CO_TX_CNT_LSS_SLV CO_CNT_LSS_SLV
|
||||
#define CO_RX_CNT_LSS_SLV OD_CNT_LSS_SLV
|
||||
#define CO_TX_CNT_LSS_SLV OD_CNT_LSS_SLV
|
||||
|
||||
#if (CO_CONFIG_LSS) & CO_CONFIG_LSS_MASTER
|
||||
#define CO_CNT_LSS_MST 1
|
||||
#define OD_CNT_LSS_MST 1
|
||||
#else
|
||||
#define CO_CNT_LSS_MST 0
|
||||
#define OD_CNT_LSS_MST 0
|
||||
#endif
|
||||
#define CO_RX_CNT_LSS_MST CO_CNT_LSS_MST
|
||||
#define CO_TX_CNT_LSS_MST CO_CNT_LSS_MST
|
||||
#define CO_RX_CNT_LSS_MST OD_CNT_LSS_MST
|
||||
#define CO_TX_CNT_LSS_MST OD_CNT_LSS_MST
|
||||
|
||||
#if (CO_CONFIG_GTW) & CO_CONFIG_GTW_ASCII
|
||||
#define CO_CNT_GTWA 1
|
||||
#define OD_CNT_GTWA 1
|
||||
#endif
|
||||
|
||||
#if (CO_CONFIG_TRACE) & CO_CONFIG_TRACE_ENABLE
|
||||
#if !defined CO_CNT_TRACE
|
||||
#define CO_CNT_TRACE 0
|
||||
#elif CO_CNT_TRACE < 0
|
||||
#error CO_CNT_TRACE from OD.h not correct!
|
||||
#if !defined OD_CNT_TRACE
|
||||
#define OD_CNT_TRACE 0
|
||||
#elif OD_CNT_TRACE < 0
|
||||
#error OD_CNT_TRACE from OD.h not correct!
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
|
@ -721,16 +721,16 @@ void CO_delete(CO_t *co) {
|
|||
#endif
|
||||
static CO_t COO;
|
||||
static CO_CANmodule_t COO_CANmodule;
|
||||
static CO_CANrx_t COO_CANmodule_rxArray[CO_CNT_ALL_RX_MSGS];
|
||||
static CO_CANtx_t COO_CANmodule_txArray[CO_CNT_ALL_TX_MSGS];
|
||||
static CO_CANrx_t COO_CANmodule_rxArray[OD_CNT_ALL_RX_MSGS];
|
||||
static CO_CANtx_t COO_CANmodule_txArray[OD_CNT_ALL_TX_MSGS];
|
||||
static CO_NMT_t COO_NMT;
|
||||
#if (CO_CONFIG_HB_CONS) & CO_CONFIG_HB_CONS_ENABLE
|
||||
static CO_HBconsumer_t COO_HBcons;
|
||||
#endif
|
||||
static CO_EM_t COO_EM;
|
||||
static CO_SDOserver_t COO_SDOserver[CO_CNT_SDO_SRV];
|
||||
static CO_SDOserver_t COO_SDOserver[OD_CNT_SDO_SRV];
|
||||
#if (CO_CONFIG_SDO_CLI) & CO_CONFIG_SDO_CLI_ENABLE
|
||||
static CO_SDOclient_t COO_SDOclient[CO_CNT_SDO_CLI];
|
||||
static CO_SDOclient_t COO_SDOclient[OD_CNT_SDO_CLI];
|
||||
#endif
|
||||
#if (CO_CONFIG_TIME) & CO_CONFIG_TIME_ENABLE
|
||||
static CO_TIME_t COO_TIME;
|
||||
|
|
@ -739,10 +739,10 @@ void CO_delete(CO_t *co) {
|
|||
static CO_SYNC_t COO_SYNC;
|
||||
#endif
|
||||
#if (CO_CONFIG_PDO) & CO_CONFIG_RPDO_ENABLE
|
||||
static CO_RPDO_t COO_RPDO[CO_CNT_RPDO];
|
||||
static CO_RPDO_t COO_RPDO[OD_CNT_RPDO];
|
||||
#endif
|
||||
#if (CO_CONFIG_PDO) & CO_CONFIG_TPDO_ENABLE
|
||||
static CO_TPDO_t COO_TPDO[CO_CNT_TPDO];
|
||||
static CO_TPDO_t COO_TPDO[OD_CNT_TPDO];
|
||||
#endif
|
||||
#if (CO_CONFIG_LEDS) & CO_CONFIG_LEDS_ENABLE
|
||||
static CO_LEDs_t COO_LEDs;
|
||||
|
|
@ -752,7 +752,7 @@ void CO_delete(CO_t *co) {
|
|||
#endif
|
||||
#if (CO_CONFIG_SRDO) & CO_CONFIG_SRDO_ENABLE
|
||||
static CO_SRDOGuard_t COO_SRDOGuard;
|
||||
static CO_SRDO_t COO_SRDO[CO_CNT_SRDO];
|
||||
static CO_SRDO_t COO_SRDO[OD_CNT_SRDO];
|
||||
#endif
|
||||
#if (CO_CONFIG_LSS) & CO_CONFIG_LSS_SLAVE
|
||||
static CO_LSSslave_t COO_LSSslave;
|
||||
|
|
@ -767,9 +767,9 @@ void CO_delete(CO_t *co) {
|
|||
#ifndef CO_TRACE_BUFFER_SIZE_FIXED
|
||||
#define CO_TRACE_BUFFER_SIZE_FIXED 100
|
||||
#endif
|
||||
static CO_trace_t COO_trace[CO_CNT_TRACE];
|
||||
static uint32_t COO_traceTimeBuffers[CO_CNT_TRACE][CO_TRACE_BUFFER_SIZE_FIXED];
|
||||
static int32_t COO_traceValueBuffers[CO_CNT_TRACE][CO_TRACE_BUFFER_SIZE_FIXED];
|
||||
static CO_trace_t COO_trace[OD_CNT_TRACE];
|
||||
static uint32_t COO_traceTimeBuffers[OD_CNT_TRACE][CO_TRACE_BUFFER_SIZE_FIXED];
|
||||
static int32_t COO_traceValueBuffers[OD_CNT_TRACE][CO_TRACE_BUFFER_SIZE_FIXED];
|
||||
#endif
|
||||
|
||||
CO_t *CO_new(CO_config_t *config, uint32_t *heapMemoryUsed) {
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ extern "C" {
|
|||
/**
|
||||
* If macro is defined externally, then configuration with multiple object
|
||||
* dictionaries will be possible. If macro is not defined, default "OD.h" file
|
||||
* with necessary definitions, such as CO_CNT_xxx, will be used, and also memory
|
||||
* with necessary definitions, such as OD_CNT_xxx, will be used, and also memory
|
||||
* consumption and startup time will be lower.
|
||||
*/
|
||||
#ifdef CO_DOXYGEN
|
||||
|
|
@ -549,7 +549,7 @@ bool_t CO_process_SYNC(CO_t *co,
|
|||
#endif
|
||||
|
||||
|
||||
#if (CO_CONFIG_PDO) & CO_CONFIG_RPDO_ENABLE
|
||||
#if ((CO_CONFIG_PDO) & CO_CONFIG_RPDO_ENABLE) || defined CO_DOXYGEN
|
||||
/**
|
||||
* Process CANopen RPDO objects.
|
||||
*
|
||||
|
|
@ -565,7 +565,7 @@ void CO_process_RPDO(CO_t *co, bool_t syncWas);
|
|||
#endif
|
||||
|
||||
|
||||
#if (CO_CONFIG_PDO) & CO_CONFIG_TPDO_ENABLE
|
||||
#if ((CO_CONFIG_PDO) & CO_CONFIG_TPDO_ENABLE) || defined CO_DOXYGEN
|
||||
/**
|
||||
* Process CANopen TPDO objects.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -99,9 +99,9 @@ Pair of ODxyz.h/.c files can be generated by OD editor tool. The tool can edit s
|
|||
|
||||
### Example ODxyz.h file
|
||||
```c
|
||||
/* OD data declaration of all groups ******************************************/
|
||||
typedef struct {
|
||||
uint32_t x1000_deviceType;
|
||||
uint8_t x1001_errorRegister;
|
||||
struct {
|
||||
uint8_t maxSubIndex;
|
||||
uint32_t vendorID;
|
||||
|
|
@ -109,19 +109,28 @@ typedef struct {
|
|||
uint32_t revisionNumber;
|
||||
uint32_t serialNumber;
|
||||
} x1018_identity;
|
||||
} ODxyz_0_t;
|
||||
} ODxyz_PERSIST_COMM_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t x1001_errorRegister;
|
||||
} ODxyz_1_t;
|
||||
uint8_t x1003_preDefinedErrorField_sub0;
|
||||
uint32_t x1003_preDefinedErrorField[8];
|
||||
} ODxyz_RAM_t;
|
||||
|
||||
extern ODxyz_0_t ODxyz_0;
|
||||
extern ODxyz_1_t ODxyz_1;
|
||||
extern ODxyz_PERSIST_COMM_t ODxyz_PERSIST_COMM;
|
||||
extern ODxyz_RAM_t ODxyz_RAM;
|
||||
extern const OD_t ODxyz;
|
||||
|
||||
/* Object dictionary entries - shortcuts **************************************/
|
||||
#define ODxyz_ENTRY_H1000 &ODxyz.list[0]
|
||||
#define ODxyz_ENTRY_H1001 &ODxyz.list[1]
|
||||
#define ODxyz_ENTRY_H1018 &ODxyz.list[2]
|
||||
#define ODxyz_ENTRY_H1003 &ODxyz.list[2]
|
||||
#define ODxyz_ENTRY_H1018 &ODxyz.list[3]
|
||||
|
||||
#define ODxyz_ENTRY_H1000_deviceType &ODxyz.list[0]
|
||||
#define ODxyz_ENTRY_H1001_errorRegister &ODxyz.list[1]
|
||||
#define ODxyz_ENTRY_H1003_preDefinedErrorField &ODxyz.list[2]
|
||||
#define ODxyz_ENTRY_H1018_identity &ODxyz.list[3]
|
||||
```
|
||||
|
||||
### Example ODxyz.c file
|
||||
|
|
@ -130,89 +139,110 @@ extern const OD_t ODxyz;
|
|||
#include "301/CO_ODinterface.h"
|
||||
#include "ODxyz.h"
|
||||
|
||||
typedef struct {
|
||||
OD_extensionIO_t xio_1001_errorRegister;
|
||||
} ODxyz_ext_t;
|
||||
|
||||
typedef struct {
|
||||
OD_obj_var_t o_1000_deviceType;
|
||||
OD_obj_var_t orig_1001_errorRegister;
|
||||
OD_obj_extended_t o_1001_errorRegister;
|
||||
OD_obj_var_t o_1018_identity[5];
|
||||
} ODxyz_objs_t;
|
||||
|
||||
ODxyz_0_t ODxyz_0 = {
|
||||
/* OD data initialization of all groups ***************************************/
|
||||
ODxyz_PERSIST_COMM_t ODxyz_PERSIST_COMM = {
|
||||
.x1000_deviceType = 0L,
|
||||
.x1018_identity = {
|
||||
.maxSubIndex = 4,
|
||||
.vendorID = 0L,
|
||||
.productCode = 0L,
|
||||
.revisionNumber = 0L,
|
||||
.serialNumber = 0L,
|
||||
},
|
||||
};
|
||||
|
||||
ODxyz_1_t ODxyz_1 = {
|
||||
.x1001_errorRegister = 0,
|
||||
};
|
||||
|
||||
static ODxyz_ext_t ODxyz_ext = {0};
|
||||
|
||||
static const ODxyz_objs_t ODxyz_objs = {
|
||||
.o_1000_deviceType = {
|
||||
.data = &ODxyz_0.x1000_deviceType,
|
||||
.attribute = ODA_SDO_R | ODA_MB,
|
||||
.dataLength = 4,
|
||||
},
|
||||
.orig_1001_errorRegister = {
|
||||
.data = &ODxyz_1.x1001_errorRegister,
|
||||
.attribute = ODA_SDO_R,
|
||||
.dataLength = 1,
|
||||
},
|
||||
.o_1001_errorRegister = {
|
||||
.flagsPDO = NULL,
|
||||
.extIO = &ODxyz_ext.xio_1001_errorRegister,
|
||||
.odObjectOriginal = &ODxyz_objs.orig_1001_errorRegister,
|
||||
},
|
||||
.o_1018_identity = {
|
||||
{
|
||||
.data = &ODxyz_0.x1018_identity.maxSubIndex,
|
||||
.attribute = ODA_SDO_R,
|
||||
.dataLength = 1,
|
||||
},
|
||||
{
|
||||
.data = &ODxyz_0.x1018_identity.vendorID,
|
||||
.attribute = ODA_SDO_R | ODA_MB,
|
||||
.dataLength = 4,
|
||||
},
|
||||
{
|
||||
.data = &ODxyz_0.x1018_identity.productCode,
|
||||
.attribute = ODA_SDO_R | ODA_MB,
|
||||
.dataLength = 4,
|
||||
},
|
||||
{
|
||||
.data = &ODxyz_0.x1018_identity.revisionNumber,
|
||||
.attribute = ODA_SDO_R | ODA_MB,
|
||||
.dataLength = 4,
|
||||
},
|
||||
{
|
||||
.data = &ODxyz_0.x1018_identity.serialNumber,
|
||||
.attribute = ODA_SDO_R | ODA_MB,
|
||||
.dataLength = 4,
|
||||
},
|
||||
.serialNumber = 0L
|
||||
}
|
||||
};
|
||||
|
||||
static const OD_entry_t ODxyz_list[] = {
|
||||
{0x1000, 0, 0, ODT_VAR, &ODxyz_objs.o_1000_deviceType},
|
||||
{0x1001, 0, 1, ODT_EVAR, &ODxyz_objs.o_1001_errorRegister},
|
||||
{0x1018, 4, 0, ODT_REC, &ODxyz_objs.o_1018_identity},
|
||||
{0x0000, 0, 0, 0, NULL}
|
||||
ODxyz_RAM_t ODxyz_RAM = {
|
||||
.x1001_errorRegister = 0,
|
||||
.x1003_preDefinedErrorField_sub0 = 0,
|
||||
.x1003_preDefinedErrorField = {0, 0, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
const OD_t OD = {
|
||||
(sizeof(OD_list) / sizeof(OD_list[0])) - 1,
|
||||
&ODxyz_list[0]
|
||||
/* IO extensions and flagsPDO (configurable by application) *******************/
|
||||
typedef struct {
|
||||
OD_extensionIO_t xio_1003_preDefinedErrorField;
|
||||
} ODxyzExts_t;
|
||||
|
||||
static ODxyzExts_t ODxyzExts = {0};
|
||||
|
||||
/* All OD objects (constant) **************************************************/
|
||||
typedef struct {
|
||||
OD_obj_var_t o_1000_deviceType;
|
||||
OD_obj_var_t o_1001_errorRegister;
|
||||
OD_obj_array_t o_1003_preDefinedErrorField;
|
||||
OD_obj_extended_t oE_1003_preDefinedErrorField;
|
||||
OD_obj_record_t o_1018_identity[5];
|
||||
} ODxyzObjs_t;
|
||||
|
||||
static const ODxyzObjs_t ODxyzObjs = {
|
||||
.o_1000_deviceType = {
|
||||
.data = &ODxyz_PERSIST_COMM.x1000_deviceType,
|
||||
.attribute = ODA_SDO_R | ODA_MB,
|
||||
.dataLength = 4
|
||||
},
|
||||
.o_1001_errorRegister = {
|
||||
.data = &ODxyz_RAM.x1001_errorRegister,
|
||||
.attribute = ODA_SDO_R,
|
||||
.dataLength = 1
|
||||
},
|
||||
.o_1003_preDefinedErrorField = {
|
||||
.data0 = &ODxyz_RAM.x1003_preDefinedErrorField_sub0,
|
||||
.data = &ODxyz_RAM.x1003_preDefinedErrorField[0],
|
||||
.attribute0 = ODA_SDO_RW,
|
||||
.attribute = ODA_SDO_R | ODA_MB,
|
||||
.dataElementLength = 4,
|
||||
.dataElementSizeof = sizeof(uint32_t)
|
||||
},
|
||||
.oE_1003_preDefinedErrorField = {
|
||||
.extIO = &ODxyzExts.xio_1003_preDefinedErrorField,
|
||||
.flagsPDO = NULL,
|
||||
.odObjectOriginal = &ODxyzObjs.o_1003_preDefinedErrorField
|
||||
},
|
||||
.o_1018_identity = {
|
||||
{
|
||||
.data = &ODxyz_PERSIST_COMM.x1018_identity.maxSubIndex,
|
||||
.subIndex = 0,
|
||||
.attribute = ODA_SDO_R,
|
||||
.dataLength = 1
|
||||
},
|
||||
{
|
||||
.data = &ODxyz_PERSIST_COMM.x1018_identity.vendorID,
|
||||
.subIndex = 1,
|
||||
.attribute = ODA_SDO_R | ODA_MB,
|
||||
.dataLength = 4
|
||||
},
|
||||
{
|
||||
.data = &ODxyz_PERSIST_COMM.x1018_identity.productCode,
|
||||
.subIndex = 2,
|
||||
.attribute = ODA_SDO_R | ODA_MB,
|
||||
.dataLength = 4
|
||||
},
|
||||
{
|
||||
.data = &ODxyz_PERSIST_COMM.x1018_identity.revisionNumber,
|
||||
.subIndex = 3,
|
||||
.attribute = ODA_SDO_R | ODA_MB,
|
||||
.dataLength = 4
|
||||
},
|
||||
{
|
||||
.data = &ODxyz_PERSIST_COMM.x1018_identity.serialNumber,
|
||||
.subIndex = 4,
|
||||
.attribute = ODA_SDO_R | ODA_MB,
|
||||
.dataLength = 4
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* Object dictionary **********************************************************/
|
||||
static const OD_entry_t ODxyzList[] = {
|
||||
{0x1000, 1, ODT_VAR, &ODxyzObjs.o_1000_deviceType},
|
||||
{0x1001, 1, ODT_VAR, &ODxyzObjs.o_1001_errorRegister},
|
||||
{0x1003, 9, ODT_EVAR, &ODxyzObjs.oE_1003_preDefinedErrorField},
|
||||
{0x1018, 5, ODT_REC, &ODxyzObjs.o_1018_identity},
|
||||
{0x0000, 0, 0, NULL}
|
||||
};
|
||||
|
||||
const OD_t ODxyz = {
|
||||
(sizeof(ODxyzList) / sizeof(ODxyzList[0])) - 1,
|
||||
&ODxyzList[0]
|
||||
};
|
||||
```
|
||||
|
||||
|
|
@ -258,7 +288,7 @@ CANopenNode includes multiple profile definition files, one for each CANopen obj
|
|||
<denotation>...</denotation>
|
||||
<BYTE/>
|
||||
<defaultValue value="0" />
|
||||
<property name="CO_storageGroup" value="1">
|
||||
<property name="CO_storageGroup" value="RAM">
|
||||
<property name="CO_extensionIO" value="true">
|
||||
</parameter>
|
||||
<parameter uniqueID="UID_PARAM_1018">
|
||||
|
|
@ -391,40 +421,50 @@ If "uniqueIDRef" attribute is not specified and "objectType" is 7(VAR), then "CA
|
|||
* "noAccess" - object will be in object dictionary, but no access.
|
||||
* <label lang="en"> (required)
|
||||
* <description lang="en"> (required)
|
||||
* <UINT and similar/> (required) - Basic or complex data type. Basic data type (for VAR) is specified in IEC 61131-3 (see below). If data type is complex (ARRAY or RECORD), then <dataTypeIDRef> must be specified and entry must be added in the <dataTypeList>. Such definition of complex data types is required by the standard, but it is not required by CANopenNode.
|
||||
* <defaultValue> (optional for VAR) - Default value for the variable.
|
||||
* <INT and similar/> (required) - Basic or complex data type. Basic data type (for VAR) is specified in IEC 61131-3 (see below). If data type is complex (ARRAY or RECORD), then <dataTypeIDRef> must be specified and entry must be added in the <dataTypeList>. Such definition of complex data types is required by the standard, but it is not required by CANopenNode.
|
||||
* <defaultValue> (optional for VAR) - Default value for the variable. If it is empty, then data is not stored inside object dictionary. Application should provide own data via IO extension.
|
||||
|
||||
Additional, optional, CANopenNode specific properties, which can be used inside parameters describing <CANopenObject>:
|
||||
* <property name="CO_storageGroup" value="..."> - group into which the C variable will belong. Variables from specific storage group may then be stored into non-volatile memory, automatically or by SDO command. Valid value is from 0x00 (default - not stored) to 0x7F.
|
||||
* <property name="CO_storageGroup" value="..."> - group name (string) into which the C variable will belong. Variables from specific storage group may then be stored into non-volatile memory, automatically or by SDO command.
|
||||
* <property name="CO_extensionIO" value="..."> - Valid value is "false" (default) or "true", if IO extension is enabled.
|
||||
* <property name="CO_flagsPDO" value="..."> - Valid value is "false" (default) or "true", if PDO flags are enabled.
|
||||
* <property name="CO_countLabel" value="..."> - Valid value is any string without spaces. OD exporter will generate a macro for each different string. For example, if four OD objects have "CO_countLabel" set to "TPDO", then macro "#define ODxyz_CNT_TPDO 4" will be generated by OD exporter.
|
||||
|
||||
Additional, optional, CANopenNode specific property, which can be used inside parameters describing "VAR":
|
||||
* <property name="CO_accessSRDO" value="..."> - Valid values are: "tx", "rx", "trx", "no"(default).
|
||||
* <property name="CO_byteLength" value="..."> - Length of the variable in bytes, optionally used by string or domain. If CO_byteLength is not specified for string, then length is calculated from string <defaultValue>.
|
||||
* <property name="CO_stringLength" value="..."> - Minimum length of the string. Used with "VISIBLE_STRING", "OCTET_STRING" and "UNICODE_STRING". If CO_stringLength smaller than length of string in <defaultValue>, then it is ignored. Byte length of unicode string is 2 * CO_stringLength. If <defaultValue> is empty and CO_stringLength is 0, then data is not stored inside object dictionary.
|
||||
|
||||
#### CANopen basic data types
|
||||
| CANopenNode | IEC 61131-3 | CANopen | dataType |
|
||||
| ------------ | ------------ | --------------- | -------- |
|
||||
| bool_t | BOOL | BOOLEAN | 0x01 |
|
||||
| int8_t | CHAR, SINT | INTEGER8 | 0x02 |
|
||||
| int16_t | INT | INTEGER16 | 0x03 |
|
||||
| int32_t | DINT | INTEGER32 | 0x04 |
|
||||
| int64_t | LINT | INTEGER64 | 0x15 |
|
||||
| uint8_t | BYTE, USINT | UNSIGNED8 | 0x05 |
|
||||
| uint16_t | WORD, UINT | UNSIGNED16 | 0x06 |
|
||||
| uint32_t | DWORD, UDINT | UNSIGNED32 | 0x07 |
|
||||
| uint64_t | LWORD, ULINT | UNSIGNED64 | 0x1B |
|
||||
| float32_t | REAL | REAL32 | 0x08 |
|
||||
| float64_t | LREAL | REAL64 | 0x11 |
|
||||
| bytestring_t | STRING | VISIBLE_STRING | 0x09 |
|
||||
| bytestring_t | - | OCTET_STRING | 0x0A |
|
||||
| bytestring_t | WSTRING | UNICODE_STRING | 0x0B |
|
||||
| bytestring_t | - | TIME_OF_DAY | 0x0C |
|
||||
| bytestring_t | - | TIME_DIFFERENCE | 0x0D |
|
||||
| bytestring_t | - | DOMAIN | 0x0F |
|
||||
| bytestring_t | BITSTRING | - | - |
|
||||
| CANopenNode | IEC 61131-3 | CANopen | dataType |
|
||||
| -------------- | -------------- | --------------- | -------- |
|
||||
| bool_t | BOOL | BOOLEAN | 0x01 |
|
||||
| int8_t | SINT, (CHAR) | INTEGER8 | 0x02 |
|
||||
| int16_t | INT | INTEGER16 | 0x03 |
|
||||
| int32_t | DINT | INTEGER32 | 0x04 |
|
||||
| int64_t | LINT | INTEGER64 | 0x15 |
|
||||
| uint8_t | USINT, (BYTE) | UNSIGNED8 | 0x05 |
|
||||
| uint16_t | UINT, (WORD) | UNSIGNED16 | 0x06 |
|
||||
| uint32_t | UDINT, (DWORD) | UNSIGNED32 | 0x07 |
|
||||
| uint64_t | ULINT, (LWORD) | UNSIGNED64 | 0x1B |
|
||||
| float32_t | REAL | REAL32 | 0x08 |
|
||||
| float64_t | LREAL | REAL64 | 0x11 |
|
||||
| uint8_t [] (1) | BITSTRING (2) | INTEGER24 | 0x10 |
|
||||
| uint8_t [] (1) | BITSTRING (2) | INTEGER40 | 0x12 |
|
||||
| uint8_t [] (1) | BITSTRING (2) | INTEGER48 | 0x13 |
|
||||
| uint8_t [] (1) | BITSTRING (2) | INTEGER56 | 0x14 |
|
||||
| uint8_t [] (1) | BITSTRING (2) | UNSIGNED24 | 0x16 |
|
||||
| uint8_t [] (1) | BITSTRING (2) | UNSIGNED40 | 0x18 |
|
||||
| uint8_t [] (1) | BITSTRING (2) | UNSIGNED48 | 0x19 |
|
||||
| uint8_t [] (1) | BITSTRING (2) | UNSIGNED56 | 0x1A |
|
||||
| char [] | STRING | VISIBLE_STRING | 0x09 |
|
||||
| uint8_t [] | BITSTRING (2) | OCTET_STRING | 0x0A |
|
||||
| uint16_t [] | WSTRING | UNICODE_STRING | 0x0B |
|
||||
| uint8_t [] (1) | BITSTRING (2) | TIME_OF_DAY | 0x0C |
|
||||
| uint8_t [] (1) | BITSTRING (2) | TIME_DIFFERENCE | 0x0D |
|
||||
| not used | BITSTRING (2) | DOMAIN | 0x0F |
|
||||
(1) Data is stored in little-endian format.
|
||||
|
||||
(2) CANopen specific type is stored as <BITSTRING/> in <parameter> and additional CANopen "dataType" attribute is stored in <CANopenObject> or <CANopenSubObject>.
|
||||
|
||||
#### <parameterGroupList>
|
||||
This is optional element and is not required by standard, nor by CANopenNode. This can be very useful for documentation, which can be organised into multiple chapters with multiple levels. CANopen objects can then be organised in any way, not only by index.
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
#include "OD.h"
|
||||
|
||||
static const OD_entry_t OD_list[] = {
|
||||
{0x1000, 0, 0, 0, NULL}
|
||||
{0x1000, 0, 0, NULL}
|
||||
};
|
||||
|
||||
const OD_t OD = {
|
||||
|
|
|
|||
30
example/OD.h
30
example/OD.h
|
|
@ -2,23 +2,23 @@
|
|||
|
||||
extern const OD_t OD;
|
||||
|
||||
#define CO_CNT_NMT 1
|
||||
#define CO_CNT_HB_PROD 1
|
||||
#define CO_CNT_EM 1
|
||||
#define CO_CNT_EM_PROD 1
|
||||
#define CO_CNT_SDO_SRV 1
|
||||
#define CO_CNT_SDO_CLI 1
|
||||
#define OD_CNT_NMT 1
|
||||
#define OD_CNT_HB_PROD 1
|
||||
#define OD_CNT_EM 1
|
||||
#define OD_CNT_EM_PROD 1
|
||||
#define OD_CNT_SDO_SRV 1
|
||||
#define OD_CNT_SDO_CLI 1
|
||||
|
||||
#if 0
|
||||
#define CO_CNT_HB_CONS 1
|
||||
#define CO_CNT_TIME 1
|
||||
#define CO_CNT_SYNC 1
|
||||
#define CO_CNT_SYNC_PROD 1
|
||||
#define CO_CNT_RPDO 4
|
||||
#define CO_CNT_TPDO 4
|
||||
#define CO_CNT_GFC 0
|
||||
#define CO_CNT_SRDO 0
|
||||
#define CO_CNT_TRACE 0
|
||||
#define OD_CNT_HB_CONS 1
|
||||
#define OD_CNT_TIME 1
|
||||
#define OD_CNT_SYNC 1
|
||||
#define OD_CNT_SYNC_PROD 1
|
||||
#define OD_CNT_RPDO 4
|
||||
#define OD_CNT_TPDO 4
|
||||
#define OD_CNT_GFC 0
|
||||
#define OD_CNT_SRDO 0
|
||||
#define OD_CNT_TRACE 0
|
||||
#endif
|
||||
|
||||
#define OD_ENTRY_H1017 &OD.list[0]
|
||||
|
|
|
|||
Loading…
Reference in a new issue