From 495f827d376fd44dc64693081556baf42e24d5fd Mon Sep 17 00:00:00 2001 From: Freddie Chopin Date: Wed, 6 May 2020 18:00:28 +0200 Subject: [PATCH 1/3] Fix minor typo/edit mistakes in CHANGELOG.md and CO_config.h --- 301/CO_config.h | 4 ++-- doc/CHANGELOG.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/301/CO_config.h b/301/CO_config.h index d00acc6..60362af 100644 --- a/301/CO_config.h +++ b/301/CO_config.h @@ -90,9 +90,9 @@ extern "C" { * Possible flags, can be ORed: * - #CO_CONFIG_FLAG_CALLBACK_PRE - Enable custom callback after preprocessing * received NMT CAN message. + * Callback is configured by CO_NMT_initCallbackPre(). * - #CO_CONFIG_FLAG_TIMERNEXT - Enable calculation of timerNext_us variable * inside CO_NMT_process(). - * Callback is configured by CO_NMT_initCallbackPre(). * - CO_CONFIG_NMT_CALLBACK_CHANGE - Enable custom callback after NMT * state changes. Callback is configured by * CO_NMT_initCallbackChanged(). @@ -114,9 +114,9 @@ extern "C" { * Possible flags, can be ORed: * - #CO_CONFIG_FLAG_CALLBACK_PRE - Enable custom callback after preprocessing * received SDO CAN message. + * Callback is configured by CO_SDO_initCallbackPre(). * - #CO_CONFIG_FLAG_TIMERNEXT - Enable calculation of timerNext_us variable * inside CO_SDO_process(). - * Callback is configured by CO_SDO_initCallbackPre(). * - CO_CONFIG_SDO_SEGMENTED - Enable SDO server segmented transfer. * - CO_CONFIG_SDO_BLOCK - Enable SDO server block transfer. If set, then * CO_CONFIG_SDO_SEGMENTED must also be set. diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 0ae2cdd..f564f77 100644 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -9,7 +9,7 @@ Change Log - All drivers removed from this project, except Neuberger-socketCAN for Linux. ### Changed - Directory structure rearranged. Before was all CANopen object files in `stack` directory, now they are in separate directories according to standard (`301`, `305`, `extra`, `socketCAN` for Linux driver). Include directives for that files now contain directory path. `CO_SDO` renamed to `CO_SDOserver` and `CO_SDOmaster` renamed to `CO_SDOclient`. Change of the project files will be necessary. -- Driver interface clarified. Before was pair of CO_driver.h/.c files for each microcontroller, now there is common CO_driver.h file. Drivers for other microcontrollers will be separate projects. Each driver must have own CO_driver_target.h file and function definitions from C_driver.h file. See documentation in CO_driver.h, example/CO_driver_target.h and example/CO_driver.c. There was no other mayor changes in driver interface. +- Driver interface clarified. Before was pair of CO_driver.h/.c files for each microcontroller, now there is common CO_driver.h file. Drivers for other microcontrollers will be separate projects. Each driver must have own CO_driver_target.h file and function definitions from C_driver.h file. See documentation in CO_driver.h, example/CO_driver_target.h and example/CO_driver.c. There was no other major changes in driver interface. - Time base is now microsecond in all functions. - CANopen.h/.c files simplified and changed. `CO_USE_GLOBALS` and `CO_init()` removed. Interface to those functions changed. - `CO_NMT_sendCommand()` master function renamed and moved from CANopen.c into CO_NMT_Heartbeat.c. From 9b8a296fb7e05c520679ad98bc05ac1f36f80e8b Mon Sep 17 00:00:00 2001 From: Freddie Chopin Date: Wed, 6 May 2020 18:08:45 +0200 Subject: [PATCH 2/3] Add CO_TIME_initCallbackPre() for received TIME messages This optional mechanism allows to immediatelly wake the thread that processes TIME, without waiting for its next tick. --- 301/CO_TIME.c | 27 ++++++++++++++++++++++++++- 301/CO_TIME.h | 24 ++++++++++++++++++++++++ 301/CO_config.h | 12 ++++++++++++ example/CO_driver_target.h | 4 ++++ socketCAN/CO_driver_target.h | 4 ++++ 5 files changed, 70 insertions(+), 1 deletion(-) diff --git a/301/CO_TIME.c b/301/CO_TIME.c index 838e2b4..026f177 100644 --- a/301/CO_TIME.c +++ b/301/CO_TIME.c @@ -46,11 +46,17 @@ static void CO_TIME_receive(void *object, void *msg){ TIME = (CO_TIME_t*)object; /* this is the correct pointer type of the first argument */ operState = *TIME->operatingState; - if((operState == CO_NMT_OPERATIONAL) || (operState == CO_NMT_PRE_OPERATIONAL)){ // Process Time from msg buffer memcpy(&TIME->Time.ullValue, data, DLC); CO_FLAG_SET(TIME->CANrxNew); + +#if (CO_CONFIG_TIME) & CO_CONFIG_FLAG_CALLBACK_PRE + /* Optional signal to RTOS, which can resume task, which handles TIME. */ + if(TIME->pFunctSignalPre != NULL) { + TIME->pFunctSignalPre(TIME->functSignalObjectPre); + } +#endif } else{ TIME->receiveError = (uint16_t)DLC; @@ -96,6 +102,11 @@ CO_ReturnError_t CO_TIME_init( TIME->em = em; TIME->operatingState = operatingState; +#if (CO_CONFIG_TIME) & CO_CONFIG_FLAG_CALLBACK_PRE + TIME->pFunctSignalPre = NULL; + TIME->functSignalObjectPre = NULL; +#endif + /* configure TIME consumer message reception */ TIME->CANdevRx = CANdevRx; @@ -131,6 +142,20 @@ CO_ReturnError_t CO_TIME_init( return ret; } +#if (CO_CONFIG_TIME) & CO_CONFIG_FLAG_CALLBACK_PRE +/******************************************************************************/ +void CO_TIME_initCallbackPre( + CO_TIME_t *TIME, + void *object, + void (*pFunctSignalPre)(void *object)) +{ + if(TIME != NULL){ + TIME->functSignalObjectPre = object; + TIME->pFunctSignalPre = pFunctSignalPre; + } +} +#endif + /******************************************************************************/ uint8_t CO_TIME_process( CO_TIME_t *TIME, diff --git a/301/CO_TIME.h b/301/CO_TIME.h index 8c6d542..89a972d 100644 --- a/301/CO_TIME.h +++ b/301/CO_TIME.h @@ -99,6 +99,12 @@ typedef struct{ uint32_t timer; /** Set to nonzero value, if TIME with wrong data length is received from CAN */ uint16_t receiveError; +#if ((CO_CONFIG_TIME) & CO_CONFIG_FLAG_CALLBACK_PRE) || defined CO_DOXYGEN + /** From CO_TIME_initCallbackPre() or NULL */ + void (*pFunctSignalPre)(void *object); + /** From CO_TIME_initCallbackPre() or NULL */ + void *functSignalObjectPre; +#endif CO_CANmodule_t *CANdevRx; /**< From CO_TIME_init() */ uint16_t CANdevRxIdx; /**< From CO_TIME_init() */ CO_CANmodule_t *CANdevTx; /**< From CO_TIME_init() */ @@ -137,6 +143,24 @@ CO_ReturnError_t CO_TIME_init( CO_CANmodule_t *CANdevTx, uint16_t CANdevTxIdx); +#if ((CO_CONFIG_TIME) & CO_CONFIG_FLAG_CALLBACK_PRE) || defined CO_DOXYGEN +/** + * Initialize TIME callback function. + * + * Function initializes optional callback function, which should immediately + * start processing of CO_TIME_process() function. + * Callback is called after TIME message is received from the CAN bus. + * + * @param TIME This object. + * @param object Pointer to object, which will be passed to pFunctSignalPre(). Can be NULL + * @param pFunctSignalPre Pointer to the callback function. Not called if NULL. + */ +void CO_TIME_initCallbackPre( + CO_TIME_t *TIME, + void *object, + void (*pFunctSignalPre)(void *object)); +#endif + /** * Process TIME communication. * diff --git a/301/CO_config.h b/301/CO_config.h index 60362af..70cd6fd 100644 --- a/301/CO_config.h +++ b/301/CO_config.h @@ -262,6 +262,18 @@ extern "C" { #endif +/** + * Configuration of TIME + * + * Possible flags, can be ORed: + * - #CO_CONFIG_FLAG_CALLBACK_PRE - Enable custom callback after preprocessing + * received TIME CAN message. + * Callback is configured by CO_TIME_initCallbackPre(). + */ +#ifdef CO_DOXYGEN +#define CO_CONFIG_TIME (CO_CONFIG_FLAG_CALLBACK_PRE) +#endif + /** * Configuration of LSS master object * diff --git a/example/CO_driver_target.h b/example/CO_driver_target.h index da2ec4c..ada8042 100644 --- a/example/CO_driver_target.h +++ b/example/CO_driver_target.h @@ -100,6 +100,10 @@ extern "C" { #define CO_CONFIG_SDO_CLI_BUFFER_SIZE 1000 #endif +#ifndef CO_CONFIG_TIME +#define CO_CONFIG_TIME (CO_CONFIG_FLAG_CALLBACK_PRE) +#endif + #ifndef CO_CONFIG_LSS_MST #define CO_CONFIG_LSS_MST (CO_CONFIG_FLAG_CALLBACK_PRE) #endif diff --git a/socketCAN/CO_driver_target.h b/socketCAN/CO_driver_target.h index 255055d..9335d0e 100644 --- a/socketCAN/CO_driver_target.h +++ b/socketCAN/CO_driver_target.h @@ -106,6 +106,10 @@ extern "C" { #define CO_CONFIG_SDO_CLI_BUFFER_SIZE 1000 #endif +#ifndef CO_CONFIG_TIME +#define CO_CONFIG_TIME (CO_CONFIG_FLAG_CALLBACK_PRE) +#endif + #ifndef CO_CONFIG_LSS_MST #define CO_CONFIG_LSS_MST (CO_CONFIG_FLAG_CALLBACK_PRE) #endif From b4b0fe069f5462acdf0bd58238505b59b3a3d1b6 Mon Sep 17 00:00:00 2001 From: Freddie Chopin Date: Wed, 6 May 2020 18:22:50 +0200 Subject: [PATCH 3/3] Convert {T,R}PDO_CALLS_EXTENSION to CO_CONFIG_{T,R}PDO_CALLS_EXTENSION User can now enable extension callbacks in RPDO/TPDO handling paths simply by configuration flags instead of modifying sources or by passing the defines directly to the compiler. --- 301/CO_PDO.c | 14 ++++++-------- 301/CO_config.h | 8 +++++++- example/CO_driver_target.h | 4 +++- socketCAN/CO_driver_target.h | 4 +++- 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/301/CO_PDO.c b/301/CO_PDO.c index 7f989cf..fb8b9f4 100644 --- a/301/CO_PDO.c +++ b/301/CO_PDO.c @@ -891,14 +891,13 @@ uint8_t CO_TPDOisCOS(CO_TPDO_t *TPDO){ return 0; } -//#define TPDO_CALLS_EXTENSION /******************************************************************************/ int16_t CO_TPDOsend(CO_TPDO_t *TPDO){ int16_t i; uint8_t* pPDOdataByte; uint8_t** ppODdataByte; -#ifdef TPDO_CALLS_EXTENSION +#if (CO_CONFIG_PDO) & CO_CONFIG_TPDO_CALLS_EXTENSION if(TPDO->SDO->ODExtensions){ /* for each mapped OD, check mapping to see if an OD extension is available, and call it if it is */ const uint32_t* pMap = &TPDO->TPDOMapPar->mappedObject1; @@ -940,7 +939,6 @@ int16_t CO_TPDOsend(CO_TPDO_t *TPDO){ return CO_CANsend(TPDO->CANdevTx, TPDO->CANtxBuff); } -//#define RPDO_CALLS_EXTENSION /******************************************************************************/ void CO_RPDO_process(CO_RPDO_t *RPDO, bool_t syncWas){ bool_t process_rpdo = true; @@ -959,9 +957,9 @@ void CO_RPDO_process(CO_RPDO_t *RPDO, bool_t syncWas){ } else if(process_rpdo) { -#if defined(RPDO_CALLS_EXTENSION) +#if (CO_CONFIG_PDO) & CO_CONFIG_RPDO_CALLS_EXTENSION bool_t update = false; -#endif /* defined(RPDO_CALLS_EXTENSION) */ +#endif uint8_t bufNo = 0; @@ -987,11 +985,11 @@ void CO_RPDO_process(CO_RPDO_t *RPDO, bool_t syncWas){ for(; i>0; i--) { **(ppODdataByte++) = *(pPDOdataByte++); } -#if defined(RPDO_CALLS_EXTENSION) +#if (CO_CONFIG_PDO) & CO_CONFIG_RPDO_CALLS_EXTENSION update = true; -#endif /* defined(RPDO_CALLS_EXTENSION) */ +#endif } -#ifdef RPDO_CALLS_EXTENSION +#if (CO_CONFIG_PDO) & CO_CONFIG_RPDO_CALLS_EXTENSION if(update && RPDO->SDO->ODExtensions){ int16_t i; /* for each mapped OD, check mapping to see if an OD extension is available, and call it if it is */ diff --git a/301/CO_config.h b/301/CO_config.h index 70cd6fd..0fb5d02 100644 --- a/301/CO_config.h +++ b/301/CO_config.h @@ -199,11 +199,17 @@ extern "C" { * - #CO_CONFIG_FLAG_TIMERNEXT - Enable calculation of timerNext_us variable * inside CO_TPDO_process(). * - CO_CONFIG_PDO_SYNC_ENABLE - Enable SYNC object inside PDO objects. + * - CO_CONFIG_RPDO_CALLS_EXTENSION - Enable calling configured extension + * callbacks when received RPDO CAN message modifies OD entries. + * - CO_CONFIG_TPDO_CALLS_EXTENSION - Enable calling configured extension + * callbacks before TPDO CAN message is sent. */ #ifdef CO_DOXYGEN -#define CO_CONFIG_PDO (CO_CONFIG_FLAG_CALLBACK_PRE | CO_CONFIG_FLAG_TIMERNEXT | CO_CONFIG_PDO_SYNC_ENABLE) +#define CO_CONFIG_PDO (CO_CONFIG_FLAG_CALLBACK_PRE | CO_CONFIG_FLAG_TIMERNEXT | CO_CONFIG_PDO_SYNC_ENABLE | CO_CONFIG_RPDO_CALLS_EXTENSION | CO_CONFIG_TPDO_CALLS_EXTENSION) #endif #define CO_CONFIG_PDO_SYNC_ENABLE 0x01 +#define CO_CONFIG_RPDO_CALLS_EXTENSION 0x02 +#define CO_CONFIG_TPDO_CALLS_EXTENSION 0x04 /** diff --git a/example/CO_driver_target.h b/example/CO_driver_target.h index ada8042..4dd5589 100644 --- a/example/CO_driver_target.h +++ b/example/CO_driver_target.h @@ -80,7 +80,9 @@ extern "C" { #ifndef CO_CONFIG_PDO #define CO_CONFIG_PDO (CO_CONFIG_FLAG_CALLBACK_PRE | \ CO_CONFIG_FLAG_TIMERNEXT | \ - CO_CONFIG_PDO_SYNC_ENABLE) + CO_CONFIG_PDO_SYNC_ENABLE | \ + CO_CONFIG_RPDO_CALLS_EXTENSION | \ + CO_CONFIG_TPDO_CALLS_EXTENSION) #endif #ifndef CO_CONFIG_SYNC diff --git a/socketCAN/CO_driver_target.h b/socketCAN/CO_driver_target.h index 9335d0e..764b87f 100644 --- a/socketCAN/CO_driver_target.h +++ b/socketCAN/CO_driver_target.h @@ -86,7 +86,9 @@ extern "C" { #ifndef CO_CONFIG_PDO #define CO_CONFIG_PDO (CO_CONFIG_FLAG_CALLBACK_PRE | \ CO_CONFIG_FLAG_TIMERNEXT | \ - CO_CONFIG_PDO_SYNC_ENABLE) + CO_CONFIG_PDO_SYNC_ENABLE | \ + CO_CONFIG_RPDO_CALLS_EXTENSION | \ + CO_CONFIG_TPDO_CALLS_EXTENSION) #endif #ifndef CO_CONFIG_SYNC