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

📄 updown.c

📁 simulink real-time workshop for dragon12 development board from
💻 C
📖 第 1 页 / 共 5 页
字号:

        /*
         * Check each system for a BIOMap. 
         */
        for (i=0; i<uploadInfo.nSys; i++) {
            const SysUploadTable *sysTable =
                (const SysUploadTable *)&uploadInfo.sysTables[i];
                
			/* modified (FW-02-03) */
            //if (*sysTable->enableState == SUBSYS_ENABLED ) {
			if(1) {
                BIOMap *map = sysTable->bioMap[tid];
                if (map != NULL) {
                    int_T section;
                
                    intHdr[NSYS_IDX]++;

                    /* Add system index */
                    size = sizeof(int32_T);
                    overFlow = UploadBufAssignMem(
                        circBuf, size, &tmpHead, &bufMem);
                    if (overFlow) goto EXIT_POINT;
                    intHdr[NBYTES_IDX] += size;

                    CIRCBUF_COPY_DATA(bufMem, &i);

                    /* Add data values */
                    for (section=0; section<map->nSections; section++) {
                        BIOSection *sect = &map->sections[section];

                        overFlow = UploadBufAssignMem(
                            circBuf, sect->nBytes, &tmpHead, &bufMem);
                        if (overFlow) goto EXIT_POINT;
                        intHdr[NBYTES_IDX] += sect->nBytes;

                        CIRCBUF_COPY_DATA(bufMem, sect->start);
                    }
                }
            }
        }

        /* If no systems were active then, do nothing. */
        if (intHdr[NSYS_IDX] == 0) goto EXIT_POINT;

        /*
         * Go back and finish the header: [nBytes msgType nSys tid]
         */
        
        /* ...msgType */
        intHdr[MSG_TYPE_IDX] = UPMSG_DATA_PT;

        /* ...tid */
        intHdr[TID_IDX] = tid;
        
        #ifdef ERASE
        /* reverse order of first 4 bytes to make Raul's ring buffers work on the 9S12...  fw-03-05 */
        /* using alternative approach: checking for data at *(ringBuf.buf + ringBuf.head + 3) */
        {
          
          char_T   dat, *myPtr = (char_T *)&intHdr;
         
          dat          = *(myPtr + 3);
          *(myPtr + 3) = *(myPtr + 0);
          *(myPtr + 0) = dat;
          dat          = *(myPtr + 2);
          *(myPtr + 2) = *(myPtr + 1);
          *(myPtr + 1) = dat;
          
        }
        #endif
          
        CIRCBUF_COPY_DATA(msgStart, intHdr);

        /*
         * Time point successfully added to queue.
         */
        circBuf->head  = tmpHead;
        circBuf->empty = FALSE;

        if (preTrig) {
            trigInfo->preTrig.count++;
        }
    }

EXIT_POINT:
    if (!preTrig) {
        if (overFlow) {
            trigInfo->overFlow = TRUE;
            trigInfo->state    = TRIGGER_TERMINATING;
        }
#ifdef VXWORKS
        else if (trigInfo->state == TRIGGER_FIRED) {
            /* allow upload server to run - if data needs to be uploaded */
            semGive(uploadSem);
        }
#endif
    } 
} /* end UploadBufAddTimePoint */


/* Function ====================================================================
 * Send termination message for data data logging event on the first available
 * buffer.
 */
PRIVATE void UploadBufAddTerminator(void)
{
    int32_T     msg[2];
    int_T       tid;
    CircularBuf *circBuf     = NULL;
    const int_T NBYTES_IDX   = 0;
    const int_T MSG_TYPE_IDX = 1;

    /*
     * Find a buffer to use.
     */
    for (tid=0; tid<NUMST; tid++) {
        circBuf = &uploadInfo.circBufs[tid];
        if (circBuf->bufSize > 0) break;
    }

#if 0
#ifdef VERBOSE
    printf("\nSending data log termination flag on tid: %d\n", tid);
#endif
#endif

    msg[NBYTES_IDX] = (2*sizeof(int32_T));

    if (uploadInfo.trigInfo.holdOff == TRIGMODE_ONESHOT) {
        msg[MSG_TYPE_IDX] = UPMSG_TERMINATE_LOG_SESSION;
    } else {
        msg[MSG_TYPE_IDX] = UPMSG_TERMINATE_LOG_EVENT;
    }
    
    /* reset this buffer */
    circBuf->head = circBuf->buf;
    circBuf->tail = circBuf->buf;

    (void)memcpy(circBuf->head, msg, (uint16_T)msg[NBYTES_IDX]);
    circBuf->head += msg[NBYTES_IDX];

    circBuf->empty   = FALSE;
    circBuf->newTail = NULL;
} /* end UploadBufAddTerminator */


/* Function ====================================================================
 * Called at the base rate, controls the state of data logging including:
 *   - monitoring the trigger signal for a trigger event
 *   - managing transition of most trigger states
 *      o a seperate function (UploadCheckEndTrigger manages the duration
 *        count and the transition from fired to terminating at the end
 *        of the data collection event).
 *
 * NOTE:
 *  o This function should be called after mdlOutputs for the base rate
 */
PUBLIC void UploadCheckTrigger(void)
{
    TriggerInfo *trigInfo = &uploadInfo.trigInfo;

    if (trigInfo->state == TRIGGER_UNARMED) return;

    if (trigInfo->state == TRIGGER_HOLDING_OFF) {
        if (trigInfo->count++ == trigInfo->holdOff) {
            UploadArmTrigger();
        } else {
            return;
        }
    }

    /*
     * Transitions from the TRIGGER_ARMED_STATE to the TRIGGER_DELAYED
     * state or to the TRIGGER_FIRED_STATE are checked for and realized
     * within the task (tid) associated with the trigger signal.
     * See UploadBufAddTimePoint().
     */ 
    
    /*
     * Look for transitions from the TRIGGER_DELAYED state.  The TRIGGER_FIRED
     * state always follows the TRIGGER_DELAYED state.
     *
     * NOTE: the trigInfo count field is first used to count the trigger delay
     *       and then used to count the trigger duration
     */
    if (trigInfo->state == TRIGGER_DELAYED) {
        if (trigInfo->count++ >= trigInfo->delay) {
            trigInfo->count = (uint_T)trigInfo->preTrig.count; /* 0 unless pretrig */
            trigInfo->state = TRIGGER_FIRED;
            if (trigInfo->preTrig.duration > 0) {
                trigInfo->preTrig.checkUnderFlow = TRUE; /* xxx ? */
            }
#ifdef VERBOSE
            printf("\nTrigger fired!\n");
#endif
        }
    }
} /* end UploadCheckTrigger */


/* Function ====================================================================
 * Called at the base rate, controls the state of data logging wrt
 *  o incrementing the duration count
 *  o managing the transition to the trigger terminating state
 *
 * NOTES:
 *  o Call this function at the very end of a step.
 *  o Also see UploadCheckTrigger()
 */
PUBLIC void UploadCheckEndTrigger(void)
{
    TriggerInfo *trigInfo = &uploadInfo.trigInfo;

    if (trigInfo->state == TRIGGER_UNARMED) return;

    /*
     * Increment duration count and terminate the data logging event if
     * the duration has been met.
     */
    if (trigInfo->state == TRIGGER_FIRED) {
        trigInfo->count++;
        if (trigInfo->count == trigInfo->duration) {
            trigInfo->state = TRIGGER_TERMINATING;
        }
    }

#ifdef VXWORKS
    if (trigInfo->state == TRIGGER_TERMINATING) {
        /* Let upload server run to ensure that term msg is sent to host. */
        semGive(uploadSem);
    }
#endif
} /* end UploadCheckEndTrigger */


/* Function =======================================================================
 * Search through the upload buffers and fill out the internal copy of the
 * buffer list.  It contains a list of all buffer memory (1 entry per non-empty
 * tid buffer) that needs to be sent to the host.  Fill out the fields of the
 * specified ExtBufMemList (passed in by ext_svr) to provide public, read-only
 * access.
 */
PRIVATE void SetExtBufListFields(ExtBufMemList *extBufList)
{
    int_T       tid;
    BufMemList  *bufList  = &uploadInfo.bufMemList;

    bufList->nActiveBufs = 0;

    for (tid=0; tid<NUMST; tid++) {
        CircularBuf *circBuf = &uploadInfo.circBufs[tid];

        if (!circBuf->empty) {
            BufMem  *bufMem;
            char_T  *head   = circBuf->head;
            char_T  *tail   = circBuf->tail;
            int_T   size    = circBuf->bufSize;

            /* Validate that head/tail ptrs are within allocated range. */
            assert((head >= circBuf->buf) && (tail >= circBuf->buf));
            assert((head < circBuf->buf + circBuf->bufSize) &&
                   (tail < circBuf->buf + circBuf->bufSize));

            bufMem = &bufList->bufs[bufList->nActiveBufs];
            bufList->tids[bufList->nActiveBufs] = tid;
            assert(bufList->nActiveBufs < bufList->maxBufs);
            bufList->nActiveBufs++;

            bufMem->section1 = tail;
            circBuf->newTail = head;

            if (head > tail) {
                /* not wrapped - only one section required */
                bufMem->nBytes1  = head - tail;

                bufMem->nBytes2  = 0;
                bufMem->section2 = NULL;
            } else {
                /* wrapped - 2 sections required */
                bufMem->nBytes1 = circBuf->buf + size - tail;

                bufMem->nBytes2  = head - circBuf->buf;
                bufMem->section2 = circBuf->buf;
            }
        }
    }

    /*
     * Provide ext_svr with readonly access to the bufMemList.
     */
    extBufList->nActiveBufs = bufList->nActiveBufs;
    extBufList->bufs        = (const BufMem *)bufList->bufs;
    extBufList->tids        = (const int_T *)bufList->tids;
} /* end SetExtBufListFields */


/* Function =======================================================================
 * Set the internal copy of the buffer list to "empty" & fill out the fields of the
 * specified ExtBufMemList (passed in by ext_svr) to provide public, read only
 * access.
 */
PRIVATE void SetExtBufListFieldsForEmptyList(ExtBufMemList *extBufList)
{
    BufMemList *bufList  = &uploadInfo.bufMemList;

    bufList->nActiveBufs = 0;

    extBufList->nActiveBufs = bufList->nActiveBufs;
    extBufList->bufs        = (const BufMem *)NULL;
} /* end SetExtBufListFieldsForEmptyList */


/* Function ====================================================================
 * Called by ext_svr (background task), this function checks all buffers for
 * data and returns a list of buffer memory to be sent to the host.
 */
PUBLIC void UploadBufGetData(ExtBufMemList *extBufList)
{
    TriggerInfo *trigInfo = &uploadInfo.trigInfo;
 
    if ((trigInfo->state == TRIGGER_FIRED) ||
        (trigInfo->state == TRIGGER_TERMINATING)) {

        SetExtBufListFields(extBufList);

        /*
         * If all bufs are empty and we are terminating then we're now done!
         */
        if ((extBufList->nActiveBufs == 0) &&
            (trigInfo->state == TRIGGER_TERMINATING)) {
            
            trigInfo->state = TRIGGER_SENDING_TERM_MSG;

            /*
             * Send the final termination message.
             */
            UploadBufAddTerminator();

            /* Now we should find 1 buffer with data. */
            SetExtBufListFields(extBufList);
            assert(extBufList->nActiveBufs == 1);

            /*
             * This should really be a message sent up to the host. xxx
             */
#ifdef VERBOSE
            if (trigInfo->overFlow) {
                printf("\n**OVERFLOW OCCURRED: count = %d**\n",
                    uploadInfo.trigInfo.count);
            }
#endif
        }
    } else {
        SetExtBufListFieldsForEmptyList(extBufList);
    }
} /* end UploadBufGetData */


/* Function ====================================================================
 * Called by ext_svr (rt_ExtModeShutdown), this function checks all buffers for
 * data and returns true if any data is ready to be uploaded, false otherwise.
 */
PUBLIC boolean_T IsAnyDataReadyForUpload(void)
{
    ExtBufMemList extBufList;
    boolean_T     upload      = false;
    TriggerInfo   *trigInfo   = &uploadInfo.trigInfo;
 
    if ((trigInfo->state == TRIGGER_FIRED) ||
        (trigInfo->state == TRIGGER_TERMINATING)) {

        SetExtBufListFields(&extBufList);

        upload = (extBufList.nActiveBufs != 0);
    }

    return upload;
}


/* [EOF] updown.c */

⌨️ 快捷键说明

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