From 8fb48173c65db56757721d42339d25d749439ac8 Mon Sep 17 00:00:00 2001 From: Janez Date: Wed, 26 Feb 2020 17:09:56 +0100 Subject: [PATCH] Add CO_CANopenInitCallback() into CANopen.h/.c. Change CO_*_initCallback() functions - add 'void *object' argument. --- 301/CO_Emergency.c | 9 ++++++--- 301/CO_Emergency.h | 9 ++++++--- 301/CO_SDOclient.c | 11 +++++++---- 301/CO_SDOclient.h | 8 ++++++-- 301/CO_SDOserver.c | 7 +++++-- 301/CO_SDOserver.h | 8 ++++++-- CANopen.c | 17 +++++++++++++++++ CANopen.h | 15 +++++++++++++++ doc/CHANGELOG.md | 1 + socketCAN/CO_Linux_threads.c | 31 ++----------------------------- 10 files changed, 71 insertions(+), 45 deletions(-) diff --git a/301/CO_Emergency.c b/301/CO_Emergency.c index b7f9373..f383c93 100644 --- a/301/CO_Emergency.c +++ b/301/CO_Emergency.c @@ -160,6 +160,7 @@ CO_ReturnError_t CO_EM_init( em->bufFull = 0U; em->wrongErrorReport = 0U; em->pFunctSignal = NULL; + em->functSignalObject = NULL; em->pFunctSignalRx = NULL; emPr->em = em; emPr->errorRegister = errorRegister; @@ -205,9 +206,11 @@ CO_ReturnError_t CO_EM_init( /******************************************************************************/ void CO_EM_initCallback( CO_EM_t *em, - void (*pFunctSignal)(void)) + void *object, + void (*pFunctSignal)(void *object)) { if(em != NULL){ + em->functSignalObject = object; em->pFunctSignal = pFunctSignal; } } @@ -391,7 +394,7 @@ void CO_errorReport(CO_EM_t *em, const uint8_t errorBit, const uint16_t errorCod /* Optional signal to RTOS, which can resume task, which handles CO_EM_process */ if(em->pFunctSignal != NULL) { - em->pFunctSignal(); + em->pFunctSignal(em->functSignalObject); } } } @@ -450,7 +453,7 @@ void CO_errorReset(CO_EM_t *em, const uint8_t errorBit, const uint32_t infoCode) /* Optional signal to RTOS, which can resume task, which handles CO_EM_process */ if(em->pFunctSignal != NULL) { - em->pFunctSignal(); + em->pFunctSignal(em->functSignalObject); } } } diff --git a/301/CO_Emergency.h b/301/CO_Emergency.h index 87e293a..0d8faba 100644 --- a/301/CO_Emergency.h +++ b/301/CO_Emergency.h @@ -262,9 +262,10 @@ typedef struct{ uint8_t *bufReadPtr; /**< Read pointer in the above buffer */ uint8_t bufFull; /**< True if above buffer is full */ uint8_t wrongErrorReport; /**< Error in arguments to CO_errorReport() */ - /** From CO_EM_initCallback() or NULL */ - void (*pFunctSignal)(void); + void (*pFunctSignal)(void *object); + /** From CO_EM_initCallback() or NULL */ + void *functSignalObject; /** From CO_EM_initCallbackRx() or NULL */ void (*pFunctSignalRx)(const uint16_t ident, const uint16_t errorCode, @@ -394,11 +395,13 @@ CO_ReturnError_t CO_EM_init( * which processes mainline CANopen functions. * * @param em This object. + * @param object Pointer to object, which will be passed to pFunctSignal(). Can be NULL * @param pFunctSignal Pointer to the callback function. Not called if NULL. */ void CO_EM_initCallback( CO_EM_t *em, - void (*pFunctSignal)(void)); + void *object, + void (*pFunctSignal)(void *object)); /** diff --git a/301/CO_SDOclient.c b/301/CO_SDOclient.c index 3815cca..d028743 100644 --- a/301/CO_SDOclient.c +++ b/301/CO_SDOclient.c @@ -162,7 +162,7 @@ static void CO_SDOclient_receive(void *object, void *msg){ /* Optional signal to RTOS, which can resume task, which handles SDO client. */ if(CO_FLAG_READ(SDO_C->CANrxNew) && SDO_C->pFunctSignal != NULL) { - SDO_C->pFunctSignal(); + SDO_C->pFunctSignal(SDO_C->functSignalObject); } } } @@ -195,6 +195,7 @@ CO_ReturnError_t CO_SDOclient_init( SDO_C->SDOClientPar = SDOClientPar; SDO_C->pFunctSignal = NULL; + SDO_C->functSignalObject = NULL; SDO_C->CANdevRx = CANdevRx; SDO_C->CANdevRxIdx = CANdevRxIdx; @@ -214,9 +215,11 @@ CO_ReturnError_t CO_SDOclient_init( /******************************************************************************/ void CO_SDOclient_initCallback( CO_SDOclient_t *SDOclient, - void (*pFunctSignal)(void)) + void *object, + void (*pFunctSignal)(void *object)) { if(SDOclient != NULL){ + SDOclient->functSignalObject = object; SDOclient->pFunctSignal = pFunctSignal; } } @@ -360,7 +363,7 @@ CO_SDOclient_return_t CO_SDOclientDownloadInitiate( /* Optional signal to RTOS. We can immediately continue SDO Client */ if(SDO_C->pFunctSignal != NULL) { - SDO_C->pFunctSignal(); + SDO_C->pFunctSignal(SDO_C->functSignalObject); } return CO_SDOcli_ok_communicationEnd; @@ -814,7 +817,7 @@ CO_SDOclient_return_t CO_SDOclientUploadInitiate( /* Optional signal to RTOS. We can immediately continue SDO Client */ if(SDO_C->pFunctSignal != NULL) { - SDO_C->pFunctSignal(); + SDO_C->pFunctSignal(SDO_C->functSignalObject); } return CO_SDOcli_ok_communicationEnd; diff --git a/301/CO_SDOclient.h b/301/CO_SDOclient.h index 28df959..ac74c8c 100644 --- a/301/CO_SDOclient.h +++ b/301/CO_SDOclient.h @@ -134,7 +134,9 @@ typedef struct{ /** 8 data bytes of the received message */ uint8_t CANrxData[8]; /** From CO_SDOclient_initCallback() or NULL */ - void (*pFunctSignal)(void); + void (*pFunctSignal)(void *object); + /** From CO_SDOclient_initCallback() or NULL */ + void *functSignalObject; /** From CO_SDOclient_init() */ CO_CANmodule_t *CANdevTx; /** CAN transmit buffer inside CANdevTx for CAN tx message */ @@ -200,11 +202,13 @@ CO_ReturnError_t CO_SDOclient_init( * which processes mainline CANopen functions. * * @param SDOclient This object. + * @param object Pointer to object, which will be passed to pFunctSignal(). Can be NULL * @param pFunctSignal Pointer to the callback function. Not called if NULL. */ void CO_SDOclient_initCallback( CO_SDOclient_t *SDOclient, - void (*pFunctSignal)(void)); + void *object, + void (*pFunctSignal)(void *object)); /** diff --git a/301/CO_SDOserver.c b/301/CO_SDOserver.c index bd5c278..8c0506c 100644 --- a/301/CO_SDOserver.c +++ b/301/CO_SDOserver.c @@ -240,7 +240,7 @@ static void CO_SDO_receive(void *object, void *msg){ /* Optional signal to RTOS, which can resume task, which handles SDO server. */ if(CO_FLAG_READ(SDO->CANrxNew) && SDO->pFunctSignal != NULL) { - SDO->pFunctSignal(); + SDO->pFunctSignal(SDO->functSignalObject); } } } @@ -322,6 +322,7 @@ CO_ReturnError_t CO_SDO_init( SDO->state = CO_SDO_ST_IDLE; CO_FLAG_CLEAR(SDO->CANrxNew); SDO->pFunctSignal = NULL; + SDO->functSignalObject = NULL; /* Configure Object dictionary entry at index 0x1200 */ @@ -361,9 +362,11 @@ CO_ReturnError_t CO_SDO_init( /******************************************************************************/ void CO_SDO_initCallback( CO_SDO_t *SDO, - void (*pFunctSignal)(void)) + void *object, + void (*pFunctSignal)(void *object)) { if(SDO != NULL){ + SDO->functSignalObject = object; SDO->pFunctSignal = pFunctSignal; } } diff --git a/301/CO_SDOserver.h b/301/CO_SDOserver.h index 213b5e4..fb49a5d 100644 --- a/301/CO_SDOserver.h +++ b/301/CO_SDOserver.h @@ -630,7 +630,9 @@ typedef struct{ /** Variable indicates, if new SDO message received from CAN bus */ volatile void *CANrxNew; /** From CO_SDO_initCallback() or NULL */ - void (*pFunctSignal)(void); + void (*pFunctSignal)(void *object); + /** From CO_SDO_initCallback() or NULL */ + void *functSignalObject; /** From CO_SDO_init() */ CO_CANmodule_t *CANdevTx; /** CAN transmit buffer inside CANdev for CAN tx message */ @@ -788,11 +790,13 @@ CO_ReturnError_t CO_SDO_init( * which processes mainline CANopen functions. * * @param SDO This object. + * @param object Pointer to object, which will be passed to pFunctSignal(). Can be NULL * @param pFunctSignal Pointer to the callback function. Not called if NULL. */ void CO_SDO_initCallback( CO_SDO_t *SDO, - void (*pFunctSignal)(void)); + void *object, + void (*pFunctSignal)(void *object)); /** diff --git a/CANopen.c b/CANopen.c index e2a3f25..9e3b8d4 100644 --- a/CANopen.c +++ b/CANopen.c @@ -626,6 +626,23 @@ CO_ReturnError_t CO_CANopenInit(uint8_t nodeId) { } +/******************************************************************************/ +void CO_CANopenInitCallback(void *object, + void (*pFunctSignal)(void *object)) +{ + CO_SDO_initCallback(CO->SDO[0], object, pFunctSignal); + CO_EM_initCallback(CO->em, object, pFunctSignal); +#if CO_NO_SDO_CLIENT != 0 + for (i = 0; i < CO_NO_SDO_CLIENT; i++) { + CO_SDOclient_initCallback(CO->SDOclient[i], object, pFunctSignal); + } +#endif +#if CO_NO_LSS_CLIENT == 1 + CO_LSSmaster_initCallback(CO->LSSmaster, object, pFunctSignal); +#endif +} + + /******************************************************************************/ CO_NMT_reset_cmd_t CO_process(CO_t *co, uint32_t timeDifference_us, diff --git a/CANopen.h b/CANopen.h index 765c7db..10bc496 100644 --- a/CANopen.h +++ b/CANopen.h @@ -273,6 +273,21 @@ CO_ReturnError_t CO_LSSinit(uint8_t nodeId, CO_ReturnError_t CO_CANopenInit(uint8_t nodeId); +/** + * Initialize callback functions. + * + * Function initializes optional callback functions, which executes after + * internal state of some CANopen object changes. For example, after CAN message + * is received or error condition is changed. Function may wake up external + * task, which processes mainline CANopen functions. + * + * @param object Pointer to object, which will be passed to pFunctSignal(). Can be NULL + * @param pFunctSignal Pointer to the callback function. Not called if NULL. + */ +void CO_CANopenInitCallback(void *object, + void (*pFunctSignal)(void *object)); + + /** * Process CANopen objects. * diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 4cdf713..9216018 100644 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -17,6 +17,7 @@ Change Log - Rename in CO_driver_target.h: `IS_CANrxNew` -> `CO_FLAG_READ`, `SET_CANrxNew` -> `CO_FLAG_SET`, `CLEAR_CANrxNew` -> `CO_FLAG_CLEAR` - CO_driver.h file, function `CO_CANrxBufferInit()`, last argument (callback) changed from `(*pFunct)(void *object, const CO_CANrxMsg_t *message)` to `void (*CANrx_callback)(void *object, void *message)`. New functions are defined in `CO_driver_target.h` file: `CO_CANrxMsg_readIdent()`, `CO_CANrxMsg_readDLC()` and `CO_CANrxMsg_readData()`. - It is necessary to manually update CO_OD.c file - it must include: `301/CO_driver.h`, `CO_OD.h` and `301/CO_SDOserver.h`. +- Added `void *object` argument CO_*_initCallback() functions. Added CO_CANopenInitCallback() into CANopen.h/.c. ### Fixed - Bugfix in `CO_HBconsumer_process()`: argument `timeDifference_us` was set to 0 inside for loop, fixed now. - BUG in CO_HBconsumer.c #168 diff --git a/socketCAN/CO_Linux_threads.c b/socketCAN/CO_Linux_threads.c index 242b05d..8ac3125 100644 --- a/socketCAN/CO_Linux_threads.c +++ b/socketCAN/CO_Linux_threads.c @@ -44,45 +44,18 @@ static uint64_t CO_LinuxThreads_clock_gettime_ms(void) static struct { uint64_t start; /* time value CO_process() was called last time in ms */ - void (*pFunct)(void* object); /* Callback function */ - void *object; } threadMain; -/** - * This function notifies the user application after an event happened - * - * This is necessary because not all stack callbacks support object pointers. - * It is not used for those callbacks that have this pointer! - */ -static void threadMain_resumeCallback(void) -{ - if (threadMain.pFunct != NULL) { - threadMain.pFunct(threadMain.object); - } -} - void threadMain_init(void (*callback)(void*), void *object) { threadMain.start = CO_LinuxThreads_clock_gettime_ms(); - threadMain.pFunct = callback; - threadMain.object = object; - CO_SDO_initCallback(CO->SDO[0], threadMain_resumeCallback); - CO_EM_initCallback(CO->em, threadMain_resumeCallback); -#if CO_NO_LSS_CLIENT == 1 - CO_LSSmaster_initCallback(CO->LSSmaster, threadMain.object, threadMain.pFunct); -#endif -#if CO_NO_SDO_CLIENT != 0 - for (int i = 0; i < CO_NO_SDO_CLIENT; i++) { - CO_SDOclient_initCallback(CO->SDOclient[i], threadMain_resumeCallback); - } -#endif + CO_CANopenInitCallback(object, callback); } void threadMain_close(void) { - threadMain.pFunct = NULL; - threadMain.object = NULL; + CO_CANopenInitCallback(NULL, NULL); } void threadMain_process(CO_NMT_reset_cmd_t *reset)