1
0
Fork 0

Add CO_..._initCallbackPre() for RPDO and SYNC (#178)

* Merge two parts of CO_PDO_receive() into single common code

* Add CO_RPDO_initCallbackPre() for received RPDO messages

This optional mechanism allows to immediatelly wake the thread that
processes RPDO, without waiting for its next tick.

* Add CO_SYNC_initCallbackPre() for received SYNC messages

This optional mechanism allows to immediatelly wake the thread that
processes SYNC, without waiting for its next tick.
This commit is contained in:
Freddie Chopin 2020-05-05 13:23:26 +02:00 committed by GitHub
parent 4c3011d34a
commit aa6075b3c8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 125 additions and 31 deletions

View file

@ -24,6 +24,8 @@
*/
#include <string.h>
#include "301/CO_driver.h"
#include "301/CO_SDOserver.h"
#include "301/CO_Emergency.h"
@ -54,33 +56,19 @@ static void CO_PDO_receive(void *object, void *msg){
(DLC >= RPDO->dataLength))
{
#if (CO_CONFIG_PDO) & CO_CONFIG_PDO_SYNC_ENABLE
if(RPDO->SYNC && RPDO->synchronous && RPDO->SYNC->CANrxToggle) {
/* copy data into second buffer and set 'new message' flag */
RPDO->CANrxData[1][0] = data[0];
RPDO->CANrxData[1][1] = data[1];
RPDO->CANrxData[1][2] = data[2];
RPDO->CANrxData[1][3] = data[3];
RPDO->CANrxData[1][4] = data[4];
RPDO->CANrxData[1][5] = data[5];
RPDO->CANrxData[1][6] = data[6];
RPDO->CANrxData[1][7] = data[7];
CO_FLAG_SET(RPDO->CANrxNew[1]);
}
else {
const size_t index = RPDO->SYNC && RPDO->synchronous && RPDO->SYNC->CANrxToggle;
#else
const size_t index = 0;
#endif
/* copy data into default buffer and set 'new message' flag */
RPDO->CANrxData[0][0] = data[0];
RPDO->CANrxData[0][1] = data[1];
RPDO->CANrxData[0][2] = data[2];
RPDO->CANrxData[0][3] = data[3];
RPDO->CANrxData[0][4] = data[4];
RPDO->CANrxData[0][5] = data[5];
RPDO->CANrxData[0][6] = data[6];
RPDO->CANrxData[0][7] = data[7];
CO_FLAG_SET(RPDO->CANrxNew[0]);
#if (CO_CONFIG_PDO) & CO_CONFIG_PDO_SYNC_ENABLE
/* copy data into appropriate buffer and set 'new message' flag */
memcpy(RPDO->CANrxData[index], data, sizeof(RPDO->CANrxData[index]));
CO_FLAG_SET(RPDO->CANrxNew[index]);
#if (CO_CONFIG_PDO) & CO_CONFIG_FLAG_CALLBACK_PRE
/* Optional signal to RTOS, which can resume task, which handles RPDO. */
if(RPDO->pFunctSignalPre != NULL) {
RPDO->pFunctSignalPre(RPDO->functSignalObjectPre);
}
#endif
}
@ -773,6 +761,10 @@ CO_ReturnError_t CO_RPDO_init(
RPDO->nodeId = nodeId;
RPDO->defaultCOB_ID = defaultCOB_ID;
RPDO->restrictionFlags = restrictionFlags;
#if (CO_CONFIG_PDO) & CO_CONFIG_FLAG_CALLBACK_PRE
RPDO->pFunctSignalPre = NULL;
RPDO->functSignalObjectPre = NULL;
#endif
/* Configure Object dictionary entry at index 0x1400+ and 0x1600+ */
CO_OD_configure(SDO, idx_RPDOCommPar, CO_ODF_RPDOcom, (void*)RPDO, 0, 0);
@ -793,6 +785,21 @@ CO_ReturnError_t CO_RPDO_init(
}
#if (CO_CONFIG_PDO) & CO_CONFIG_FLAG_CALLBACK_PRE
/******************************************************************************/
void CO_RPDO_initCallbackPre(
CO_RPDO_t *RPDO,
void *object,
void (*pFunctSignalPre)(void *object))
{
if(RPDO != NULL){
RPDO->functSignalObjectPre = object;
RPDO->pFunctSignalPre = pFunctSignalPre;
}
}
#endif
/******************************************************************************/
CO_ReturnError_t CO_TPDO_init(
CO_TPDO_t *TPDO,

View file

@ -188,6 +188,12 @@ typedef struct{
#else
volatile void *CANrxNew[1];
uint8_t CANrxData[1][8];
#endif
#if ((CO_CONFIG_PDO) & CO_CONFIG_FLAG_CALLBACK_PRE) || defined CO_DOXYGEN
/** From CO_RPDO_initCallbackPre() or NULL */
void (*pFunctSignalPre)(void *object);
/** From CO_RPDO_initCallbackPre() or NULL */
void *functSignalObjectPre;
#endif
CO_CANmodule_t *CANdevRx; /**< From CO_RPDO_init() */
uint16_t CANdevRxIdx; /**< From CO_RPDO_init() */
@ -280,6 +286,25 @@ CO_ReturnError_t CO_RPDO_init(
uint16_t CANdevRxIdx);
#if ((CO_CONFIG_PDO) & CO_CONFIG_FLAG_CALLBACK_PRE) || defined CO_DOXYGEN
/**
* Initialize RPDO callback function.
*
* Function initializes optional callback function, which should immediately
* start processing of CO_RPDO_process() function.
* Callback is called after RPDO message is received from the CAN bus.
*
* @param RPDO 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_RPDO_initCallbackPre(
CO_RPDO_t *RPDO,
void *object,
void (*pFunctSignalPre)(void *object));
#endif
/**
* Initialize TPDO object.
*

View file

@ -67,6 +67,13 @@ static void CO_SYNC_receive(void *object, void *msg) {
}
if(CO_FLAG_READ(SYNC->CANrxNew)) {
SYNC->CANrxToggle = SYNC->CANrxToggle ? false : true;
#if (CO_CONFIG_SYNC) & CO_CONFIG_FLAG_CALLBACK_PRE
/* Optional signal to RTOS, which can resume task, which handles SYNC. */
if(SYNC->pFunctSignalPre != NULL) {
SYNC->pFunctSignalPre(SYNC->functSignalObjectPre);
}
#endif
}
}
}
@ -285,6 +292,11 @@ CO_ReturnError_t CO_SYNC_init(
SYNC->CANdevRx = CANdevRx;
SYNC->CANdevRxIdx = CANdevRxIdx;
#if (CO_CONFIG_SYNC) & CO_CONFIG_FLAG_CALLBACK_PRE
SYNC->pFunctSignalPre = NULL;
SYNC->functSignalObjectPre = NULL;
#endif
/* Configure Object dictionary entry at index 0x1005, 0x1006 and 0x1019 */
CO_OD_configure(SDO, OD_H1005_COBID_SYNC, CO_ODF_1005, (void*)SYNC, 0, 0);
CO_OD_configure(SDO, OD_H1006_COMM_CYCL_PERIOD, CO_ODF_1006, (void*)SYNC, 0, 0);
@ -319,6 +331,21 @@ CO_ReturnError_t CO_SYNC_init(
}
#if (CO_CONFIG_SYNC) & CO_CONFIG_FLAG_CALLBACK_PRE
/******************************************************************************/
void CO_SYNC_initCallbackPre(
CO_SYNC_t *SYNC,
void *object,
void (*pFunctSignalPre)(void *object))
{
if(SYNC != NULL){
SYNC->functSignalObjectPre = object;
SYNC->pFunctSignalPre = pFunctSignalPre;
}
}
#endif
/******************************************************************************/
uint8_t CO_SYNC_process(
CO_SYNC_t *SYNC,

View file

@ -96,6 +96,12 @@ typedef struct{
uint32_t timer;
/** Set to nonzero value, if SYNC with wrong data length is received from CAN */
uint16_t receiveError;
#if ((CO_CONFIG_SYNC) & CO_CONFIG_FLAG_CALLBACK_PRE) || defined CO_DOXYGEN
/** From CO_SYNC_initCallbackPre() or NULL */
void (*pFunctSignalPre)(void *object);
/** From CO_SYNC_initCallbackPre() or NULL */
void *functSignalObjectPre;
#endif
CO_CANmodule_t *CANdevRx; /**< From CO_SYNC_init() */
uint16_t CANdevRxIdx; /**< From CO_SYNC_init() */
CO_CANmodule_t *CANdevTx; /**< From CO_SYNC_init() */
@ -137,6 +143,25 @@ CO_ReturnError_t CO_SYNC_init(
uint16_t CANdevTxIdx);
#if ((CO_CONFIG_SYNC) & CO_CONFIG_FLAG_CALLBACK_PRE) || defined CO_DOXYGEN
/**
* Initialize SYNC callback function.
*
* Function initializes optional callback function, which should immediately
* start processing of CO_SYNC_process() function.
* Callback is called after SYNC message is received from the CAN bus.
*
* @param SYNC 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_SYNC_initCallbackPre(
CO_SYNC_t *SYNC,
void *object,
void (*pFunctSignalPre)(void *object));
#endif
/**
* Process SYNC communication.
*

View file

@ -193,12 +193,15 @@ extern "C" {
* Configuration of PDO
*
* Possible flags, can be ORed:
* - #CO_CONFIG_FLAG_CALLBACK_PRE - Enable custom callback after preprocessing
* received RPDO CAN message.
* Callback is configured by CO_RPDO_initCallbackPre().
* - #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.
*/
#ifdef CO_DOXYGEN
#define CO_CONFIG_PDO (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)
#endif
#define CO_CONFIG_PDO_SYNC_ENABLE 0x01
@ -207,11 +210,14 @@ extern "C" {
* Configuration of SYNC
*
* Possible flags, can be ORed:
* - #CO_CONFIG_FLAG_CALLBACK_PRE - Enable custom callback after preprocessing
* received SYNC CAN message.
* Callback is configured by CO_SYNC_initCallbackPre().
* - #CO_CONFIG_FLAG_TIMERNEXT - Enable calculation of timerNext_us variable
* inside CO_SYNC_process().
*/
#ifdef CO_DOXYGEN
#define CO_CONFIG_SYNC (CO_CONFIG_FLAG_TIMERNEXT)
#define CO_CONFIG_SYNC (CO_CONFIG_FLAG_CALLBACK_PRE | CO_CONFIG_FLAG_TIMERNEXT)
#endif

View file

@ -78,12 +78,14 @@ extern "C" {
#endif
#ifndef CO_CONFIG_PDO
#define CO_CONFIG_PDO (CO_CONFIG_FLAG_TIMERNEXT | \
#define CO_CONFIG_PDO (CO_CONFIG_FLAG_CALLBACK_PRE | \
CO_CONFIG_FLAG_TIMERNEXT | \
CO_CONFIG_PDO_SYNC_ENABLE)
#endif
#ifndef CO_CONFIG_SYNC
#define CO_CONFIG_SYNC (CO_CONFIG_FLAG_TIMERNEXT)
#define CO_CONFIG_SYNC (CO_CONFIG_FLAG_CALLBACK_PRE | \
CO_CONFIG_FLAG_TIMERNEXT)
#endif
#ifndef CO_CONFIG_SDO_CLI

View file

@ -84,12 +84,14 @@ extern "C" {
#endif
#ifndef CO_CONFIG_PDO
#define CO_CONFIG_PDO (CO_CONFIG_FLAG_TIMERNEXT | \
#define CO_CONFIG_PDO (CO_CONFIG_FLAG_CALLBACK_PRE | \
CO_CONFIG_FLAG_TIMERNEXT | \
CO_CONFIG_PDO_SYNC_ENABLE)
#endif
#ifndef CO_CONFIG_SYNC
#define CO_CONFIG_SYNC (CO_CONFIG_FLAG_TIMERNEXT)
#define CO_CONFIG_SYNC (CO_CONFIG_FLAG_CALLBACK_PRE | \
CO_CONFIG_FLAG_TIMERNEXT)
#endif
#ifndef CO_CONFIG_SDO_CLI