1
0
Fork 0

CO_ODinterface - Change some API:

- Add OD_getPtr_vs(), OD_getPtr_os() and OD_getPtr_us().
- Move read/write from OD_subEntry_t into OD_IO_t structure.
- Change argument in OD_getSub(), use OD_IO_t instead OD_stream_t.
- OD_getSub(), argument subEntry is optional.
- Change return value of OD_extensionIO_init() to ODR_t.
This commit is contained in:
Janez 2020-12-02 16:44:31 +01:00
parent d224de0ac9
commit 09bf926856
7 changed files with 434 additions and 312 deletions

View file

@ -55,9 +55,9 @@
#if (CO_CONFIG_EM) & CO_CONFIG_EM_PRODUCER
#if (CO_CONFIG_EM) & CO_CONFIG_EM_PROD_CONFIGURABLE
/*
* Custom functions for read/write OD variable "COB-ID EMCY"
* Custom functions for read/write OD object "COB-ID EMCY"
*
* For more information see file CO_ODinterface.h, OD_subEntry_t.
* For more information see file CO_ODinterface.h, OD_IO_t.
*/
static OD_size_t OD_read_1014(OD_stream_t *stream, uint8_t subIndex,
void *buf, OD_size_t count,
@ -128,9 +128,9 @@ static OD_size_t OD_write_1014(OD_stream_t *stream, uint8_t subIndex,
}
#else
/*
* Custom functions for read/write OD variable "COB-ID EMCY"
* Custom functions for read/write OD object "COB-ID EMCY"
*
* For more information see file CO_ODinterface.h, OD_subEntry_t.
* For more information see file CO_ODinterface.h, OD_IO_t.
*/
static OD_size_t OD_read_1014_default(OD_stream_t *stream, uint8_t subIndex,
void *buf, OD_size_t count,
@ -154,9 +154,9 @@ static OD_size_t OD_read_1014_default(OD_stream_t *stream, uint8_t subIndex,
#if (CO_CONFIG_EM) & CO_CONFIG_EM_PROD_INHIBIT
/*
* Custom function for writing OD variable "Inhibit time EMCY"
* Custom function for writing OD object "Inhibit time EMCY"
*
* For more information see file CO_ODinterface.h, OD_subEntry_t.
* For more information see file CO_ODinterface.h, OD_IO_t.
*/
static OD_size_t OD_write_1015(OD_stream_t *stream, uint8_t subIndex,
const void *buf, OD_size_t count,
@ -183,9 +183,9 @@ static OD_size_t OD_write_1015(OD_stream_t *stream, uint8_t subIndex,
#if (CO_CONFIG_EM) & CO_CONFIG_EM_HISTORY
/*
* Custom functions for read/write OD variable _OD_statusBits_, optional
* Custom functions for read/write OD object _OD_statusBits_, optional
*
* For more information see file CO_ODinterface.h, OD_subEntry_t.
* For more information see file CO_ODinterface.h, OD_IO_t.
*/
static OD_size_t OD_read_1003(OD_stream_t *stream, uint8_t subIndex,
void *buf, OD_size_t count,
@ -251,9 +251,9 @@ static OD_size_t OD_write_1003(OD_stream_t *stream, uint8_t subIndex,
#if (CO_CONFIG_EM) & CO_CONFIG_EM_STATUS_BITS
/*
* Custom functions for read/write OD variable _OD_statusBits_, optional
* Custom functions for read/write OD object _OD_statusBits_, optional
*
* For more information see file CO_ODinterface.h, OD_subEntry_t.
* For more information see file CO_ODinterface.h, OD_IO_t.
*/
static OD_size_t OD_read_statusBits(OD_stream_t *stream, uint8_t subIndex,
void *buf, OD_size_t count,
@ -410,10 +410,11 @@ CO_ReturnError_t CO_EM_init(CO_EM_t *em,
uint16_t producerCanId = (uint16_t)(COB_IDEmergency32 & 0x7FF);
em->producerEnabled = (COB_IDEmergency32 & 0x80000000) == 0
&& producerCanId != 0;
if (!OD_extensionIO_init(OD_1014_cobIdEm,
(void *) em,
OD_read_1014,
OD_write_1014)) {
ODR_t odRetE = OD_extensionIO_init(OD_1014_cobIdEm,
(void *) em,
OD_read_1014,
OD_write_1014);
if (odRetE != ODR_OK) {
CO_errinfo(CANdevTx, OD_getIndex(OD_1014_cobIdEm));
return CO_ERROR_OD_PARAMETERS;
}
@ -427,10 +428,11 @@ CO_ReturnError_t CO_EM_init(CO_EM_t *em,
#else
uint16_t producerCanId = CO_CAN_ID_EMERGENCY + nodeId;
em->producerEnabled = (COB_IDEmergency32 & 0x80000000) == 0;
if (!OD_extensionIO_init(OD_1014_cobIdEm,
(void *) em,
OD_read_1014_default,
OD_writeOriginal)) {
ODR_t odRetE = OD_extensionIO_init(OD_1014_cobIdEm,
(void *) em,
OD_read_1014_default,
OD_writeOriginal);
if (odRetE != ODR_OK) {
CO_errinfo(CANdevTx, OD_getIndex(OD_1014_cobIdEm));
return CO_ERROR_OD_PARAMETERS;
}

View file

@ -55,9 +55,9 @@ static void CO_NMT_receive(void *object, void *msg) {
/*
* Custom function for writing OD variable "Producer heartbeat time"
* Custom function for writing OD object "Producer heartbeat time"
*
* For more information see file CO_ODinterface.h, OD_subEntry_t.
* For more information see file CO_ODinterface.h, OD_IO_t.
*/
static OD_size_t OD_write_1017(OD_stream_t *stream, uint8_t subIndex,
const void *buf, OD_size_t count,
@ -125,19 +125,22 @@ CO_ReturnError_t CO_NMT_init(CO_NMT_t *NMT,
/* get and verify required "Producer heartbeat time" from Object Dict. */
uint16_t HBprodTime_ms;
if (OD_get_u16(OD_1017_ProducerHbTime, 0, &HBprodTime_ms, true) != ODR_OK) {
ODR_t odRet = OD_get_u16(OD_1017_ProducerHbTime, 0, &HBprodTime_ms, true);
if (odRet != ODR_OK) {
CO_errinfo(NMT_CANdevRx, OD_getIndex(OD_1017_ProducerHbTime));
return CO_ERROR_OD_PARAMETERS;
}
NMT->HBproducerTime_us = (uint32_t)HBprodTime_ms * 1000;
if (!OD_extensionIO_init(OD_1017_ProducerHbTime,
(void *) NMT,
OD_readOriginal,
OD_write_1017)
) {
odRet = OD_extensionIO_init(OD_1017_ProducerHbTime,
(void *) NMT,
OD_readOriginal,
OD_write_1017);
if (odRet != ODR_OK) {
CO_errinfo(HB_CANdevTx, OD_getIndex(OD_1017_ProducerHbTime));
return CO_ERROR_OD_PARAMETERS;
}
if (NMT->HBproducerTimer > NMT->HBproducerTime_us) {
NMT->HBproducerTimer = NMT->HBproducerTime_us;
}

View file

@ -109,7 +109,7 @@ OD_size_t OD_writeOriginal(OD_stream_t *stream, uint8_t subIndex,
odData += stream->dataOffset;
if (dataLenToCopy > count) {
/* Reamining data space in OD variable is larger than current count
/* Remaining data space in OD variable is larger than current count
* of data, so only current count of data will be copied */
dataLenToCopy = count;
stream->dataOffset += dataLenToCopy;
@ -121,7 +121,7 @@ OD_size_t OD_writeOriginal(OD_stream_t *stream, uint8_t subIndex,
}
if (dataLenToCopy < count) {
/* OD variable is smaller than current ammount of data */
/* OD variable is smaller than current amount of data */
*returnCode = ODR_DATA_LONG;
return 0;
}
@ -133,25 +133,25 @@ OD_size_t OD_writeOriginal(OD_stream_t *stream, uint8_t subIndex,
}
}
/* Read value from variable from Object Dictionary disabled, see OD_subEntry_t*/
/* Read value from variable from Object Dictionary disabled, see OD_IO_t*/
static OD_size_t OD_readDisabled(OD_stream_t *stream, uint8_t subIndex,
void *buf, OD_size_t count,
ODR_t *returnCode)
{
(void) stream; (void) subIndex; (void) buf; (void) count;
if (returnCode != NULL) *returnCode = ODR_WRITEONLY;
if (returnCode != NULL) *returnCode = ODR_UNSUPP_ACCESS;
return 0;
}
/* Write value to variable from Object Dictionary disabled, see OD_subEntry_t */
/* Write value to variable from Object Dictionary disabled, see OD_IO_t */
static OD_size_t OD_writeDisabled(OD_stream_t *stream, uint8_t subIndex,
const void *buf, OD_size_t count,
ODR_t *returnCode)
{
(void) stream; (void) subIndex; (void) buf; (void) count;
if (returnCode != NULL) *returnCode = ODR_READONLY;
if (returnCode != NULL) *returnCode = ODR_UNSUPP_ACCESS;
return 0;
}
@ -198,14 +198,15 @@ const OD_entry_t *OD_find(const OD_t *od, uint16_t index) {
/******************************************************************************/
ODR_t OD_getSub(const OD_entry_t *entry, uint8_t subIndex,
OD_subEntry_t *subEntry, OD_stream_t *stream, bool_t odOrig)
OD_subEntry_t *subEntry, OD_IO_t *io, bool_t odOrig)
{
if (entry == NULL || entry->odObject == NULL) return ODR_IDX_NOT_EXIST;
else if (subEntry == NULL || stream == NULL) return ODR_DEV_INCOMPAT;
else if (io == NULL) return ODR_DEV_INCOMPAT;
const void *odObjectOrig = entry->odObject;
const OD_obj_extended_t *odObjectExt = NULL;
uint8_t odBasicType = entry->odObjectType & ODT_TYPE_MASK;
OD_attr_t attr = 0;
/* Is object type extended? */
if ((entry->odObjectType & ODT_EXTENSION_MASK) != 0) {
@ -214,42 +215,35 @@ ODR_t OD_getSub(const OD_entry_t *entry, uint8_t subIndex,
if (odObjectOrig == NULL) return ODR_DEV_INCOMPAT;
}
/* common properties */
subEntry->index = entry->index;
subEntry->subIndex = subIndex;
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;
stream->dataObjectOriginal = odo->data;
stream->dataLength = odo->dataLength;
attr = odo->attribute;
io->stream.dataObjectOriginal = odo->data;
io->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) {
subEntry->attribute = odo->attribute0;
stream->dataObjectOriginal = odo->data0;
stream->dataLength = 1;
attr = odo->attribute0;
io->stream.dataObjectOriginal = odo->data0;
io->stream.dataLength = 1;
}
else {
subEntry->attribute = odo->attribute;
attr = odo->attribute;
if (odo->data == NULL) {
stream->dataObjectOriginal = NULL;
io->stream.dataObjectOriginal = NULL;
}
else {
char *data = (char *)odo->data;
int i = subIndex - 1;
stream->dataObjectOriginal = data + odo->dataElementSizeof * i;
io->stream.dataObjectOriginal = data + odo->dataElementSizeof * i;
}
stream->dataLength = odo->dataElementLength;
io->stream.dataLength = odo->dataElementLength;
}
}
else if (odBasicType == ODT_REC) {
@ -263,9 +257,9 @@ ODR_t OD_getSub(const OD_entry_t *entry, uint8_t subIndex,
}
if (odo == NULL) return ODR_SUB_NOT_EXIST;
subEntry->attribute = odo->attribute;
stream->dataObjectOriginal = odo->data;
stream->dataLength = odo->dataLength;
attr = odo->attribute;
io->stream.dataObjectOriginal = odo->data;
io->stream.dataLength = odo->dataLength;
}
else {
return ODR_DEV_INCOMPAT;
@ -273,18 +267,29 @@ ODR_t OD_getSub(const OD_entry_t *entry, uint8_t subIndex,
/* read, write and dataObject, direct or with IO extension */
if (odObjectExt == NULL || odObjectExt->extIO == NULL || odOrig) {
subEntry->read = OD_readOriginal;
subEntry->write = OD_writeOriginal;
stream->object = NULL;
io->read = OD_readOriginal;
io->write = OD_writeOriginal;
io->stream.object = NULL;
}
else {
subEntry->read = odObjectExt->extIO->read != NULL ?
odObjectExt->extIO->read : OD_readDisabled;
subEntry->write = odObjectExt->extIO->write != NULL ?
odObjectExt->extIO->write : OD_writeDisabled;
stream->object = odObjectExt->extIO->object;
io->read = odObjectExt->extIO->read != NULL ?
odObjectExt->extIO->read : OD_readDisabled;
io->write = odObjectExt->extIO->write != NULL ?
odObjectExt->extIO->write : OD_writeDisabled;
io->stream.object = odObjectExt->extIO->object;
}
/* common properties */
if (subEntry != NULL) {
subEntry->index = entry->index;
subEntry->subIndex = subIndex;
subEntry->subEntriesCount = entry->subEntriesCount;
subEntry->attribute = attr;
subEntry->flagsPDO = odObjectExt != NULL ?
odObjectExt->flagsPDO : NULL;
}
io->stream.dataOffset = 0;
return ODR_OK;
}
@ -324,34 +329,34 @@ uint32_t OD_getSDOabCode(ODR_t returnCode) {
}
/******************************************************************************/
bool_t OD_extensionIO_init(const OD_entry_t *entry,
void *object,
OD_size_t (*read)(OD_stream_t *stream,
ODR_t OD_extensionIO_init(const OD_entry_t *entry,
void *object,
OD_size_t (*read)(OD_stream_t *stream,
uint8_t subIndex,
void *buf,
OD_size_t count,
ODR_t *returnCode),
OD_size_t (*write)(OD_stream_t *stream,
uint8_t subIndex,
void *buf,
const void *buf,
OD_size_t count,
ODR_t *returnCode),
OD_size_t (*write)(OD_stream_t *stream,
uint8_t subIndex,
const void *buf,
OD_size_t count,
ODR_t *returnCode))
ODR_t *returnCode))
{
if (entry == NULL || (entry->odObjectType & ODT_EXTENSION_MASK) == 0) {
return false;
if (entry == NULL) {
return ODR_IDX_NOT_EXIST;
}
const OD_obj_extended_t *odo = (const OD_obj_extended_t *) entry->odObject;
if (odo->extIO == NULL) {
return false;
if ((entry->odObjectType & ODT_EXTENSION_MASK) == 0 || odo->extIO == NULL) {
return ODR_PAR_INCOMPAT;
}
odo->extIO->object = object;
odo->extIO->read = read;
odo->extIO->write = write;
return true;
return ODR_OK;
}
@ -359,110 +364,120 @@ bool_t OD_extensionIO_init(const OD_entry_t *entry,
ODR_t OD_get_i8(const OD_entry_t *entry, uint8_t subIndex,
int8_t *val, bool_t odOrig)
{
OD_subEntry_t subEntry; OD_stream_t st;
ODR_t ret = OD_getSub(entry, subIndex, &subEntry, &st, odOrig);
OD_IO_t io;
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
if (ret == ODR_OK && st.dataLength != sizeof(*val)) ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) subEntry.read(&st, subIndex, val, sizeof(*val), &ret);
if (ret == ODR_OK && io.stream.dataLength != sizeof(*val))
ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) io.read(&io.stream, subIndex, val, sizeof(*val), &ret);
return ret;
}
ODR_t OD_get_i16(const OD_entry_t *entry, uint8_t subIndex,
int16_t *val, bool_t odOrig)
{
OD_subEntry_t subEntry; OD_stream_t st;
ODR_t ret = OD_getSub(entry, subIndex, &subEntry, &st, odOrig);
OD_IO_t io;
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
if (ret == ODR_OK && st.dataLength != sizeof(*val)) ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) subEntry.read(&st, subIndex, val, sizeof(*val), &ret);
if (ret == ODR_OK && io.stream.dataLength != sizeof(*val))
ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) io.read(&io.stream, subIndex, val, sizeof(*val), &ret);
return ret;
}
ODR_t OD_get_i32(const OD_entry_t *entry, uint8_t subIndex,
int32_t *val, bool_t odOrig)
{
OD_subEntry_t subEntry; OD_stream_t st;
ODR_t ret = OD_getSub(entry, subIndex, &subEntry, &st, odOrig);
OD_IO_t io;
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
if (ret == ODR_OK && st.dataLength != sizeof(*val)) ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) subEntry.read(&st, subIndex, val, sizeof(*val), &ret);
if (ret == ODR_OK && io.stream.dataLength != sizeof(*val))
ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) io.read(&io.stream, subIndex, val, sizeof(*val), &ret);
return ret;
}
ODR_t OD_get_i64(const OD_entry_t *entry, uint8_t subIndex,
int64_t *val, bool_t odOrig)
{
OD_subEntry_t subEntry; OD_stream_t st;
ODR_t ret = OD_getSub(entry, subIndex, &subEntry, &st, odOrig);
OD_IO_t io;
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
if (ret == ODR_OK && st.dataLength != sizeof(*val)) ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) subEntry.read(&st, subIndex, val, sizeof(*val), &ret);
if (ret == ODR_OK && io.stream.dataLength != sizeof(*val))
ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) io.read(&io.stream, subIndex, val, sizeof(*val), &ret);
return ret;
}
ODR_t OD_get_u8(const OD_entry_t *entry, uint8_t subIndex,
uint8_t *val, bool_t odOrig)
{
OD_subEntry_t subEntry; OD_stream_t st;
ODR_t ret = OD_getSub(entry, subIndex, &subEntry, &st, odOrig);
OD_IO_t io;
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
if (ret == ODR_OK && st.dataLength != sizeof(*val)) ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) subEntry.read(&st, subIndex, val, sizeof(*val), &ret);
if (ret == ODR_OK && io.stream.dataLength != sizeof(*val))
ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) io.read(&io.stream, subIndex, val, sizeof(*val), &ret);
return ret;
}
ODR_t OD_get_u16(const OD_entry_t *entry, uint8_t subIndex,
uint16_t *val, bool_t odOrig)
{
OD_subEntry_t subEntry; OD_stream_t st;
ODR_t ret = OD_getSub(entry, subIndex, &subEntry, &st, odOrig);
OD_IO_t io;
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
if (ret == ODR_OK && st.dataLength != sizeof(*val)) ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) subEntry.read(&st, subIndex, val, sizeof(*val), &ret);
if (ret == ODR_OK && io.stream.dataLength != sizeof(*val))
ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) io.read(&io.stream, subIndex, val, sizeof(*val), &ret);
return ret;
}
ODR_t OD_get_u32(const OD_entry_t *entry, uint8_t subIndex,
uint32_t *val, bool_t odOrig)
{
OD_subEntry_t subEntry; OD_stream_t st;
ODR_t ret = OD_getSub(entry, subIndex, &subEntry, &st, odOrig);
OD_IO_t io;
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
if (ret == ODR_OK && st.dataLength != sizeof(*val)) ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) subEntry.read(&st, subIndex, val, sizeof(*val), &ret);
if (ret == ODR_OK && io.stream.dataLength != sizeof(*val))
ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) io.read(&io.stream, subIndex, val, sizeof(*val), &ret);
return ret;
}
ODR_t OD_get_u64(const OD_entry_t *entry, uint8_t subIndex,
uint64_t *val, bool_t odOrig)
{
OD_subEntry_t subEntry; OD_stream_t st;
ODR_t ret = OD_getSub(entry, subIndex, &subEntry, &st, odOrig);
OD_IO_t io;
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
if (ret == ODR_OK && st.dataLength != sizeof(*val)) ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) subEntry.read(&st, subIndex, val, sizeof(*val), &ret);
if (ret == ODR_OK && io.stream.dataLength != sizeof(*val))
ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) io.read(&io.stream, subIndex, val, sizeof(*val), &ret);
return ret;
}
ODR_t OD_get_r32(const OD_entry_t *entry, uint8_t subIndex,
float32_t *val, bool_t odOrig)
{
OD_subEntry_t subEntry; OD_stream_t st;
ODR_t ret = OD_getSub(entry, subIndex, &subEntry, &st, odOrig);
OD_IO_t io;
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
if (ret == ODR_OK && st.dataLength != sizeof(*val)) ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) subEntry.read(&st, subIndex, val, sizeof(*val), &ret);
if (ret == ODR_OK && io.stream.dataLength != sizeof(*val))
ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) io.read(&io.stream, subIndex, val, sizeof(*val), &ret);
return ret;
}
ODR_t OD_get_r64(const OD_entry_t *entry, uint8_t subIndex,
float64_t *val, bool_t odOrig)
{
OD_subEntry_t subEntry; OD_stream_t st;
ODR_t ret = OD_getSub(entry, subIndex, &subEntry, &st, odOrig);
OD_IO_t io;
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
if (ret == ODR_OK && st.dataLength != sizeof(*val)) ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) subEntry.read(&st, subIndex, val, sizeof(*val), &ret);
if (ret == ODR_OK && io.stream.dataLength != sizeof(*val))
ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) io.read(&io.stream, subIndex, val, sizeof(*val), &ret);
return ret;
}
@ -470,210 +485,304 @@ ODR_t OD_get_r64(const OD_entry_t *entry, uint8_t subIndex,
ODR_t OD_set_i8(const OD_entry_t *entry, uint8_t subIndex,
int8_t val, bool_t odOrig)
{
OD_subEntry_t subEntry; OD_stream_t st;
ODR_t ret = OD_getSub(entry, subIndex, &subEntry, &st, odOrig);
OD_IO_t io;
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
if (ret == ODR_OK && st.dataLength != sizeof(val)) ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) subEntry.write(&st, subIndex, &val, sizeof(val), &ret);
if (ret == ODR_OK && io.stream.dataLength != sizeof(val))
ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) io.write(&io.stream, subIndex, &val, sizeof(val), &ret);
return ret;
}
ODR_t OD_set_i16(const OD_entry_t *entry, uint8_t subIndex,
int16_t val, bool_t odOrig)
{
OD_subEntry_t subEntry; OD_stream_t st;
ODR_t ret = OD_getSub(entry, subIndex, &subEntry, &st, odOrig);
OD_IO_t io;
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
if (ret == ODR_OK && st.dataLength != sizeof(val)) ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) subEntry.write(&st, subIndex, &val, sizeof(val), &ret);
if (ret == ODR_OK && io.stream.dataLength != sizeof(val))
ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) io.write(&io.stream, subIndex, &val, sizeof(val), &ret);
return ret;
}
ODR_t OD_set_i32(const OD_entry_t *entry, uint8_t subIndex,
int32_t val, bool_t odOrig)
{
OD_subEntry_t subEntry; OD_stream_t st;
ODR_t ret = OD_getSub(entry, subIndex, &subEntry, &st, odOrig);
OD_IO_t io;
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
if (ret == ODR_OK && st.dataLength != sizeof(val)) ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) subEntry.write(&st, subIndex, &val, sizeof(val), &ret);
if (ret == ODR_OK && io.stream.dataLength != sizeof(val))
ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) io.write(&io.stream, subIndex, &val, sizeof(val), &ret);
return ret;
}
ODR_t OD_set_i64(const OD_entry_t *entry, uint8_t subIndex,
int64_t val, bool_t odOrig)
{
OD_subEntry_t subEntry; OD_stream_t st;
ODR_t ret = OD_getSub(entry, subIndex, &subEntry, &st, odOrig);
OD_IO_t io;
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
if (ret == ODR_OK && st.dataLength != sizeof(val)) ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) subEntry.write(&st, subIndex, &val, sizeof(val), &ret);
if (ret == ODR_OK && io.stream.dataLength != sizeof(val))
ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) io.write(&io.stream, subIndex, &val, sizeof(val), &ret);
return ret;
}
ODR_t OD_set_u8(const OD_entry_t *entry, uint8_t subIndex,
uint8_t val, bool_t odOrig)
{
OD_subEntry_t subEntry; OD_stream_t st;
ODR_t ret = OD_getSub(entry, subIndex, &subEntry, &st, odOrig);
OD_IO_t io;
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
if (ret == ODR_OK && st.dataLength != sizeof(val)) ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) subEntry.write(&st, subIndex, &val, sizeof(val), &ret);
if (ret == ODR_OK && io.stream.dataLength != sizeof(val))
ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) io.write(&io.stream, subIndex, &val, sizeof(val), &ret);
return ret;
}
ODR_t OD_set_u16(const OD_entry_t *entry, uint8_t subIndex,
uint16_t val, bool_t odOrig)
{
OD_subEntry_t subEntry; OD_stream_t st;
ODR_t ret = OD_getSub(entry, subIndex, &subEntry, &st, odOrig);
OD_IO_t io;
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
if (ret == ODR_OK && st.dataLength != sizeof(val)) ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) subEntry.write(&st, subIndex, &val, sizeof(val), &ret);
if (ret == ODR_OK && io.stream.dataLength != sizeof(val))
ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) io.write(&io.stream, subIndex, &val, sizeof(val), &ret);
return ret;
}
ODR_t OD_set_u32(const OD_entry_t *entry, uint8_t subIndex,
uint32_t val, bool_t odOrig)
{
OD_subEntry_t subEntry; OD_stream_t st;
ODR_t ret = OD_getSub(entry, subIndex, &subEntry, &st, odOrig);
OD_IO_t io;
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
if (ret == ODR_OK && st.dataLength != sizeof(val)) ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) subEntry.write(&st, subIndex, &val, sizeof(val), &ret);
if (ret == ODR_OK && io.stream.dataLength != sizeof(val))
ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) io.write(&io.stream, subIndex, &val, sizeof(val), &ret);
return ret;
}
ODR_t OD_set_u64(const OD_entry_t *entry, uint8_t subIndex,
uint64_t val, bool_t odOrig)
{
OD_subEntry_t subEntry; OD_stream_t st;
ODR_t ret = OD_getSub(entry, subIndex, &subEntry, &st, odOrig);
OD_IO_t io;
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
if (ret == ODR_OK && st.dataLength != sizeof(val)) ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) subEntry.write(&st, subIndex, &val, sizeof(val), &ret);
if (ret == ODR_OK && io.stream.dataLength != sizeof(val))
ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) io.write(&io.stream, subIndex, &val, sizeof(val), &ret);
return ret;
}
ODR_t OD_set_r32(const OD_entry_t *entry, uint8_t subIndex,
float32_t val, bool_t odOrig)
{
OD_subEntry_t subEntry; OD_stream_t st;
ODR_t ret = OD_getSub(entry, subIndex, &subEntry, &st, odOrig);
OD_IO_t io;
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
if (ret == ODR_OK && st.dataLength != sizeof(val)) ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) subEntry.write(&st, subIndex, &val, sizeof(val), &ret);
if (ret == ODR_OK && io.stream.dataLength != sizeof(val))
ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) io.write(&io.stream, subIndex, &val, sizeof(val), &ret);
return ret;
}
ODR_t OD_set_r64(const OD_entry_t *entry, uint8_t subIndex,
float64_t val, bool_t odOrig)
{
OD_subEntry_t subEntry; OD_stream_t st;
ODR_t ret = OD_getSub(entry, subIndex, &subEntry, &st, odOrig);
OD_IO_t io;
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
if (ret == ODR_OK && st.dataLength != sizeof(val)) ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) subEntry.write(&st, subIndex, &val, sizeof(val), &ret);
if (ret == ODR_OK && io.stream.dataLength != sizeof(val))
ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) io.write(&io.stream, subIndex, &val, sizeof(val), &ret);
return ret;
}
/******************************************************************************/
ODR_t OD_getPtr_i8(const OD_entry_t *entry, uint8_t subIndex, int8_t **val) {
OD_subEntry_t subEntry; OD_stream_t st;
ODR_t ret = OD_getSub(entry, subIndex, &subEntry, &st, true);
OD_IO_t io;
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, true);
if (ret == ODR_OK && st.dataLength != sizeof(**val))ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) *val = (int8_t *)st.dataObjectOriginal;
if (*val == NULL) ret = ODR_DEV_INCOMPAT;
if (val == NULL || io.stream.dataObjectOriginal == NULL)
ret = ODR_DEV_INCOMPAT;
else if (ret == ODR_OK && io.stream.dataLength != sizeof(**val))
ret = ODR_TYPE_MISMATCH;
else if (ret == ODR_OK)
*val = (int8_t *)io.stream.dataObjectOriginal;
return ret;
}
ODR_t OD_getPtr_i16(const OD_entry_t *entry, uint8_t subIndex, int16_t **val) {
OD_subEntry_t subEntry; OD_stream_t st;
ODR_t ret = OD_getSub(entry, subIndex, &subEntry, &st, true);
OD_IO_t io;
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, true);
if (ret == ODR_OK && st.dataLength != sizeof(**val))ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) *val = (int16_t *)st.dataObjectOriginal;
if (*val == NULL) ret = ODR_DEV_INCOMPAT;
if (val == NULL || io.stream.dataObjectOriginal == NULL)
ret = ODR_DEV_INCOMPAT;
else if (ret == ODR_OK && io.stream.dataLength != sizeof(**val))
ret = ODR_TYPE_MISMATCH;
else if (ret == ODR_OK)
*val = (int16_t *)io.stream.dataObjectOriginal;
return ret;
}
ODR_t OD_getPtr_i32(const OD_entry_t *entry, uint8_t subIndex, int32_t **val) {
OD_subEntry_t subEntry; OD_stream_t st;
ODR_t ret = OD_getSub(entry, subIndex, &subEntry, &st, true);
OD_IO_t io;
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, true);
if (ret == ODR_OK && st.dataLength != sizeof(**val))ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) *val = (int32_t *)st.dataObjectOriginal;
if (*val == NULL) ret = ODR_DEV_INCOMPAT;
if (val == NULL || io.stream.dataObjectOriginal == NULL)
ret = ODR_DEV_INCOMPAT;
else if (ret == ODR_OK && io.stream.dataLength != sizeof(**val))
ret = ODR_TYPE_MISMATCH;
else if (ret == ODR_OK)
*val = (int32_t *)io.stream.dataObjectOriginal;
return ret;
}
ODR_t OD_getPtr_i64(const OD_entry_t *entry, uint8_t subIndex, int64_t **val) {
OD_subEntry_t subEntry; OD_stream_t st;
ODR_t ret = OD_getSub(entry, subIndex, &subEntry, &st, true);
OD_IO_t io;
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, true);
if (ret == ODR_OK && st.dataLength != sizeof(**val))ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) *val = (int64_t *)st.dataObjectOriginal;
if (*val == NULL) ret = ODR_DEV_INCOMPAT;
if (val == NULL || io.stream.dataObjectOriginal == NULL)
ret = ODR_DEV_INCOMPAT;
else if (ret == ODR_OK && io.stream.dataLength != sizeof(**val))
ret = ODR_TYPE_MISMATCH;
else if (ret == ODR_OK)
*val = (int64_t *)io.stream.dataObjectOriginal;
return ret;
}
ODR_t OD_getPtr_u8(const OD_entry_t *entry, uint8_t subIndex, uint8_t **val) {
OD_subEntry_t subEntry; OD_stream_t st;
ODR_t ret = OD_getSub(entry, subIndex, &subEntry, &st, true);
OD_IO_t io;
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, true);
if (ret == ODR_OK && st.dataLength != sizeof(**val))ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) *val = (uint8_t *)st.dataObjectOriginal;
if (*val == NULL) ret = ODR_DEV_INCOMPAT;
if (val == NULL || io.stream.dataObjectOriginal == NULL)
ret = ODR_DEV_INCOMPAT;
else if (ret == ODR_OK && io.stream.dataLength != sizeof(**val))
ret = ODR_TYPE_MISMATCH;
else if (ret == ODR_OK)
*val = (uint8_t *)io.stream.dataObjectOriginal;
return ret;
}
ODR_t OD_getPtr_u16(const OD_entry_t *entry, uint8_t subIndex, uint16_t **val) {
OD_subEntry_t subEntry; OD_stream_t st;
ODR_t ret = OD_getSub(entry, subIndex, &subEntry, &st, true);
OD_IO_t io;
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, true);
if (ret == ODR_OK && st.dataLength != sizeof(**val))ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) *val = (uint16_t *)st.dataObjectOriginal;
if (*val == NULL) ret = ODR_DEV_INCOMPAT;
if (val == NULL || io.stream.dataObjectOriginal == NULL)
ret = ODR_DEV_INCOMPAT;
else if (ret == ODR_OK && io.stream.dataLength != sizeof(**val))
ret = ODR_TYPE_MISMATCH;
else if (ret == ODR_OK)
*val = (uint16_t *)io.stream.dataObjectOriginal;
return ret;
}
ODR_t OD_getPtr_u32(const OD_entry_t *entry, uint8_t subIndex, uint32_t **val) {
OD_subEntry_t subEntry; OD_stream_t st;
ODR_t ret = OD_getSub(entry, subIndex, &subEntry, &st, true);
OD_IO_t io;
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, true);
if (ret == ODR_OK && st.dataLength != sizeof(**val))ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) *val = (uint32_t *)st.dataObjectOriginal;
if (*val == NULL) ret = ODR_DEV_INCOMPAT;
if (val == NULL || io.stream.dataObjectOriginal == NULL)
ret = ODR_DEV_INCOMPAT;
else if (ret == ODR_OK && io.stream.dataLength != sizeof(**val))
ret = ODR_TYPE_MISMATCH;
else if (ret == ODR_OK)
*val = (uint32_t *)io.stream.dataObjectOriginal;
return ret;
}
ODR_t OD_getPtr_u64(const OD_entry_t *entry, uint8_t subIndex, uint64_t **val) {
OD_subEntry_t subEntry; OD_stream_t st;
ODR_t ret = OD_getSub(entry, subIndex, &subEntry, &st, true);
OD_IO_t io;
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, true);
if (ret == ODR_OK && st.dataLength != sizeof(**val))ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) *val = (uint64_t *)st.dataObjectOriginal;
if (*val == NULL) ret = ODR_DEV_INCOMPAT;
if (val == NULL || io.stream.dataObjectOriginal == NULL)
ret = ODR_DEV_INCOMPAT;
else if (ret == ODR_OK && io.stream.dataLength != sizeof(**val))
ret = ODR_TYPE_MISMATCH;
else if (ret == ODR_OK)
*val = (uint64_t *)io.stream.dataObjectOriginal;
return ret;
}
ODR_t OD_getPtr_r32(const OD_entry_t *entry, uint8_t subIndex, float32_t **val){
OD_subEntry_t subEntry; OD_stream_t st;
ODR_t ret = OD_getSub(entry, subIndex, &subEntry, &st, true);
OD_IO_t io;
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, true);
if (ret == ODR_OK && st.dataLength != sizeof(**val))ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) *val = (float32_t *)st.dataObjectOriginal;
if (*val == NULL) ret = ODR_DEV_INCOMPAT;
if (val == NULL || io.stream.dataObjectOriginal == NULL)
ret = ODR_DEV_INCOMPAT;
else if (ret == ODR_OK && io.stream.dataLength != sizeof(**val))
ret = ODR_TYPE_MISMATCH;
else if (ret == ODR_OK)
*val = (float32_t *)io.stream.dataObjectOriginal;
return ret;
}
ODR_t OD_getPtr_r64(const OD_entry_t *entry, uint8_t subIndex, float64_t **val){
OD_subEntry_t subEntry; OD_stream_t st;
ODR_t ret = OD_getSub(entry, subIndex, &subEntry, &st, true);
OD_IO_t io;
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, true);
if (ret == ODR_OK && st.dataLength != sizeof(**val))ret = ODR_TYPE_MISMATCH;
if (ret == ODR_OK) *val = (float64_t *)st.dataObjectOriginal;
if (*val == NULL) ret = ODR_DEV_INCOMPAT;
if (val == NULL || io.stream.dataObjectOriginal == NULL)
ret = ODR_DEV_INCOMPAT;
else if (ret == ODR_OK && io.stream.dataLength != sizeof(**val))
ret = ODR_TYPE_MISMATCH;
else if (ret == ODR_OK)
*val = (float64_t *)io.stream.dataObjectOriginal;
return ret;
}
ODR_t OD_getPtr_vs(const OD_entry_t *entry, uint8_t subIndex,
char **val, OD_size_t *dataLength)
{
OD_IO_t io;
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, true);
if (val == NULL || io.stream.dataObjectOriginal == NULL
|| io.stream.dataLength == 0)
{
ret = ODR_DEV_INCOMPAT;
}
else if (ret == ODR_OK) {
*val = (char *)io.stream.dataObjectOriginal;
if (dataLength != NULL) *dataLength = io.stream.dataLength;
}
return ret;
}
ODR_t OD_getPtr_os(const OD_entry_t *entry, uint8_t subIndex,
uint8_t **val, OD_size_t *dataLength)
{
OD_IO_t io;
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, true);
if (val == NULL || io.stream.dataObjectOriginal == NULL
|| io.stream.dataLength == 0)
{
ret = ODR_DEV_INCOMPAT;
}
else if (ret == ODR_OK) {
*val = (uint8_t *)io.stream.dataObjectOriginal;
if (dataLength != NULL) *dataLength = io.stream.dataLength;
}
return ret;
}
ODR_t OD_getPtr_us(const OD_entry_t *entry, uint8_t subIndex,
uint16_t **val, OD_size_t *dataLength)
{
OD_IO_t io;
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, true);
if (val == NULL || io.stream.dataObjectOriginal == NULL
|| io.stream.dataLength == 0)
{
ret = ODR_DEV_INCOMPAT;
}
else if (ret == ODR_OK) {
*val = (uint16_t *)io.stream.dataObjectOriginal;
if (dataLength != NULL) *dataLength = io.stream.dataLength;
}
return ret;
}

View file

@ -190,29 +190,6 @@ typedef enum {
} ODR_t;
/**
* IO stream structure, used for read/write access to OD variable.
*
* Structure is initialized with @ref OD_getSub() function.
*/
typedef struct {
/** 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
* inside read / write functions from IO extension.
*/
void *object;
/** Data length in bytes or 0, if length is not specified */
OD_size_t dataLength;
/** In case of large data, dataOffset indicates position of already
* transferred data */
OD_size_t dataOffset;
} OD_stream_t;
/**
* Structure describing properties of a variable, located in specific index and
* sub-index inside the Object Dictionary.
@ -251,6 +228,39 @@ typedef struct {
* mapped.
*/
OD_flagsPDO_t *flagsPDO;
} OD_subEntry_t;
/**
* IO stream structure, used for read/write access to OD variable, part of
* @ref OD_IO_t.
*/
typedef struct {
/** 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
* inside read / write functions from IO extension.
*/
void *object;
/** Data length in bytes or 0, if length is not specified */
OD_size_t dataLength;
/** In case of large data, dataOffset indicates position of already
* transferred data */
OD_size_t dataOffset;
} OD_stream_t;
/**
* Structure for input / output on the OD variable. It is initialized with
* @ref OD_getSub() function. Access principle to OD variable is via read/write
* functions operating on stream, similar as standard read/write.
*/
typedef struct {
/** Object Dictionary stream object, passed to read or write */
OD_stream_t stream;
/**
* Function pointer for reading value from specified variable from Object
* Dictionary. If OD variable is larger than buf, then this function must
@ -260,21 +270,20 @@ typedef struct {
*
* Read can be restarted with @ref OD_rwRestart() function.
*
* At the moment, when Object Dictionary is initialised, every variable has
* At the moment, when Object Dictionary is initialized, every variable has
* assigned the same "read" function. This default function simply copies
* data from Object Dictionary variable. Application can bind its own "read"
* function for specific object. In that case application is able to
* calculate data for reading from own internal state at the moment of
* "read" function call. For this functionality OD object must have IO
* extension enabled. OD object must also be initialised with
* extension enabled. OD object must also be initialized with
* @ref OD_extensionIO_init() function call.
*
* "read" function must always copy all own data to buf, except if "buf" is
* not large enough. ("*returnCode" must not return 'ODR_PARTIAL', if there
* is still space in "buf".)
*
* @param stream Object Dictionary stream object, returned from
* @ref OD_getSub() function, see @ref OD_stream_t.
* @param stream Object Dictionary stream object.
* @param subIndex Object Dictionary subIndex of the accessed element.
* @param buf Pointer to external buffer, where to data will be copied.
* @param count Size of the external buffer in bytes.
@ -301,8 +310,7 @@ typedef struct {
* "write" function must always copy all available data from buf. If OD
* variable expect more data, then "*returnCode" must return 'ODR_PARTIAL'.
*
* @param stream Object Dictionary stream object, returned from
* @ref OD_getSub() function, see @ref OD_stream_t.
* @param stream Object Dictionary stream object.
* @param subIndex Object Dictionary subIndex of the accessed element.
* @param buf Pointer to external buffer, from where data will be copied.
* @param count Size of the external buffer in bytes.
@ -313,23 +321,6 @@ typedef struct {
*/
OD_size_t (*write)(OD_stream_t *stream, uint8_t subIndex,
const void *buf, OD_size_t count, ODR_t *returnCode);
} OD_subEntry_t;
/**
* Helper structure for storing all objects necessary for frequent read from or
* write to specific OD variable. Structure can be used by application and can
* be filled inside and after @ref OD_getSub() function call.
*/
typedef struct {
/** Object passed to read or write */
OD_stream_t stream;
/** Read function pointer, see @ref OD_subEntry_t */
OD_size_t (*read)(OD_stream_t *stream, uint8_t subIndex,
void *buf, OD_size_t count, ODR_t *returnCode);
/** Write function pointer, see @ref OD_subEntry_t */
OD_size_t (*write)(OD_stream_t *stream, uint8_t subIndex,
const void *buf, OD_size_t count, ODR_t *returnCode);
} OD_IO_t;
@ -370,8 +361,8 @@ typedef struct {
* This function can be used inside read / write functions, specified by
* @ref OD_extensionIO_init(). It reads data directly from memory location
* specified by Object dictionary. If no IO extension is used on OD entry, then
* subEntry->read returned by @ref OD_getSub() equals to this function. See
* also @ref OD_subEntry_t.
* io->read returned by @ref OD_getSub() equals to this function. See
* also @ref OD_IO_t.
*/
OD_size_t OD_readOriginal(OD_stream_t *stream, uint8_t subIndex,
void *buf, OD_size_t count, ODR_t *returnCode);
@ -383,8 +374,8 @@ OD_size_t OD_readOriginal(OD_stream_t *stream, uint8_t subIndex,
* This function can be used inside read / write functions, specified by
* @ref OD_extensionIO_init(). It writes data directly to memory location
* specified by Object dictionary. If no IO extension is used on OD entry, then
* subEntry->write returned by @ref OD_getSub() equals to this function. See
* also @ref OD_subEntry_t.
* io->write returned by @ref OD_getSub() equals to this function. See
* also @ref OD_IO_t.
*/
OD_size_t OD_writeOriginal(OD_stream_t *stream, uint8_t subIndex,
const void *buf, OD_size_t count, ODR_t *returnCode);
@ -403,19 +394,19 @@ const OD_entry_t *OD_find(const OD_t *od, uint16_t index);
/**
* Find sub-object with specified sub-index on OD entry returned by OD_find.
* Function populates subEntry and stream structures with sub-object data.
* Function populates subEntry and io structures with sub-object data.
*
* @param entry OD entry returned by @ref OD_find().
* @param subIndex Sub-index of the variable from the OD object.
* @param [out] subEntry Structure will be populated on success.
* @param [out] stream Structure will be populated on success.
* @param [out] subEntry Structure will be populated on success, may be NULL.
* @param [out] io Structure will be populated on success.
* @param odOrig If true, then potential IO extension on entry will be
* ignored and access to data entry in the original OD location will be returned
*
* @return Value from @ref ODR_t, "ODR_OK" in case of success.
*/
ODR_t OD_getSub(const OD_entry_t *entry, uint8_t subIndex,
OD_subEntry_t *subEntry, OD_stream_t *stream, bool_t odOrig);
OD_subEntry_t *subEntry, OD_IO_t *io, bool_t odOrig);
/**
@ -437,8 +428,7 @@ static inline uint16_t OD_getIndex(const OD_entry_t *entry) {
* @ref OD_getSub(). It is also not necessary to call this function, if prevous
* read or write was successfully finished.
*
* @param stream Object Dictionary stream object, returned from
* @ref OD_getSub() function, see @ref OD_stream_t.
* @param stream Object Dictionary stream object.
*/
static inline void OD_rwRestart(OD_stream_t *stream) {
stream->dataOffset = 0;
@ -482,25 +472,26 @@ uint32_t OD_getSDOabCode(ODR_t returnCode);
* @param object Object, which will be passed to read or write function.
* @param read Read function pointer. If NULL, then read will be disabled.
* @ref OD_readOriginal can be used here to keep original read function.
* For function description see @ref OD_subEntry_t.
* For function description see @ref OD_IO_t.
* @param write Write function pointer. If NULL, then write will be disabled.
* @ref OD_writeOriginal can be used here to keep original write function.
* For function description see @ref OD_subEntry_t.
* For function description see @ref OD_IO_t.
*
* @return true on success, false if OD object doesn't exist or is not extended.
* @return "ODR_OK" on success, "ODR_IDX_NOT_EXIST" if OD object doesn't exist,
* "ODR_PAR_INCOMPAT" if OD object is not extended.
*/
bool_t OD_extensionIO_init(const OD_entry_t *entry,
void *object,
OD_size_t (*read)(OD_stream_t *stream,
ODR_t OD_extensionIO_init(const OD_entry_t *entry,
void *object,
OD_size_t (*read)(OD_stream_t *stream,
uint8_t subIndex,
void *buf,
OD_size_t count,
ODR_t *returnCode),
OD_size_t (*write)(OD_stream_t *stream,
uint8_t subIndex,
void *buf,
const void *buf,
OD_size_t count,
ODR_t *returnCode),
OD_size_t (*write)(OD_stream_t *stream,
uint8_t subIndex,
const void *buf,
OD_size_t count,
ODR_t *returnCode));
ODR_t *returnCode));
/**
@ -630,6 +621,31 @@ ODR_t OD_getPtr_u64(const OD_entry_t *entry, uint8_t subIndex, uint64_t **val);
ODR_t OD_getPtr_r32(const OD_entry_t *entry, uint8_t subIndex, float32_t **val);
/** Get pointer to float64_t variable from OD, see @ref OD_getPtr_i8 */
ODR_t OD_getPtr_r64(const OD_entry_t *entry, uint8_t subIndex, float64_t **val);
/**
* Get pointer to "visible string" variable from Object Dictionary
*
* Function always returns "dataObjectOriginal" pointer, which points to data
* in the original OD location. Take care, if IO extension is enabled on OD
* entry.
*
* @param entry OD entry returned by @ref OD_find().
* @param subIndex Sub-index of the variable from the OD object.
* @param [out] val Pointer to variable will be written here.
* @param [out] dataLength Total variable length will be written here, may be
* NULL.
*
* @return Value from @ref ODR_t, "ODR_OK" in case of success. Error, if
* variable does not exist in object dictionary or it has zero length or other
* reason.
*/
ODR_t OD_getPtr_vs(const OD_entry_t *entry, uint8_t subIndex,
char **val, OD_size_t *dataLength);
/** Get pointer to "octet string" variable from OD, see @ref OD_getPtr_vs */
ODR_t OD_getPtr_os(const OD_entry_t *entry, uint8_t subIndex,
uint8_t **val, OD_size_t *dataLength);
/** Get pointer to "unicode string" variable from OD, see @ref OD_getPtr_vs */
ODR_t OD_getPtr_us(const OD_entry_t *entry, uint8_t subIndex,
uint16_t **val, OD_size_t *dataLength);
/** @} */ /* CO_ODgetSetters */
@ -716,10 +732,10 @@ typedef struct {
typedef struct {
/** Object on which read and write will operate */
void *object;
/** Application specified function pointer, see @ref OD_subEntry_t. */
/** Application specified function pointer, see @ref OD_IO_t. */
OD_size_t (*read)(OD_stream_t *stream, uint8_t subIndex,
void *buf, OD_size_t count, ODR_t *returnCode);
/** Application specified function pointer, see @ref OD_subEntry_t. */
/** Application specified function pointer, see @ref OD_IO_t. */
OD_size_t (*write)(OD_stream_t *stream, uint8_t subIndex,
const void *buf, OD_size_t count, ODR_t *returnCode);
} OD_extensionIO_t;

View file

@ -158,9 +158,9 @@ static void CO_SDOclient_receive(void *object, void *msg) {
#if (CO_CONFIG_SDO_CLI) & CO_CONFIG_FLAG_OD_DYNAMIC
/*
* Custom function for writing OD variable _SDO client parameter_
* Custom function for writing OD object _SDO client parameter_
*
* For more information see file CO_ODinterface.h, OD_subEntry_t.
* For more information see file CO_ODinterface.h, OD_IO_t.
*/
static OD_size_t OD_write_1280(OD_stream_t *stream, uint8_t subIndex,
const void *buf, OD_size_t count,
@ -289,10 +289,11 @@ CO_ReturnError_t CO_SDOclient_init(CO_SDOclient_t *SDO_C,
}
#if (CO_CONFIG_SDO_CLI) & CO_CONFIG_FLAG_OD_DYNAMIC
if (!OD_extensionIO_init(OD_1280_SDOcliPar,
(void *)SDO_C,
OD_readOriginal,
OD_write_1280)) {
ODR_t odRetE = OD_extensionIO_init(OD_1280_SDOcliPar,
(void *)SDO_C,
OD_readOriginal,
OD_write_1280);
if (odRetE != ODR_OK) {
CO_errinfo(CANdevTx, OD_getIndex(OD_1280_SDOcliPar));
return CO_ERROR_OD_PARAMETERS;
}
@ -518,7 +519,7 @@ CO_SDO_return_t CO_SDOclientDownload(CO_SDOclient_t *SDO_C,
OD_subEntry_t subEntry;
odRet = OD_getSub(OD_find(SDO_C->OD, SDO_C->index), SDO_C->subIndex,
&subEntry, &SDO_C->OD_IO.stream, false);
&subEntry, &SDO_C->OD_IO, false);
if (odRet != ODR_OK) {
abortCode = (CO_SDO_abortCode_t)OD_getSDOabCode(odRet);
@ -528,13 +529,10 @@ CO_SDO_return_t CO_SDOclientDownload(CO_SDOclient_t *SDO_C,
abortCode = CO_SDO_AB_READONLY;
ret = CO_SDO_RT_endedWithClientAbort;
}
else if (subEntry.write == NULL) {
else if (SDO_C->OD_IO.write == NULL) {
abortCode = CO_SDO_AB_DEVICE_INCOMPAT;
ret = CO_SDO_RT_endedWithClientAbort;
}
else {
SDO_C->OD_IO.write = subEntry.write;
}
}
/* write data, in several passes if necessary */
if (SDO_C->OD_IO.write != NULL) {
@ -1099,7 +1097,7 @@ CO_SDO_return_t CO_SDOclientUpload(CO_SDOclient_t *SDO_C,
OD_subEntry_t subEntry;
odRet = OD_getSub(OD_find(SDO_C->OD, SDO_C->index), SDO_C->subIndex,
&subEntry, &SDO_C->OD_IO.stream, false);
&subEntry, &SDO_C->OD_IO, false);
if (odRet != ODR_OK) {
abortCode = (CO_SDO_abortCode_t)OD_getSDOabCode(odRet);
@ -1109,13 +1107,10 @@ CO_SDO_return_t CO_SDOclientUpload(CO_SDOclient_t *SDO_C,
abortCode = CO_SDO_AB_WRITEONLY;
ret = CO_SDO_RT_endedWithClientAbort;
}
else if (subEntry.read == NULL) {
else if (SDO_C->OD_IO.read == NULL) {
abortCode = CO_SDO_AB_DEVICE_INCOMPAT;
ret = CO_SDO_RT_endedWithClientAbort;
}
else {
SDO_C->OD_IO.read = subEntry.read;
}
}
size_t countFifo = CO_fifo_getSpace(&SDO_C->bufFifo);

View file

@ -154,7 +154,7 @@ static void CO_SDO_receive(void *object, void *msg) {
* Custom function for reading OD variable _SDO server parameter_, default
* channel
*
* For more information see file CO_ODinterface.h, OD_subEntry_t.
* For more information see file CO_ODinterface.h, OD_IO_t.
*/
static OD_size_t OD_read_1200_default(OD_stream_t *stream, uint8_t subIndex,
void *buf, OD_size_t count,
@ -254,10 +254,10 @@ static CO_ReturnError_t CO_SDOserver_init_canRxTx(CO_SDOserver_t *SDO,
#if (CO_CONFIG_SDO_SRV) & CO_CONFIG_FLAG_OD_DYNAMIC
/*
* Custom function for writing OD variable _SDO server parameter_, additional
* Custom function for writing OD object _SDO server parameter_, additional
* channels
*
* For more information see file CO_ODinterface.h, OD_subEntry_t.
* For more information see file CO_ODinterface.h, OD_IO_t.
*/
static OD_size_t OD_write_1201_additional(OD_stream_t *stream, uint8_t subIndex,
const void *buf, OD_size_t count,
@ -385,11 +385,11 @@ CO_ReturnError_t CO_SDOserver_init(CO_SDOserver_t *SDO,
CanId_ClientToServer = CO_CAN_ID_SDO_CLI + nodeId;
CanId_ServerToClient = CO_CAN_ID_SDO_SRV + nodeId;
SDO->valid = true;
if (!OD_extensionIO_init(OD_1200_SDOsrvPar,
(void *) SDO,
OD_read_1200_default,
NULL)
) {
ODR_t odRetE = OD_extensionIO_init(OD_1200_SDOsrvPar,
(void *) SDO,
OD_read_1200_default,
NULL);
if (odRetE != ODR_OK) {
CO_errinfo(CANdevTx, OD_getIndex(OD_1200_SDOsrvPar));
return CO_ERROR_OD_PARAMETERS;
}
@ -422,11 +422,11 @@ CO_ReturnError_t CO_SDOserver_init(CO_SDOserver_t *SDO,
? (uint16_t)(COB_IDServerToClient32 & 0x7FF) : 0;
#if (CO_CONFIG_SDO_SRV) & CO_CONFIG_FLAG_OD_DYNAMIC
if (!OD_extensionIO_init(OD_1200_SDOsrvPar,
(void *) SDO,
OD_readOriginal,
OD_write_1201_additional)
) {
ODR_t odRetE = OD_extensionIO_init(OD_1200_SDOsrvPar,
(void *) SDO,
OD_readOriginal,
OD_write_1201_additional);
if (odRetE != ODR_OK) {
CO_errinfo(CANdevTx, OD_getIndex(OD_1200_SDOsrvPar));
return CO_ERROR_OD_PARAMETERS;
}
@ -548,15 +548,13 @@ CO_SDO_return_t CO_SDOserver_process(CO_SDOserver_t *SDO,
| SDO->CANrxData[1];
SDO->subIndex = SDO->CANrxData[3];
odRet = OD_getSub(OD_find(SDO->OD, SDO->index), SDO->subIndex,
&subEntry, &SDO->OD_IO.stream, false);
&subEntry, &SDO->OD_IO, false);
if (odRet != ODR_OK) {
abortCode = (CO_SDO_abortCode_t)OD_getSDOabCode(odRet);
SDO->state = CO_SDO_ST_ABORT;
}
else {
SDO->attribute = subEntry.attribute;
SDO->OD_IO.read = subEntry.read;
SDO->OD_IO.write = subEntry.write;
/* verify read/write attributes */
if (upload && (SDO->attribute & ODA_SDO_R) == 0) {

View file

@ -43,8 +43,7 @@ void myFunc(const OD_t *od) {
/* Init IO for "Manufacturer device name" at index 0x1008, sub-index 0x00 */
entry = OD_find(od, 0x1008);
ret = OD_getSub(entry, 0x00, &subEntry, &io1008.stream, false);
io1008.read = subEntry.read;
ret = OD_getSub(entry, 0x00, &subEntry, &io1008, false);
/* Read with io1008, subindex = 0x00 */
if (ret == ODR_OK)
bytesRd = io1008.read(&io1008.stream, 0x00, &buf[0], sizeof(buf), &ret);