📄 updown.c
字号:
BdUploadInfo *uploadInfo= &uploadInfoArray[upInfoIdx];
switch(uploadInfo->trigInfo.state) {
case TRIGGER_UNARMED:
break;
case TRIGGER_HOLDING_OFF:
case TRIGGER_ARMED:
case TRIGGER_DELAYED:
case TRIGGER_FIRED:
/*
* Move to TRIGGER_TERMINATING and ensure that we are no longer in
* "normal" mode (TRIGMODE_NORMAL) so that the trigger does not get
* re-armed.
*/
uploadInfo->trigInfo.holdOff=TRIGMODE_ONESHOT;
uploadInfo->trigInfo.state=TRIGGER_TERMINATING;
#ifdef VXWORKS
/*
* Let upload server run to ensure that term pkt is sent to host (needed
* for all but the TRIGGERED_FIRED case since the upload server is
* inactive).
*/
semGive(uploadSem);
#endif
break;
case TRIGGER_TERMINATING:
/*
* Ensure that we are no longer in "normal" mode (TRIGMODE_NORMAL) so
* that the trigger does not get re-armed.
*/
uploadInfo->trigInfo.holdOff=TRIGMODE_ONESHOT;
break;
}
#ifdef LCDUSE4ERRORS
/* cosmetics and debug msgs */
DisplayTriggerStateOnLCD(upInfoIdx);
#endif
} /* end UploadCancelLogEvent */
/* Function ====================================================================
* Called by ext_svr (background task), in order to perform tasks that need
* to be done after each time that data has been sent to the host. This
* includes:
*
* o move the tail for the specified buffer forward
* o detect the end of a data logging event so that the trigger state can
* be either set to unarmed (for one shot) or backed to armed (for normal
* mode).
*
* NOTE: UploadBufGetData and UploadBufMoveTail must be called in pairs where the
* UploadBufGetData call precedes the UploadBufMoveTail call.
*/
PUBLIC void UploadBufDataSent(const int_T tid, int32_T upInfoIdx) {
BdUploadInfo *uploadInfo= &uploadInfoArray[upInfoIdx];
CircularBuf *circBuf= &uploadInfo->circBufs[tid];
/*
* Move the tail forward. Since we are moving the tail forward, we know that
* head == tail represents an empty buffer and not a full buffer.
*/
circBuf->tail=circBuf->newTail;
circBuf->empty=(circBuf->tail==circBuf->head);
#ifdef HOSTALIVECHECK
circBuf->full = FALSE; /* now also monitoring 'buffer full' condition -- fw-07-07 */
#endif
} /* end UploadBufDataSent */
/*
* Macro =======================================================================
* Move the tail of a circular buffer forward by one time step - accounting for
* wrapping.
*
* turned all 'int' into 'int32_T' -- fw-07-07
*/
#define MOVE_TAIL_ONESTEP(circBuf, end) \
{ \
int32_T nBytesPassedEnd; \
int32_T nBytesInStep; \
int32_T *nBytesPtr = (int32_T *)((circBuf)->tail)+1; \
\
(void)memcpy(&nBytesInStep, nBytesPtr, sizeof(int32_T)); \
nBytesInStep += (2*sizeof(int32_T)); \
assert(nBytesInStep > 0); \
(circBuf)->tail += (nBytesInStep); \
nBytesPassedEnd = (int32_T)((circBuf)->tail - (end)); \
if (nBytesPassedEnd >= 0) { \
(circBuf)->tail = (circBuf)->buf + nBytesPassedEnd; \
} \
} /* end MOVE_TAIL_ONESTEP */
/*
* Macro =======================================================================
* Copy data into the circular buffer.
*/
#define CIRCBUF_COPY_DATA(bufMem, data) \
{ \
(void)memcpy((bufMem).section1, (data), (bufMem).nBytes1); \
if ((bufMem).section2 != NULL) { \
char *tmp = ((char *)(data)) + (bufMem).nBytes1; \
(void)memcpy((bufMem).section2, tmp, (bufMem).nBytes2); \
} \
} /* end CIRCBUF_COPY_DATA */
/* Function ====================================================================
* Assign sections in the circular buffer for the requested number of bytes
* (i.e., fill in the bufMem struct). If there is no room in the circular
* buffer return an overflow error.
*
* NOTE: Do not move the CircularBuffers head forward in this function!
* Only move the tmpHead forward. The actual head is not advanced
* until the entire time point is successfully copied into the buffer.
*
* This function modifies tmpHead to point at the next available
* location.
*
* It is possible for tmpHead to equal the tail upon entry to this
* function. This does not necessarily mean that the buffer is
* empty (unwrapped). It could also mean that the buffer is exactly
* full (this is considered as wrapped).
*/
PRIVATE boolean_T UploadBufAssignMem(CircularBuf *circBuf, int_T nBytesToAdd, char **tmpHead, /* in-out */
BufMem *bufMem) /* out */ {
int_T nBytesLeft;
boolean_T overFlow=FALSE;
char *end=circBuf->buf+circBuf->bufSize; /* 1 past end */
// local function name... debugging only
#if DEBUG_MSG_LVL > 0
const char *funct_name="UploadBufAssignMem";
#endif
#if DISP_CIRCBUF_FREE == 1
#if TARGET_BOARD == DRAGON12
PORTB=0;
#elif TARGET_BOARD != C32BASED
PTH=0;
#endif
#endif
#ifdef HOSTALIVECHECK
/* when the buffer is already full -> do nothing -- fw-07-07 */
if(circBuf->full) {
/* target buffer full -> stop buffering until the host sends the next ACK_PACKET */
HostIsAlive = FALSE; /* assuming that the host is deeeead... stop buffering (mc_main) */
goto EXIT_POINT;
}
#endif
if((*tmpHead>circBuf->tail)||circBuf->empty) {
/* buffer not wrapped */
nBytesLeft=(int_T)((end-*tmpHead)+(circBuf->tail-circBuf->buf));
#if TARGET_BOARD != C32BASED
#if DISP_CIRCBUF_FREE == 1
{
int myFree;
myFree=(int)(nBytesLeft*10/circBuf->bufSize);
displayDigit(myFree);
}
#endif
#endif
if(nBytesLeft<nBytesToAdd) {
#ifdef HOSTALIVECHECK
/* buffer full -> set circBuf->full flag -- fw-07-07 */
circBuf->full = TRUE;
#endif
#if DEBUG_MSG_LVL > 0
PRINT_DEBUG_MSG_LVL1("WARNING: circBuf full! **************************************\n\r");
PRINT_DEBUG_MSG_LVL1("Receive buffer contents:\n\r [");
/* nBytesAvailable = FIFOBUFSIZE -> display up to FIFOBUFSIZE bytes... */
ExtSerialPortPeekRB(FIFOBUFSIZE);
PRINT_DEBUG_MSG_LVL1_Raw(" ]\n\r");
#endif
/* switch debug messages off (to avoid endless <ISR> messages) */
SWITCH_DYNAMIC_DBG_LVL(0);
#if TARGET_BOARD != C32BASED
displayDigit(-1);
#endif
overFlow=TRUE;
goto EXIT_POINT;
}
if((*tmpHead+nBytesToAdd)<end) {
/* still not wrapped */
bufMem->nBytes1=nBytesToAdd;
bufMem->section1= *tmpHead;
bufMem->nBytes2=0;
bufMem->section2=NULL;
*tmpHead+=nBytesToAdd;
}
else {
/* now we're wrapped */
bufMem->nBytes1=(int_T)(end-*tmpHead);
bufMem->section1= *tmpHead;
bufMem->nBytes2=nBytesToAdd-bufMem->nBytes1;
bufMem->section2=(bufMem->nBytes2>0)?circBuf->buf:NULL;
*tmpHead=circBuf->buf+bufMem->nBytes2;
}
}
else {
/* buffer wrapped */
nBytesLeft=(int_T)(circBuf->tail-*tmpHead);
#if TARGET_BOARD != C32BASED
#if DISP_CIRCBUF_FREE == 1
{
int myFree;
myFree=(int)(nBytesLeft*10/circBuf->bufSize);
displayDigit(myFree);
}
#endif
#endif
if(nBytesLeft<nBytesToAdd) {
#ifdef HOSTALIVECHECK
/* buffer full -> set circBuf->full flag -- fw-07-07 */
circBuf->full = TRUE;
#endif
#if DEBUG_MSG_LVL > 0
PRINT_DEBUG_MSG_LVL1("WARNING: circBuf full! **************************************\n\r");
PRINT_DEBUG_MSG_LVL1("Receive buffer contents:\n\r [");
/* nBytesAvailable = FIFOBUFSIZE -> display up to FIFOBUFSIZE bytes... */
ExtSerialPortPeekRB(FIFOBUFSIZE);
PRINT_DEBUG_MSG_LVL1_Raw(" ]\n\r");
#endif
/* switch debug messages off (to avoid endless <ISR> messages) */
SWITCH_DYNAMIC_DBG_LVL(0);
#if TARGET_BOARD != C32BASED
displayDigit(-1);
#endif
overFlow=TRUE;
goto EXIT_POINT;
}
bufMem->nBytes1=nBytesToAdd;
bufMem->section1= *tmpHead;
bufMem->nBytes2=0;
bufMem->section2=NULL;
*tmpHead+=nBytesToAdd;
}
EXIT_POINT:
return(overFlow);
} /* end UploadBufAssignMem */
/* Function ====================================================================
* Check the trigger signals for crossings. Return true if a trigger event is
* encountered. It is assumed that the trigger signals are real_T.
*/
PRIVATE boolean_T UploadCheckTriggerSignals(int32_T upInfoIdx) {
int i;
BdUploadInfo *uploadInfo= &uploadInfoArray[upInfoIdx];
TriggerInfo *trigInfo= &uploadInfo->trigInfo;
real_T *oldTrigSigVals=trigInfo->oldTrigSigVals;
real_T *oldSigPtr=oldTrigSigVals;
for(i=0; i<trigInfo->trigSignals.nSections; i++) {
UploadSection *section= &trigInfo->trigSignals.sections[i];
int_T nEls=section->nBytes/sizeof(real_T); /* xxx cache? */
/*
* If we have a previous signal value to check, then see if we had
* a crossing.
*/
if(trigInfo->haveOldTrigSigVal) {
int_T j;
real_T level=trigInfo->level;
real_T *rStart=(real_T *)section->start; /* gauranteed by host */
for(j=0; j<nEls; j++) {
if(trigInfo->lookForRising&&(((rStart[j]>=level)&&(oldSigPtr[j]<level))||((rStart[j]>level)&&(oldSigPtr[j]==level)))) {
return(TRUE);
}
if(trigInfo->lookForFalling&&(((rStart[j]<level)&&(oldSigPtr[j]>=level))||((rStart[j]==level)&&(oldSigPtr[j]>level)))) {
return(TRUE);
}
}
}
/*
* Update old signal values.
*/
(void)memcpy(oldSigPtr, section->start, section->nBytes);
oldSigPtr+=section->nBytes;
}
assert(oldTrigSigVals+trigInfo->trigSignals.nBytes==oldSigPtr);
trigInfo->haveOldTrigSigVal=TRUE;
return(FALSE);
} /* end UploadCheckTriggerSignals */
/* Function ====================================================================
* If the trigger is in the TRIGGER_FIRED state or we are collecting data for
* pretriggering, add data, for each tid with a hit, to the upload buffers.
* This function is called from within the appropriate task, once per sample
* hit.
*
* The format of the packet that is sent to the host is as follows:
*
* definitions:
* pktType - A qualifier indicating any special action that needs to be
* taken (e.g., a termination flag following the last data point,
* or a flag indicating that it is the first data point after
* a trigger event).
*
* nBytes - total number of target bytes for this packet (including the
* nBytes field). nBytes worth of data represents 1 full time
* step of the target simulation.
*
* nSys - The number of systems for which this packet contains data.
*
* tid - The tid with which this data is associated.
*
* upInfoIdx - upInfo index
*
* t - simulation time
*
* sysId - The index into the BdUploadInfo.sysTables array so that we can
* map the target data back to the appropriate sytstem. This is
* NOT the descendent system index!
*
* data - the target simulation data (in target format)
*
* The packet looks like:
* [nBytes pktType nSys tid upInfoIdx t sysId [data] sysId [data]...]
* | | | | | |
* ----------------------------- ----------- ------------
* pkt header sys data sys data
*
* Ints are int32_T.
*/
PUBLIC void UploadBufAddTimePoint(int_T tid, real_T taskTime, int32_T upInfoIdx) {
int_T preTrig;
int_T overFlow;
TriggerInfo *trigInfo;
CircularBuf *circBuf;
BdUploadInfo *uploadInfo= &uploadInfoArray[upInfoIdx];
overFlow=FALSE;
trigInfo= &uploadInfo->trigInfo;
circBuf= &uploadInfo->circBufs[tid];
/*
* Check for transitions from the TRIGGER_ARMED state to either the
* TRIGGER_FIRED_STATE or the TRIGGER_DELAYED state. We only do this
* if it is a sample hit for the trigger signal. Note that this
* is the only place in the whole world that the trigger state can
* move from TRIGGER_ARMED_STATE to TRIGGER_DELAYED or TRIGGER_FIRED.
*/
if(trigInfo->state==TRIGGER_ARMED) {
if(trigInfo->trigSignals.nSections==0) {
/* short-circuit for manual trigger */
trigInfo->state=TRIGGER_FIRED;
}
else if((tid==trigInfo->tid)&&(UploadCheckTriggerSignals(upInfoIdx))) {
/* trig signal crossing */
if(trigInfo->delay==0) {
trigInfo->state=TRIGGER_FIRED;
/* 0 unless pretrig */
trigInfo->count=(int_T)(trigInfo->preTrig.count);
}
else {
trigInfo->state=TRIGGER_DELAYED;
assert(t
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -