Skip to content

Commit

Permalink
Merge pull request #57 from embedded-office/feature/user-abort-codes
Browse files Browse the repository at this point in the history
Introduce user defined SDO abort codes in type functions (fix #56)
  • Loading branch information
michael-hillmann authored Jul 28, 2021
2 parents 33f3325 + 55d7013 commit 09090ec
Show file tree
Hide file tree
Showing 27 changed files with 648 additions and 235 deletions.
12 changes: 10 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,14 @@ and starting with version 4.1.0 this project adheres to [Semantic Versioning](ht

## [unreleased]

- none
none

## [4.1.7] - 2012-07-28

### Added

- Introduce COObjTypeUserSDOAbort() to define amnufacturer specific SDO Abort codes within type functions
- Add CMake toolchain files for ARM-GCC Cortex-M3, M4 and M7

## [4.1.6] - 2012-07-21

Expand Down Expand Up @@ -131,7 +138,8 @@ and starting with version 4.1.0 this project adheres to [Semantic Versioning](ht
- First Open Source Release.


[unreleased]: https://github.com/embedded-office/canopen-stack/compare/v4.1.6...HEAD
[unreleased]: https://github.com/embedded-office/canopen-stack/compare/v4.1.7...HEAD
[4.1.7]: https://github.com/embedded-office/canopen-stack/compare/v4.1.6...v4.1.7
[4.1.6]: https://github.com/embedded-office/canopen-stack/compare/v4.1.5...v4.1.6
[4.1.5]: https://github.com/embedded-office/canopen-stack/compare/v4.1.4...v4.1.5
[4.1.4]: https://github.com/embedded-office/canopen-stack/compare/v4.1.3...v4.1.4
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
cmake_minimum_required (VERSION 3.15)
project (CanopenStack VERSION 4.1.6)
project (CanopenStack VERSION 4.1.7)

# Make CANopen library
add_subdirectory(canopen)
Expand Down
20 changes: 1 addition & 19 deletions canopen/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ target_sources(Canopen
source/co_if_nvm.c
source/co_if_timer.c
source/co_if.c
source/co_lss.c
source/co_lss.c
source/co_nmt.c
source/co_obj.c
source/co_para.c
Expand All @@ -36,21 +36,3 @@ target_sources(Canopen
source/co_tmr.c
source/co_ver.c
)

#---
# enable warnings and tread as errors
#
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# tread all files as C files
target_compile_options(Canopen PRIVATE /TC)
endif()
# enable all warnings
target_compile_options(Canopen PRIVATE -Wall
-Wextra
-Wpedantic
-Werror)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
target_compile_options(Canopen PRIVATE /W4
/WX)
endif()
19 changes: 19 additions & 0 deletions canopen/include/co_obj.h
Original file line number Diff line number Diff line change
Expand Up @@ -852,6 +852,25 @@ CO_ERR COObjRdType(CO_OBJ *obj, struct CO_NODE_T *node, void *dst, uint32_t len,
*/
CO_ERR COObjWrType(CO_OBJ *obj, struct CO_NODE_T *node, void *src, uint32_t len, uint32_t off);

/*! \brief TYPE SPECIFIC SDO ABORT CODE
*
* This function is responsible to set a user defined SDO abort code
* for the current transfer of an SDO server. This function is useful,
* when detecting an error within a type read od write function during
* an SDO transfer. If no SDO transfer is active, this function will
* do nothing.
*
* \param obj
* String object entry reference
*
* \param node
* reference to parent node
*
* \param abort
* Requested abort code (or 0 for standardized abort code)
*/
void COObjTypeUserSDOAbort(CO_OBJ *obj, struct CO_NODE_T *node, uint32_t abort);

/*! \brief STRING OBJECT SIZE
*
* This function is responsible to calculate and return the size of the
Expand Down
1 change: 1 addition & 0 deletions canopen/include/co_sdo_srv.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ typedef struct CO_SDO_T {
CO_IF_FRM *Frm; /*!< SDO request/response CAN frame */
uint32_t RxId; /*!< SDO request CAN identifier */
uint32_t TxId; /*!< SDO response CAN identifier */
uint32_t Abort; /*!< SDO abort code overwrite, when >0 */
uint16_t Idx; /*!< Extracted Multiplexer Index */
uint8_t Sub; /*!< Extracted Multiplexer Subindex */
struct CO_SDO_BUF_T Buf; /*!< Transfer buffer management structure */
Expand Down
2 changes: 1 addition & 1 deletion canopen/include/co_ver.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

#define CO_VER_MAJOR 4
#define CO_VER_MINOR 1
#define CO_VER_BUILD 6
#define CO_VER_BUILD 7

/******************************************************************************
* PUBLIC FUNCTIONS
Expand Down
15 changes: 15 additions & 0 deletions canopen/source/co_obj.c
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,21 @@ CO_ERR COObjWrType(CO_OBJ *obj, CO_NODE *node, void *src, uint32_t len, uint32_t
return (result);
}

/*
* see function definition
*/
void COObjTypeUserSDOAbort(CO_OBJ *obj, struct CO_NODE_T *node, uint32_t abort)
{
uint8_t n;

for (n = 0; n < CO_SDOS_N; n++) {
if (node->Sdo[n].Obj == obj) {
node->Sdo[n].Abort = abort;
break;
}
}
}

/*
* see function definition
*/
Expand Down
13 changes: 10 additions & 3 deletions canopen/source/co_sdo_srv.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ CO_SDO *COSdoCheck(CO_SDO *srv, CO_IF_FRM *frm)
while ((n < CO_SDOS_N) && (result == 0)) {
if (CO_GET_ID(frm) == srv[n].RxId) {
CO_SET_ID(frm, srv[n].TxId);
srv[n].Frm = frm;
srv[n].Frm = frm;
srv[n].Abort = 0;
if (srv[n].Obj == 0) {
srv[n].Idx = CO_GET_WORD(frm, 1);
srv[n].Sub = CO_GET_BYTE(frm, 3);
Expand Down Expand Up @@ -318,7 +319,11 @@ CO_ERR COSdoUploadExpedited(CO_SDO *srv)
nodeid = srv->Node->NodeId;
err = COObjRdValue(srv->Obj, srv->Node, (void *)&data, CO_LONG, nodeid);
if (err != CO_ERR_NONE) {
COSdoAbort(srv, CO_SDO_ERR_TOS);
if (srv->Abort > 0) {
COSdoAbort(srv, srv->Abort);
} else {
COSdoAbort(srv, CO_SDO_ERR_TOS);
}
return (result);
} else {
cmd = (uint8_t)0x43u | (uint8_t)(((4u - size) & 0x3u) << 2u);
Expand Down Expand Up @@ -363,7 +368,9 @@ CO_ERR COSdoDownloadExpedited(CO_SDO *srv)
data = CO_GET_LONG(srv->Frm, 4);
err = COObjWrValue(srv->Obj, srv->Node, (void*)&data, CO_LONG, nodeid);
if (err != CO_ERR_NONE) {
if (err == CO_ERR_OBJ_RANGE) {
if (srv->Abort > 0) {
COSdoAbort(srv, srv->Abort);
} else if (err == CO_ERR_OBJ_RANGE) {
COSdoAbort(srv, CO_SDO_ERR_RANGE);
} else if (err == CO_ERR_OBJ_MAP_TYPE) {
COSdoAbort(srv, CO_SDO_ERR_OBJ_MAP);
Expand Down
1 change: 1 addition & 0 deletions docs/docs/api/object/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ The object component provides an interface to the individual object entries.
+COObjWrBufCont(source, length) int16_t
+COObjWrBufStart(source, length) int16_t
+COObjWrValue(source, width, nodeId) int16_t
+COObjTypeUserSDOAbort(node, code) void
}
```

Expand Down
25 changes: 20 additions & 5 deletions docs/docs/usecase/dictionary.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,16 +200,16 @@ If a new user type didn't need to have special behavior on accessing (e.g. get-s
The following list shows the type function prototypes. The return value of the size type function (e.g. `DemoSize()`) shall return the size of the user type in bytes. The other type functions shall return `CO_ERR_NONE` after the successful operation. If an error is detected the corresponding error codes must be returned: `CO_ERR_TYPE_RD`, `CO_ERR_TYPE_WR` or `CO_ERR_TYPE_CTRL`.
```c
uint32_t DemoSize (CO_OBJ *obj, uint32_t width);
CO_ERR DemoRead (CO_OBJ *obj, void *buf, uint32_t len);
CO_ERR DemoWrite(CO_OBJ *obj, void *buf, uint32_t len);
CO_ERR DemoCtrl (CO_OBJ *obj, uint16_t id, uint32_t para);
uint32_t DemoSize (CO_OBJ *obj, CO_NODE *node, uint32_t width);
CO_ERR DemoRead (CO_OBJ *obj, CO_NODE *node, void *buf, uint32_t len);
CO_ERR DemoWrite(CO_OBJ *obj, CO_NODE *node, void *buf, uint32_t len);
CO_ERR DemoCtrl (CO_OBJ *obj, CO_NODE *node, uint16_t id, uint32_t para);
```

**Note:** The parameter `len` in the functions `DemoRead()` and `DemoWrite()` is the length of the data, given via the pointer `buf`. If you want to use the width of the object entry, you can use the following snippet:

```c
CO_ERR DemoRead(CO_OBJ *obj, void *buf, uint32_t len)
CO_ERR DemoRead(CO_OBJ *obj, CO_NODE *node, void *buf, uint32_t len)
{
uint32_t width = CO_GET_SIZE(obj->Key);

Expand Down Expand Up @@ -254,3 +254,18 @@ sequenceDiagram
O-->>-D: value
D-->>-A: value
```

When you need to control the ABORT codes of SDO expedited transfers, you can use the function `COObjTypeUserSDOAbort()` to set a user defined SDO abort code within your type functions:

```c
CO_ERR DemoWrite(CO_OBJ *obj, CO_NODE *node, void *buf, uint32_t len)
{
:
if (/* your write error condition */) {
/* the given abort code is considered in SDO transfers only! */
COObjTypeUserSDOAbort(obj, node, 0x12345678);
return CO_ERR_TYPE_WR;
}
:
}
```
10 changes: 8 additions & 2 deletions driver/source/co_can_dummy.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
* INCLUDES
******************************************************************************/

/* TODO: rename the include file name to match the naming convention:
/* TODO: rename the include file name to match the naming convention:
* co_can_<device>.h
*/
#include "co_can_dummy.h"
Expand All @@ -44,7 +44,7 @@ static void DrvCanClose (void);
* PUBLIC VARIABLE
******************************************************************************/

/* TODO: rename the variable to match the naming convention:
/* TODO: rename the variable to match the naming convention:
* <device>CanDriver
*/
const CO_IF_CAN_DRV DummyCanDriver = {
Expand All @@ -67,17 +67,23 @@ static void DrvCanInit(void)

static void DrvCanEnable(uint32_t baudrate)
{
(void)baudrate;

/* TODO: set the given baudrate to the CAN controller */
}

static int16_t DrvCanSend(CO_IF_FRM *frm)
{
(void)frm;

/* TODO: wait for free CAN message slot and send the given CAN frame */
return (0u);
}

static int16_t DrvCanRead (CO_IF_FRM *frm)
{
(void)frm;

/* TODO: wait for a CAN frame and read CAN frame from the CAN controller */
return (0u);
}
Expand Down
12 changes: 10 additions & 2 deletions driver/source/co_nvm_dummy.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
* INCLUDES
******************************************************************************/

/* TODO: rename the include file name to match the naming convention:
/* TODO: rename the include file name to match the naming convention:
* co_nvm_<device>.h
*/
#include "co_nvm_dummy.h"
Expand All @@ -42,7 +42,7 @@ static uint32_t DrvNvmWrite (uint32_t start, uint8_t *buffer, uint32_t size);
* PUBLIC VARIABLE
******************************************************************************/

/* TODO: rename the variable to match the naming convention:
/* TODO: rename the variable to match the naming convention:
* <device>NvmDriver
*/
const CO_IF_NVM_DRV DummyNvmDriver = {
Expand All @@ -62,12 +62,20 @@ static void DrvNvmInit(void)

static uint32_t DrvNvmRead(uint32_t start, uint8_t *buffer, uint32_t size)
{
(void)start;
(void)buffer;
(void)size;

/* TODO: read a memory block from non-volatile memory into given buffer */
return (0u);
}

static uint32_t DrvNvmWrite(uint32_t start, uint8_t *buffer, uint32_t size)
{
(void)start;
(void)buffer;
(void)size;

/* TODO: write content of given buffer into non-volatile memory */
return (0u);
}
8 changes: 6 additions & 2 deletions driver/source/co_timer_dummy.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
* INCLUDES
******************************************************************************/

/* TODO: rename the include file name to match the naming convention:
/* TODO: rename the include file name to match the naming convention:
* co_timer_<device>.h
*/
#include "co_timer_dummy.h"
Expand All @@ -44,7 +44,7 @@ static void DrvTimerStop (void);
* PUBLIC VARIABLE
******************************************************************************/

/* TODO: rename the variable to match the naming convention:
/* TODO: rename the variable to match the naming convention:
* <device>TimerDriver
*/
const CO_IF_TIMER_DRV DummyTimerDriver = {
Expand All @@ -62,6 +62,8 @@ const CO_IF_TIMER_DRV DummyTimerDriver = {

static void DrvTimerInit(uint32_t freq)
{
(void)freq;

/* TODO: initialize timer, clear counter and keep timer stopped */
}

Expand All @@ -84,6 +86,8 @@ static uint32_t DrvTimerDelay(void)

static void DrvTimerReload(uint32_t reload)
{
(void)reload;

/* TODO: reload timer counter value with given reload value */
}

Expand Down
18 changes: 0 additions & 18 deletions example/dynamic-od/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,3 @@ target_include_directories(DynamicOD
# specify the dependencies for this application
#
target_link_libraries(DynamicOD Canopen CanopenDriver)

#---
# enable warnings and tread as errors
#
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# tread all files as C files
target_compile_options(Quickstart PRIVATE /TC)
endif()
# enable all warnings
target_compile_options(Quickstart PRIVATE -Wall
-Wextra
-Wpedantic
-Werror)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
target_compile_options(Quickstart PRIVATE /W4
/WX)
endif()
18 changes: 0 additions & 18 deletions example/quickstart/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,3 @@ target_include_directories(Quickstart
# specify the dependencies for this application
#
target_link_libraries(Quickstart Canopen CanopenDriver)

#---
# enable warnings and tread as errors
#
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# tread all files as C files
target_compile_options(Quickstart PRIVATE /TC)
endif()
# enable all warnings
target_compile_options(Quickstart PRIVATE -Wall
-Wextra
-Wpedantic
-Werror)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
target_compile_options(Quickstart PRIVATE /W4
/WX)
endif()
18 changes: 0 additions & 18 deletions testsuite/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -75,21 +75,3 @@ target_include_directories(CanopenTest
# specify the dependencies for this application
#
target_link_libraries(CanopenTest Canopen CanopenDriver)

#---
# enable warnings and tread as errors
#
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# tread all files as C files
target_compile_options(CanopenTest PRIVATE /TC)
endif()
# enable all warnings
# target_compile_options(CanopenTest PRIVATE -Wall
# -Wextra
# -Wpedantic
# -Werror)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
target_compile_options(CanopenTest PRIVATE /W4
/WX)
endif()
Loading

0 comments on commit 09090ec

Please sign in to comment.