⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 updown.c

📁 simulink real-time workshop for dragon12 development board from
💻 C
📖 第 1 页 / 共 5 页
字号:
     * Re-initialize trigger fields.
     */
    uploadInfo.trigInfo.count             = 0;
    uploadInfo.trigInfo.haveOldTrigSigVal = FALSE;

    /* 
     * Reset pre-trig counts for normal mode.
     */
    uploadInfo.trigInfo.preTrig.count = 0;

    /* 
     * Re-arm after all initialization.  Make sure that trigInfo.state is
     * set last since this routine may be interupted.
     */
    uploadInfo.trigInfo.state = TRIGGER_ARMED;

} /* end UploadArmTrigger */


/* Function ====================================================================
 * Terminate this data logging session by destroying the uploadInfo and
 * setting the trigger backed to the unarmed state.
 */
PRIVATE void EndLoggingSession(void)
{
    uploadInfo.trigInfo.state = TRIGGER_UNARMED;
    UploadLogInfoTerm();
} /* end UploadEndLoggingSession */


/* Function ====================================================================
 * Cancel this data logging session.
 */
PUBLIC void UploadCancelLogging(void)
{
    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 msg 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:
    case TRIGGER_SENDING_TERM_MSG:
        /*
         * 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;
    }
} /* 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)
{
    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);

    /*
     * See if this is the end of the data logging event.
     */
    if (uploadInfo.trigInfo.state == TRIGGER_SENDING_TERM_MSG) {
        
        if (uploadInfo.trigInfo.holdOff == TRIGMODE_ONESHOT) {
            EndLoggingSession();
        } else {
            uploadInfo.trigInfo.count = 0;
            uploadInfo.trigInfo.state = TRIGGER_HOLDING_OFF;
        }
    }
} /* end UploadBufDataSent */


/*
 * Macro =======================================================================
 * Move the tail of a circular buffer forward by one time step - accounting for
 * wrapping.
 */
#define MOVE_TAIL_ONESTEP(circBuf, end)                            \
{                                                                  \
    int  nBytesPassedEnd;                                          \
    int  nBytesInStep;                                             \
                                                                   \
    (void)memcpy(&nBytesInStep, (circBuf)->tail, sizeof(int32_T)); \
    assert(nBytesInStep > 0);                                      \
    (circBuf)->tail += (nBytesInStep);                             \
    nBytesPassedEnd = (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), (uint16_T)((bufMem).nBytes1));  \
    if ((bufMem).section2 != NULL) {                            \
        char *tmp = ((char *)(data)) + (bufMem).nBytes1;        \
        (void)memcpy((bufMem).section2, tmp, (uint16_T)((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 passed end */

    if ((*tmpHead > circBuf->tail) || circBuf->empty) {
        /* buffer not wrapped */
        nBytesLeft = (end - *tmpHead) + (circBuf->tail - circBuf->buf);

        if (nBytesLeft < nBytesToAdd) {
            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  = end - *tmpHead;
            bufMem->section1 = *tmpHead;

            bufMem->nBytes2  = nBytesToAdd - bufMem->nBytes1;
            bufMem->section2 = (bufMem->nBytes2 > 0) ? circBuf->buf : NULL;

            *tmpHead = circBuf->buf + bufMem->nBytes2;
        }  
    } else {
        /* wrapped */
        nBytesLeft = circBuf->tail - *tmpHead;
        if (nBytesLeft < nBytesToAdd) {
            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(void)
{
    int         i;
    TriggerInfo *trigInfo       = &uploadInfo.trigInfo;
    real_T      *oldTrigSigVals = trigInfo->oldTrigSigVals;
    real_T      *oldSigPtr      = oldTrigSigVals;
       
    for (i=0; i<trigInfo->trigSignals.nSections; i++) {
        BIOSection *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, (uint16_T)(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 message that is sent to the host is as follows:
 *
 * definitions:
 *      nBytes - total number of target bytes for this message (including the
 *               nBytes field).  nBytes worth of data represents 1 full time
 *               step of the target simulation.
 *
 *      msgType - 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).
 *
 *      nSys - The number of systems for which this message contains data.
 *
 *      tid - The tid with which this data is associated.
 *
 *      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 message looks like:
 * [nBytes msgType nSys tid t sysId [data] sysId [data]...]
 *     |                     | |         | |          |
 *     ----------------------- ----------- ------------
 *          msg header          sys data     sys data
 *
 * Ints are int32_T.
 */
PUBLIC void UploadBufAddTimePoint(int_T tid, real_T taskTime)
{
    int_T       preTrig;
    TriggerInfo *trigInfo = &uploadInfo.trigInfo;
    CircularBuf *circBuf  = &uploadInfo.circBufs[tid];
    int_T       overFlow  = FALSE;

    /*
     * 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 ((tid == trigInfo->tid) && (trigInfo->state == TRIGGER_ARMED)) {
        if ((trigInfo->trigSignals.nSections == 0) || /* manual trigger       */
            (UploadCheckTriggerSignals())) {          /* trig signal crossing */
    
            if (trigInfo->delay == 0) {
                trigInfo->state = TRIGGER_FIRED;
                trigInfo->count = (uint_T)trigInfo->preTrig.count; /* 0 unless pretrig */
            } else {
                trigInfo->state = TRIGGER_DELAYED;
                assert(trigInfo->count == 0);

                /* We will be skipping this step, so the delay count is 1. */
                trigInfo->count = 1;
            }
        }
    }

    preTrig = (trigInfo->state == TRIGGER_ARMED) &&
              (trigInfo->preTrig.duration > 0);
    
    /*
     * Handle adding data to the collection buffers - if needed.
     */
    if (((trigInfo->state == TRIGGER_FIRED) || preTrig) &&
        circBuf->bufSize != 0) { /* bufSize == 0 means no signals in this tid */

        int_T       i;
        BufMem      bufMem;
        BufMem      msgStart;
        int_T       size;
        char_T      *tmpHead    = circBuf->head;

        const int_T NBYTES_IDX   = 0;
        const int_T MSG_TYPE_IDX = 1;
        const int_T NSYS_IDX     = 2;
        const int_T TID_IDX      = 3;
        int32_T     intHdr[4]    = {0,0,0,0};

        if (preTrig && (trigInfo->preTrig.count==trigInfo->preTrig.duration)) {
            /* Advance the tail (we don't need the oldest point anymore). */
            char *end = circBuf->buf + circBuf->bufSize;
            MOVE_TAIL_ONESTEP(circBuf, end);
            trigInfo->preTrig.count--;
        }

        /*
         * Save some space for the 4 integer values that make up the message
         * header: [nBytes msgType nSys tid].  The values are filled in later.
         */
        size = 4*sizeof(int32_T);
        overFlow = UploadBufAssignMem(circBuf, size, &tmpHead, &msgStart);
        if (overFlow) goto EXIT_POINT;
        intHdr[NBYTES_IDX] += size;

        /* time */
        overFlow = UploadBufAssignMem(
            circBuf, sizeof(real_T), &tmpHead, &bufMem);
        if (overFlow) goto EXIT_POINT;
        intHdr[NBYTES_IDX] += sizeof(real_T);
        
        CIRCBUF_COPY_DATA(bufMem, &taskTime);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -