1
0
Fork 0

Remove CO_CONFIG_EM_BUFFER_SIZE macro, size is fetched from Object Dictionary

It is necessary to re-generate OD.h file with the latest CANopenEditor
from https://github.com/CANopenNode/CANopenEditor
This commit is contained in:
Janez 2021-06-28 12:39:03 +02:00
parent b8b9011f7f
commit b9927ff1cd
5 changed files with 166 additions and 100 deletions

View file

@ -34,11 +34,7 @@
#error CO_CONFIG_EM_ERR_STATUS_BITS_COUNT is not correct
#endif
#if CO_CONFIG_EM_BUFFER_SIZE < 1 || CO_CONFIG_EM_BUFFER_SIZE > 254
#error CO_CONFIG_EM_BUFFER_SIZE is not correct
#endif
/* fifo buffer example for CO_CONFIG_EM_BUFFER_SIZE = 6 (em->fifo size = 6+1) *
/* fifo buffer example for fifoSize = 7 (actual capacity = 6) *
* *
* 0 * * * * *
* 1 pp==wp fifoPpPtr fifoWrPtr * *
@ -194,6 +190,9 @@ static ODR_t OD_read_1003(OD_stream_t *stream, void *buf,
CO_EM_t *em = (CO_EM_t *)stream->object;
if (em->fifoSize < 2) {
return ODR_DEV_INCOMPAT;
}
if (stream->subIndex == 0) {
CO_setUint8(buf, em->fifoCount);
@ -205,12 +204,12 @@ static ODR_t OD_read_1003(OD_stream_t *stream, void *buf,
* fifoWrPtr. Get correct index in FIFO buffer. */
int16_t index = (int16_t)em->fifoWrPtr - stream->subIndex;
if (index < 0) {
index += CO_CONFIG_EM_BUFFER_SIZE + 1;
index += em->fifoSize;
}
else if (index >= (CO_CONFIG_EM_BUFFER_SIZE + 1)) {
else if (index >= (em->fifoSize)) {
return ODR_DEV_INCOMPAT;
}
CO_setUint32(buf, em->fifo[index][0]);
CO_setUint32(buf, em->fifo[index].msg);
*countRead = sizeof(uint32_t);
return ODR_OK;
@ -345,12 +344,16 @@ static void CO_EM_receive(void *object, void *msg) {
CO_ReturnError_t CO_EM_init(CO_EM_t *em,
CO_CANmodule_t *CANdevTx,
const OD_entry_t *OD_1001_errReg,
#if (CO_CONFIG_EM) & (CO_CONFIG_EM_PRODUCER | CO_CONFIG_EM_HISTORY)
CO_EM_fifo_t *fifo,
uint8_t fifoSize,
#endif
#if (CO_CONFIG_EM) & CO_CONFIG_EM_PRODUCER
OD_entry_t *OD_1014_cobIdEm,
uint16_t CANdevTxIdx,
#if (CO_CONFIG_EM) & CO_CONFIG_EM_PROD_INHIBIT
#if (CO_CONFIG_EM) & CO_CONFIG_EM_PROD_INHIBIT
OD_entry_t *OD_1015_InhTime,
#endif
#endif
#endif
#if (CO_CONFIG_EM) & CO_CONFIG_EM_HISTORY
OD_entry_t *OD_1003_preDefErr,
@ -371,6 +374,9 @@ CO_ReturnError_t CO_EM_init(CO_EM_t *em,
/* verify arguments */
if (em == NULL || OD_1001_errReg == NULL
#if (CO_CONFIG_EM) & (CO_CONFIG_EM_PRODUCER | CO_CONFIG_EM_HISTORY)
|| (fifo == NULL && fifoSize >= 2)
#endif
#if (CO_CONFIG_EM) & CO_CONFIG_EM_PRODUCER
|| OD_1014_cobIdEm == NULL || CANdevTx == NULL
|| nodeId < 1 || nodeId > 127
@ -399,6 +405,10 @@ CO_ReturnError_t CO_EM_init(CO_EM_t *em,
}
*em->errorRegister = 0;
#if (CO_CONFIG_EM) & (CO_CONFIG_EM_PRODUCER | CO_CONFIG_EM_HISTORY)
em->fifo = fifo;
em->fifoSize = fifoSize;
#endif
#if (CO_CONFIG_EM) & CO_CONFIG_EM_PRODUCER
/* get initial and verify "COB-ID EMCY" from Object Dictionary */
uint32_t COB_IDEmergency32;
@ -616,77 +626,83 @@ void CO_EM_process(CO_EM_t *em,
/* post-process Emergency message in fifo buffer. */
#if (CO_CONFIG_EM) & CO_CONFIG_EM_PRODUCER
uint8_t fifoPpPtr = em->fifoPpPtr;
if (em->fifoSize >= 2) {
uint8_t fifoPpPtr = em->fifoPpPtr;
#if (CO_CONFIG_EM) & CO_CONFIG_EM_PROD_INHIBIT
if (em->inhibitEmTimer < em->inhibitEmTime_us) {
em->inhibitEmTimer += timeDifference_us;
}
if (em->inhibitEmTimer < em->inhibitEmTime_us) {
em->inhibitEmTimer += timeDifference_us;
}
if (fifoPpPtr != em->fifoWrPtr && !em->CANtxBuff->bufferFull
&& em->inhibitEmTimer >= em->inhibitEmTime_us
) {
em->inhibitEmTimer = 0;
if (fifoPpPtr != em->fifoWrPtr && !em->CANtxBuff->bufferFull
&& em->inhibitEmTimer >= em->inhibitEmTime_us
) {
em->inhibitEmTimer = 0;
#else
if (fifoPpPtr != em->fifoWrPtr && !em->CANtxBuff->bufferFull) {
if (fifoPpPtr != em->fifoWrPtr && !em->CANtxBuff->bufferFull) {
#endif
/* add error register to emergency message */
em->fifo[fifoPpPtr][0] |= (uint32_t) errorRegister << 16;
/* add error register to emergency message */
em->fifo[fifoPpPtr].msg |= (uint32_t) errorRegister << 16;
/* send emergency message */
memcpy(em->CANtxBuff->data, &em->fifo[fifoPpPtr][0],
sizeof(em->CANtxBuff->data));
CO_CANsend(em->CANdevTx, em->CANtxBuff);
/* send emergency message */
memcpy(em->CANtxBuff->data, &em->fifo[fifoPpPtr].msg,
sizeof(em->CANtxBuff->data));
CO_CANsend(em->CANdevTx, em->CANtxBuff);
#if (CO_CONFIG_EM) & CO_CONFIG_EM_CONSUMER
/* report also own emergency messages */
if (em->pFunctSignalRx != NULL) {
uint32_t errMsg = em->fifo[fifoPpPtr][0];
em->pFunctSignalRx(0,
CO_SWAP_16((uint16_t) errMsg),
errorRegister,
(uint8_t) (errMsg >> 24),
CO_SWAP_32(em->fifo[fifoPpPtr][1]));
}
/* report also own emergency messages */
if (em->pFunctSignalRx != NULL) {
uint32_t errMsg = em->fifo[fifoPpPtr].msg;
em->pFunctSignalRx(0,
CO_SWAP_16((uint16_t) errMsg),
errorRegister,
(uint8_t) (errMsg >> 24),
CO_SWAP_32(em->fifo[fifoPpPtr].info));
}
#endif
/* increment pointer */
em->fifoPpPtr = (++fifoPpPtr < (CO_CONFIG_EM_BUFFER_SIZE + 1)) ?
fifoPpPtr : 0;
/* increment pointer */
em->fifoPpPtr = (++fifoPpPtr < em->fifoSize) ? fifoPpPtr : 0;
/* verify message buffer overflow. Clear error condition if all messages
* from fifo buffer are processed */
if (em->fifoOverflow == 1) {
em->fifoOverflow = 2;
CO_errorReport(em, CO_EM_EMERGENCY_BUFFER_FULL, CO_EMC_GENERIC, 0);
/* verify message buffer overflow. Clear error condition if all
* messages from fifo buffer are processed */
if (em->fifoOverflow == 1) {
em->fifoOverflow = 2;
CO_errorReport(em, CO_EM_EMERGENCY_BUFFER_FULL,
CO_EMC_GENERIC, 0);
}
else if (em->fifoOverflow == 2 && em->fifoPpPtr == em->fifoWrPtr) {
em->fifoOverflow = 0;
CO_errorReset(em, CO_EM_EMERGENCY_BUFFER_FULL, 0);
}
}
else if (em->fifoOverflow == 2 && em->fifoPpPtr == em->fifoWrPtr) {
em->fifoOverflow = 0;
CO_errorReset(em, CO_EM_EMERGENCY_BUFFER_FULL, 0);
}
}
#if (CO_CONFIG_EM) & CO_CONFIG_EM_PROD_INHIBIT
#if (CO_CONFIG_EM) & CO_CONFIG_FLAG_TIMERNEXT
else if (timerNext_us != NULL && em->inhibitEmTimer < em->inhibitEmTime_us){
/* check again after inhibit time elapsed */
uint32_t diff = em->inhibitEmTime_us - em->inhibitEmTimer;
if (*timerNext_us > diff) {
*timerNext_us = diff;
else if (timerNext_us != NULL
&& em->inhibitEmTimer < em->inhibitEmTime_us)
{
/* check again after inhibit time elapsed */
uint32_t diff = em->inhibitEmTime_us - em->inhibitEmTimer;
if (*timerNext_us > diff) {
*timerNext_us = diff;
}
}
}
#endif
#endif
#elif (CO_CONFIG_EM) & CO_CONFIG_EM_HISTORY
uint8_t fifoPpPtr = em->fifoPpPtr;
while (fifoPpPtr != em->fifoWrPtr) {
/* add error register to emergency message and increment pointers */
em->fifo[fifoPpPtr][0] |= (uint32_t) errorRegister << 16;
if (++fifoPpPtr >= (CO_CONFIG_EM_BUFFER_SIZE + 1)) {
fifoPpPtr = 0;
}
}
em->fifoPpPtr = fifoPpPtr;
#elif (CO_CONFIG_EM) & CO_CONFIG_EM_HISTORY
if (em->fifoSize >= 2) {
uint8_t fifoPpPtr = em->fifoPpPtr;
while (fifoPpPtr != em->fifoWrPtr) {
/* add error register to emergency message and increment pointers */
em->fifo[fifoPpPtr].msg |= (uint32_t) errorRegister << 16;
if (++fifoPpPtr >= em->fifoSize) {
fifoPpPtr = 0;
}
}
em->fifoPpPtr = fifoPpPtr;
}
#endif /* (CO_CONFIG_EM) & CO_CONFIG_EM_PRODUCER, #elif CO_CONFIG_EM_HISTORY */
return;
@ -741,22 +757,24 @@ void CO_error(CO_EM_t *em, bool_t setError, const uint8_t errorBit,
else *errorStatusBits &= ~bitmask;
#if (CO_CONFIG_EM) & (CO_CONFIG_EM_PRODUCER | CO_CONFIG_EM_HISTORY)
uint8_t fifoWrPtr = em->fifoWrPtr;
uint8_t fifoWrPtrNext = fifoWrPtr + 1;
if (fifoWrPtrNext >= (CO_CONFIG_EM_BUFFER_SIZE + 1)) {
fifoWrPtrNext = 0;
}
if (em->fifoSize >= 2) {
uint8_t fifoWrPtr = em->fifoWrPtr;
uint8_t fifoWrPtrNext = fifoWrPtr + 1;
if (fifoWrPtrNext >= em->fifoSize) {
fifoWrPtrNext = 0;
}
if (fifoWrPtrNext == em->fifoPpPtr) {
em->fifoOverflow = 1;
}
else {
em->fifo[fifoWrPtr][0] = errMsg;
if (fifoWrPtrNext == em->fifoPpPtr) {
em->fifoOverflow = 1;
}
else {
em->fifo[fifoWrPtr].msg = errMsg;
#if (CO_CONFIG_EM) & CO_CONFIG_EM_PRODUCER
em->fifo[fifoWrPtr][1] = infoCodeSwapped;
em->fifo[fifoWrPtr].info = infoCodeSwapped;
#endif
em->fifoWrPtr = fifoWrPtrNext;
if (em->fifoCount < CO_CONFIG_EM_BUFFER_SIZE) em->fifoCount++;
em->fifoWrPtr = fifoWrPtrNext;
if (em->fifoCount < (em->fifoSize - 1)) em->fifoCount++;
}
}
#endif /* (CO_CONFIG_EM) & (CO_CONFIG_EM_PRODUCER | CO_CONFIG_EM_HISTORY) */

View file

@ -39,9 +39,6 @@
#ifndef CO_CONFIG_EM_ERR_STATUS_BITS_COUNT
#define CO_CONFIG_EM_ERR_STATUS_BITS_COUNT (10*8)
#endif
#ifndef CO_CONFIG_EM_BUFFER_SIZE
#define CO_CONFIG_EM_BUFFER_SIZE 16
#endif
#ifndef CO_CONFIG_ERR_CONDITION_GENERIC
#define CO_CONFIG_ERR_CONDITION_GENERIC (em->errorStatusBits[5] != 0)
#endif
@ -362,6 +359,21 @@ typedef enum {
} CO_EM_errorStatusBits_t;
#if ((CO_CONFIG_EM) & (CO_CONFIG_EM_PRODUCER | CO_CONFIG_EM_HISTORY)) \
|| defined CO_DOXYGEN
/**
* Fifo buffer for emergency producer and error history
*/
typedef struct {
uint32_t msg;
#if ((CO_CONFIG_EM) & CO_CONFIG_EM_PRODUCER) || defined CO_DOXYGEN
uint32_t info;
#endif
} CO_EM_fifo_t;
#endif
/**
* Emergency object.
*/
@ -379,13 +391,13 @@ typedef struct {
|| defined CO_DOXYGEN
/** Internal circular FIFO buffer for storing pre-processed emergency
* messages. Messages are added by @ref CO_error() function. All messages
* are later post-processed by @ref CO_EM_process() function. Fifo is also
* used for error history - OD object 0x1003, "Pre-defined error field". */
#if ((CO_CONFIG_EM) & CO_CONFIG_EM_PRODUCER) || defined CO_DOXYGEN
uint32_t fifo[CO_CONFIG_EM_BUFFER_SIZE + 1][2];
#else
uint32_t fifo[CO_CONFIG_EM_BUFFER_SIZE + 1][1];
#endif
* are later post-processed by @ref CO_EM_process() function. In case of
* overflow, error is indicated but emergency message is not sent. Fifo is
* also used for error history, OD object 0x1003, "Pre-defined error field".
* Buffer is defined by @ref CO_EM_init(). */
CO_EM_fifo_t *fifo;
/** Size of the above buffer, specified by @ref CO_EM_init(). */
uint8_t fifoSize;
/** Pointer for the fifo buffer, where next emergency message will be
* written by @ref CO_error() function. */
uint8_t fifoWrPtr;
@ -458,6 +470,11 @@ typedef struct {
* Function must be called in the communication reset section.
*
* @param em This object will be initialized.
* @param fifo Fifo buffer for emergency producer and error history. It must be
* defined externally. Its size must be capacity+1. See also @ref CO_EM_t, fifo.
* @param fifoSize Size of the above fifo buffer. It is usually equal to the
* length of the OD array 0x1003 + 1. If fifoSize is smaller than 2, then
* emergency producer and error history will not work and 'fifo' may be NULL.
* @param CANdevTx CAN device for Emergency transmission.
* @param OD_1001_errReg OD entry for 0x1001 - "Error register", entry is
* required, without IO extension.
@ -484,6 +501,11 @@ typedef struct {
CO_ReturnError_t CO_EM_init(CO_EM_t *em,
CO_CANmodule_t *CANdevTx,
const OD_entry_t *OD_1001_errReg,
#if ((CO_CONFIG_EM) & (CO_CONFIG_EM_PRODUCER | CO_CONFIG_EM_HISTORY)) \
|| defined CO_DOXYGEN
CO_EM_fifo_t *fifo,
uint8_t fifoSize,
#endif
#if ((CO_CONFIG_EM) & CO_CONFIG_EM_PRODUCER) || defined CO_DOXYGEN
OD_entry_t *OD_1014_cobIdEm,
uint16_t CANdevTxIdx,

View file

@ -232,20 +232,6 @@ extern "C" {
#define CO_CONFIG_EM_ERR_STATUS_BITS_COUNT (10*8)
#endif
/**
* Size of the internal buffer, where emergencies are stored after error
* indication with @ref CO_error() function. Each emergency has to be post-
* processed by the @ref CO_EM_process() function. In case of overflow, error is
* indicated but emergency message is not sent.
*
* The same buffer is also used for OD object 0x1003, "Pre-defined error field".
*
* Each buffer element consumes 8 bytes. Valid values are 1 to 254.
*/
#ifdef CO_DOXYGEN
#define CO_CONFIG_EM_BUFFER_SIZE 16
#endif
/**
* Condition for calculating CANopen Error register, "generic" error bit.
*

View file

@ -78,6 +78,9 @@
#ifndef OD_ENTRY_H1003
#define OD_ENTRY_H1003 NULL
#endif
#ifndef OD_CNT_ARR_1003
#define OD_CNT_ARR_1003 8
#endif
#if (CO_CONFIG_EM) & CO_CONFIG_EM_PRODUCER
#if OD_CNT_EM_PROD == 1
#define CO_TX_CNT_EM_PROD OD_CNT_EM_PROD
@ -382,6 +385,18 @@ CO_t *CO_new(CO_config_t *config, uint32_t *heapMemoryUsed) {
#endif
#if (CO_CONFIG_EM) & CO_CONFIG_EM_PRODUCER
ON_MULTI_OD(TX_CNT_EM_PROD = 1);
#endif
#if (CO_CONFIG_EM) & (CO_CONFIG_EM_PRODUCER | CO_CONFIG_EM_HISTORY)
uint8_t fifoSize = CO_GET_CNT(ARR_1003) + 1;
if (fifoSize >= 2) {
p = calloc(fifoSize, sizeof(CO_EM_fifo_t));
if (p == NULL) break;
else co->em_fifo = (CO_EM_fifo_t *)p;
mem += fifoSize * sizeof(CO_EM_fifo_t);
}
else {
co->em_fifo = NULL;
}
#endif
}
@ -706,6 +721,9 @@ void CO_delete(CO_t *co) {
/* Emergency */
free(co->em);
#if (CO_CONFIG_EM) & (CO_CONFIG_EM_PRODUCER | CO_CONFIG_EM_HISTORY)
free(co->em_fifo);
#endif
#if (CO_CONFIG_HB_CONS) & CO_CONFIG_HB_CONS_ENABLE
free(co->HBconsMonitoredNodes);
@ -736,6 +754,9 @@ void CO_delete(CO_t *co) {
static CO_HBconsNode_t COO_HBconsMonitoredNodes[OD_CNT_ARR_1016];
#endif
static CO_EM_t COO_EM;
#if (CO_CONFIG_EM) & (CO_CONFIG_EM_PRODUCER | CO_CONFIG_EM_HISTORY)
static CO_EM_fifo_t COO_EM_FIFO[CO_GET_CNT(ARR_1003) + 1];
#endif
static CO_SDOserver_t COO_SDOserver[OD_CNT_SDO_SRV];
#if (CO_CONFIG_SDO_CLI) & CO_CONFIG_SDO_CLI_ENABLE
static CO_SDOclient_t COO_SDOclient[OD_CNT_SDO_CLI];
@ -795,6 +816,9 @@ CO_t *CO_new(CO_config_t *config, uint32_t *heapMemoryUsed) {
co->HBconsMonitoredNodes = &COO_HBconsMonitoredNodes[0];
#endif
co->em = &COO_EM;
#if (CO_CONFIG_EM) & (CO_CONFIG_EM_PRODUCER | CO_CONFIG_EM_HISTORY)
co->em_fifo = &COO_EM_FIFO[0];
#endif
co->SDOserver = &COO_SDOserver[0];
#if (CO_CONFIG_SDO_CLI) & CO_CONFIG_SDO_CLI_ENABLE
co->SDOclient = &COO_SDOclient[0];
@ -972,6 +996,10 @@ CO_ReturnError_t CO_CANopenInit(CO_t *co,
err = CO_EM_init(co->em,
co->CANmodule,
OD_GET(H1001, OD_H1001_ERR_REG),
#if (CO_CONFIG_EM) & (CO_CONFIG_EM_PRODUCER | CO_CONFIG_EM_HISTORY)
co->em_fifo,
(CO_GET_CNT(ARR_1003) + 1),
#endif
#if (CO_CONFIG_EM) & CO_CONFIG_EM_PRODUCER
OD_GET(H1014, OD_H1014_COBID_EMERGENCY),
CO_GET_CO(TX_IDX_EM_PROD),

View file

@ -214,6 +214,12 @@ typedef struct {
const OD_entry_t *ENTRY_H1001; /**< OD entry for @ref CO_EM_init() */
OD_entry_t *ENTRY_H1014; /**< OD entry for @ref CO_EM_init() */
OD_entry_t *ENTRY_H1015; /**< OD entry for @ref CO_EM_init() */
/** Size of the fifo buffer, which is used for intermediate storage of
* emergency messages. Fifo is used by emergency producer and by error
* history (OD object 0x1003). Size is usually equal to size of array in
* OD object 0x1003. If later is not used, CNT_ARR_1003 must also be set to
* value greater than 0, or emergency producer will not work. */
uint8_t CNT_ARR_1003;
OD_entry_t *ENTRY_H1003; /**< OD entry for @ref CO_EM_init() */
/** Number of SDO server objects, from 0 to 128 (CANrx + CANtx). There must
* be at least one SDO server object in the device. */
@ -292,6 +298,7 @@ typedef struct {
#if ((CO_CONFIG_HB_CONS) & CO_CONFIG_HB_CONS_ENABLE) || defined CO_DOXYGEN
/** Heartbeat consumer object, initialised by @ref CO_HBconsumer_init() */
CO_HBconsumer_t *HBcons;
/** Object for monitored nodes, initialised by @ref CO_HBconsumer_init() */
CO_HBconsNode_t *HBconsMonitoredNodes;
#if defined CO_MULTIPLE_OD || defined CO_DOXYGEN
uint16_t RX_IDX_HB_CONS; /**< Start index in CANrx. */
@ -303,6 +310,11 @@ typedef struct {
uint16_t RX_IDX_EM_CONS; /**< Start index in CANrx. */
uint16_t TX_IDX_EM_PROD; /**< Start index in CANtx. */
#endif
#if ((CO_CONFIG_EM) & (CO_CONFIG_EM_PRODUCER | CO_CONFIG_EM_HISTORY)) \
|| defined CO_DOXYGEN
/** FIFO for emergency object, initialised by @ref CO_EM_init() */
CO_EM_fifo_t *em_fifo;
#endif
/** SDO server objects, initialised by @ref CO_SDOserver_init() */
CO_SDOserver_t *SDOserver;
#if defined CO_MULTIPLE_OD || defined CO_DOXYGEN