From a6f45c308f2f7fddf1ea509fb5ac79d34eef8784 Mon Sep 17 00:00:00 2001 From: Lars Danielsson Date: Wed, 23 Sep 2020 13:01:00 +0200 Subject: [PATCH 1/2] Allow Download Complete Access data size to be less than full size Change-Id: Ie27c54547c88d89bc1a8c99afc875ea1276a6d85 --- soes/esc_coe.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/soes/esc_coe.c b/soes/esc_coe.c index a1440ec..a3c4d01 100644 --- a/soes/esc_coe.c +++ b/soes/esc_coe.c @@ -455,7 +455,8 @@ static uint32_t complete_access_subindex_loop(const _objd *objd, int16_t nidx, int16_t nsub, uint8_t *mbxdata, - load_t load_type) + load_t load_type, + uint16_t max_bytes) { /* Objects with dynamic entries cannot be accessed with Complete Access */ if ((objd->datatype == DTYPE_VISIBLE_STRING) || @@ -525,6 +526,11 @@ static uint32_t complete_access_subindex_loop(const _objd *objd, /* Subindex 0 is padded to 16 bit */ size += (nsub == 0) ? 16 : bitlen; nsub++; + + if ((max_bytes > 0) && (BITS2BYTES(size) >= max_bytes)) + { + break; + } } return size; @@ -576,7 +582,7 @@ static void SDO_upload_complete_access (void) const _objd *objd = SDOobjects[nidx].objdesc; /* loop through the subindexes to get the total size */ - uint32_t size = complete_access_subindex_loop(objd, nidx, nsub, NULL, UPLOAD); + uint32_t size = complete_access_subindex_loop(objd, nidx, nsub, NULL, UPLOAD, 0); if (size > 0xffff) { /* 'size' is in this case actually an abort code */ @@ -599,7 +605,7 @@ static void SDO_upload_complete_access (void) } /* copy subindex data into the preallocated buffer */ - complete_access_subindex_loop(objd, nidx, nsub, ESCvar.mbxdata, UPLOAD); + complete_access_subindex_loop(objd, nidx, nsub, ESCvar.mbxdata, UPLOAD, 0); _COEsdo *coeres = (_COEsdo *) &MBX[MBXout * ESC_MBXSIZE]; init_coesdo(coeres, COE_SDORESPONSE, @@ -900,14 +906,20 @@ static void SDO_download_complete_access (void) const _objd *objd = SDOobjects[nidx].objdesc; /* loop through the subindexes to get the total size */ - uint32_t size = complete_access_subindex_loop(objd, nidx, nsub, NULL, DOWNLOAD); + uint32_t size = complete_access_subindex_loop(objd, nidx, nsub, NULL, DOWNLOAD, 0); if (size > 0xffff) { /* 'size' is in this case actually an abort code */ set_state_idle (index, subindex, size); return; } - else if (bytes == BITS2BYTES(size)) + /* The document ETG.1020 S (R) V1.3.0, chapter 12.2, states that + * "The SDO Download Complete Access data length shall always match + * the full current object size (defined by SubIndex0)". + * But EtherCAT Conformance Test Tool doesn't follow this rule for some test + * cases, which is the reason to here only check for 'less than or equal'. + */ + else if (bytes <= BITS2BYTES(size)) { abortcode = ESC_download_pre_objecthandler(index, subindex, mbxdata, size, objd->flags | COMPLETE_ACCESS_FLAG); @@ -918,7 +930,7 @@ static void SDO_download_complete_access (void) } /* copy download data to subindexes */ - complete_access_subindex_loop(objd, nidx, nsub, (uint8_t *)mbxdata, DOWNLOAD); + complete_access_subindex_loop(objd, nidx, nsub, (uint8_t *)mbxdata, DOWNLOAD, bytes); abortcode = ESC_download_post_objecthandler(index, subindex, objd->flags | COMPLETE_ACCESS_FLAG); @@ -930,16 +942,8 @@ static void SDO_download_complete_access (void) } else { -#if 0 - /* The document ETG.1020 S (R) V1.3.0, chapter 12.2, states that - * "The SDO Download Complete Access data length shall always match - * the full current object size (defined by SubIndex0)". - * But EtherCAT Conformance Test Tool doesn't follow this rule for some - * test cases, which thus will fail if the correct abort code is used :( - */ set_state_idle (index, subindex, ABORT_TYPEMISMATCH); return; -#endif } uint8_t MBXout = ESC_claimbuffer (); From 74d710b8b78e9555227e1f15346afb6cc0c80297 Mon Sep 17 00:00:00 2001 From: Lars Danielsson Date: Wed, 23 Sep 2020 13:24:11 +0200 Subject: [PATCH 2/2] Add more data types which may have flexible length Change-Id: Ia78d89adfb4017e970ace7fdf0b1bccffc8ac357 --- soes/esc_coe.c | 9 +++++++-- soes/esc_coe.h | 4 ++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/soes/esc_coe.c b/soes/esc_coe.c index a3c4d01..58fe954 100644 --- a/soes/esc_coe.c +++ b/soes/esc_coe.c @@ -776,7 +776,8 @@ static void SDO_download (void) if (actsize != size) { /* entries with data types VISIBLE_STRING, OCTET_STRING, - * and UNICODE_STRING may have flexible length + * UNICODE_STRING, ARRAY_OF_INT, ARRAY_OF_SINT, + * ARRAY_OF_DINT, and ARRAY_OF_UDINT may have flexible length */ uint16_t type = (objd + nsub)->datatype; if (type == DTYPE_VISIBLE_STRING) @@ -785,7 +786,11 @@ static void SDO_download (void) memset((objd + nsub)->data + size, 0, actsize - size); } else if ((type != DTYPE_OCTET_STRING) && - (type != DTYPE_UNICODE_STRING)) + (type != DTYPE_UNICODE_STRING) && + (type != DTYPE_ARRAY_OF_INT) && + (type != DTYPE_ARRAY_OF_SINT) && + (type != DTYPE_ARRAY_OF_DINT) && + (type != DTYPE_ARRAY_OF_UDINT)) { set_state_idle (index, subindex, ABORT_TYPEMISMATCH); return; diff --git a/soes/esc_coe.h b/soes/esc_coe.h index 4d3af27..689750c 100644 --- a/soes/esc_coe.h +++ b/soes/esc_coe.h @@ -83,6 +83,10 @@ typedef struct #define DTYPE_BIT6 0x0035 #define DTYPE_BIT7 0x0036 #define DTYPE_BIT8 0x0037 +#define DTYPE_ARRAY_OF_INT 0x0260 +#define DTYPE_ARRAY_OF_SINT 0x0261 +#define DTYPE_ARRAY_OF_DINT 0x0262 +#define DTYPE_ARRAY_OF_UDINT 0x0263 #define ATYPE_Rpre 0x01 #define ATYPE_Rsafe 0x02