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

📄 ext_svr.c

📁 simulink real-time workshop for dragon12 development board from
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * Copyright 1994-2002 The MathWorks, Inc.
 *
 * File: ext_svr.c     $Revision: 1.51 $
 *
 * Abstract:
 *  External mode server interface (TCPIP example).  Provides functions
 *  that get called by main routine (modelname.c):
 *    o ExtParseArgsAndInitUD:  parse args and create UserData
 *    o ExtWaitForStartMsg:     return true if waiting for host to start
 *    o rt_ExtModeInit:         external mode initialization
 *    o rt_ExtModeSleep:        pause the process
 *    o rt_MsgServerWork:       server for setting/getting messages from host
 *    o rt_MsgServer:           server dispatcher - for multi-tasking targets
 *    o rt_UploadServerWork:    server for setting upload data on host
 *    o rt_UploadServer:        server dispatcher - for multi-tasking targets
 *    o rt_ExtModeShutdown:     external mode termination
 *
 *  Paremter downloading and data uploading supported for single and
 *  multi-tasking targets.
 */

/* modifications: (FW-02-03)
 *
 * (1)  deleted unused conditional code sections (VXWORKS, __LCC__, VERBOSE)
 * (2)  added target specific header files
 * (3)  substituted all variables 'connected' by 'bufenable' (readability)
 * (4)  added global control flag TXactive
 * (5)  added global variables ringBuf, user communication variables, telegram macros
 * (6)  replaced all error messages with calls to abort_LED
 * (7)  local functions GetMsgHdr & GetMsg: added acknowledgement control
 * (8)  modified local function DisconnectFromHost (inclusion of flag TXactive, etc.)
 * (9)  modified local function ProcessConnectMsg (msgHdr.size forced to 0, etc.)
 * (10) added local functions ProcessReceiveUserDataMsg() and ProcessSetUserData()
 * (11) removed unused VISIBLE function ProcessArgsAndInitUD()
 * (12) modified VISIBLE function rt_UploadServerWork()
 * (13) modified VISIBLE function rt_ExtModeInit()
 * (14) simplified VISIBLE function rt_MsgServerWork()
 * (15) adapted VISIBLE function rt_ExtModeShutdown()
 *
 */

 
 /*****************
 * Include files *
 *****************/

/*ANSI C headers*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "cpp_req_defines.h"      /* EXT_MODE, etc. -- generated by 'gen_cpp_req_defines_h.tlc' */


/*Real Time Workshop headers*/
#include "tmwtypes.h"
#include "simstruc_types.h"

#include "ext_share.h"
#include "ext_test.h"			/* needed, despite the absence of 'ext_test.c'  -- (FW-02-03) */
#include "ext_svr_transport.h"
#include "updown.h"
#include "updown_util.h"
#include "dt_info.h"

/* microcontroller headers */
#include "mc_signal.h"			/* abort_LED */
#include "buffer.h"				/* ClearBuffer */
#include <mc9s12dp256.h>		      /* port definitions etc. */


/*Uncomment to test 4 byte reals*/
/*#define real_T float*/


/**********************
 * External Variables *
 **********************/

extern int_T           volatile startModel;
extern TargetSimStatus volatile modelStatus;

/********************
 * Global Variables *
 ********************/


/*
 * Flags.
 */
PUBLIC  boolean_T   bufenable       = FALSE; /* (also used in mc_main.c -> PUBLIC) */
PRIVATE boolean_T   commInitialized = FALSE;
PRIVATE boolean_T	  TXactive		    = FALSE; /* set in rt_MsgServerWork upon receipt of an EXT_DATA_UPLD_REQUEST; */

/*
 * Pointer to opaque user data (defined by ext_svr_transport.c).
 */
PRIVATE ExtUserData *extUD          = NULL;

/*
 * Buffer used to receive messages.
 */
PRIVATE int_T msgBufSize = 0;
PRIVATE char  *msgBuf    = NULL;

/*
 * Communication ring buffer
 */
extern ringBuf_tag ringBuf; 

/*
 * User communication  --  via the MATLAB communication port
 */
#include "s0_usertel.h"

// DEFINE global user communication admin variables ( initialised in mc_main->Init_ComVars() )
myUsrBuf	*userTelBuf[MAX_UCOM_CHANNELS];		/* pointer to the data buffer admin structures of all user telegrams */
int_T		 user_txd_queue[MAX_UCOM_CHANNELS];	/* queue of txd channels to be scanned by Process_UserDownload() */
int_T		 num_user_channels_active;			/* number of active user data channels to be serviced */	
int_T		 next_user_channel_index;			/* index of the next channel to be scanned for (txd queue) */

  
/*******************
 * Local Functions *
 *******************/


/* Function: GrowRecvBufIfNeeded ===============================================
 * Abstract:
 *  Allocate or increase the size of buffer for receiving messages from target.
 */
PRIVATE boolean_T GrowRecvBufIfNeeded(const int_T msgSize)
{
    if (msgSize > msgBufSize) {
        if (msgBuf != NULL) free(msgBuf);

        msgBufSize = msgSize;
        msgBuf     = (char *)malloc((uint16_T)msgBufSize);

        if (msgBuf == NULL) return(EXT_ERROR);
    }
    return(EXT_NO_ERROR);
} /* end GrowRecvBufIfNeeded */


/* Function: GetMsgHdr =========================================================
 * Abstract:
 *  Attempts to retrieve a message header from the host.  If a header is in 
 *  fact retrieved, the reference arg, 'hdrAvail' will be returned as true.
 *
 *  EXT_NO_ERROR is returned on success, EXT_ERROR is returned on failure.
 *
 * NOTES:
 *  o It is not necessarily an error for 'hdrAvail' to be returned as false.
 *    It typically means that we were polling for messages and none were
 *    available.
 */
PRIVATE boolean_T GetMsgHdr(MsgHeader *msgHdr, boolean_T *hdrAvail)
{
    int_T     nGot  = 0; /* assume */
    boolean_T error = EXT_NO_ERROR;
    
    /* enable acknowledgement */
	extUD->acknowledgeMsg = TRUE;
	
	/*
     * Read the message header.  Assumed that the entire message
     * header can be read in one shot.
     */
    error = ExtGetHostMsg(extUD,sizeof(MsgHeader),&nGot,(char_T *)msgHdr);
    if (error) goto EXIT_POINT;
    assert((nGot == 0) || (nGot == sizeof(MsgHeader)));

EXIT_POINT:
    *hdrAvail = (boolean_T)(nGot > 0);
    return(error);
} /* end GetMsgHdr */


/* Function: GetMsg ============================================================
 * Abstract:
 *  Receive nBytes from the host.  Return a buffer containing the bytes or
 *  NULL if an error occurs.  Note that the pointer returned is that of the
 *  global msgBuf.  If the buf needs to be grown to accommodate the message,
 *  it is realloc'd.  This function will try to get the requested number
 *  of bytes indefinately - it is assumed that the data is either already there,
 *  or will show up in a "reasonable" amount of time.
 */
PRIVATE const char *GetMsg(const int_T msgSize)
{
    int_T     nGot;
    boolean_T error     = EXT_NO_ERROR;
    int_T     nGotTotal = 0;

    error = GrowRecvBufIfNeeded(msgSize);
    if (error != EXT_NO_ERROR) goto EXIT_POINT;
    
    /* disable acknowledgement */
	extUD->acknowledgeMsg = FALSE;
	
	/* Get the data. */
    while(nGotTotal < msgSize) {
        error = ExtGetHostMsg(extUD,
            msgSize - nGotTotal, &nGot, (char_T *)(msgBuf + nGotTotal));
        if (error) {
			abort_LED(28);
            goto EXIT_POINT;
		}

		nGotTotal += nGot;
    }

    /* re-enable acknowledgement */
	extUD->acknowledgeMsg = TRUE;
	
	/* make dummy call (-> request 0 bytes...) to ExtGetHostMsg to send acknowledgement */
	error = ExtGetHostMsg(extUD, 0, &nGot, (char_T *)msgBuf);
    if (error) {
		abort_LED(28);
	}


EXIT_POINT:
    return((error == EXT_NO_ERROR) ? msgBuf : NULL);
} /* end GetMsg */


/* Forward declaration */
boolean_T rt_UploadServerWork(void);


/* Function: DisconnectFromHost ================================================
 * Abstract:
 *  Disconnect from the host.
 */
PRIVATE void DisconnectFromHost(void)
{
    
	/* flush upload ring buffer */
	ringBuf.head = ringBuf.tail = 0;

	/*
     * Make sure buffers are flushed so that the final points get to
     * host (this is important for the case of the target reaching tfinal
     * while data is uploading is in progress).
     */
	UploadPrepareForFinalFlush();
    
	/* transfer data from the RTW buffer to the upload buffer */
	put_data_buffer();

	/* upload termination telegram: '80005000' */
	TXactive	= TRUE;
	(void)rt_UploadServerWork();
    
    /* disable any further buffering */
	bufenable	= FALSE;

	/* Destroy all data associated with data logging */
	UploadLogInfoTerm();

    /* disable any further buffering */
//	bufenable	= FALSE;

	/* request re-initialisation of the serial interface */
	commInitialized = FALSE;

  /* reset communication (ring) buffer -> all pts are reset to zero, memory is NOT released */
	//ClearBuffer(RecBufPtr);

	//blinky(50000);
	//blinky(50000);
	//blinky(50000);
} /* end DisconnectFromHost */


/* Function: ProcessConnectMsg =================================================
 * Abstract:
 *  Process the EXT_CONNECT message and send response to host.
 */
PRIVATE boolean_T ProcessConnectMsg(RTWExtModeInfo *ei)
{
    int_T                   nSet;
    MsgHeader               msgHdr;
    uint_T                  tmpBufSize;
    uint32_T                *tmpBuf = NULL;
    boolean_T               error   = EXT_NO_ERROR;
    
    const DataTypeTransInfo *dtInfo    = rteiGetModelMappingInfo(ei);
    uint_T                  *dtSizes   = dtGetDataTypeSizes(dtInfo);
    uint_T                  nDataTypes = dtGetNumDataTypes(dtInfo);

    assert(bufenable);
    assert(!comminitialized);

    /*
     * Send the 1st of two EXT_CONNECT_RESPONSE messages to the host. 
     * The message consists purely of the msgHeader.  In this special
     * case the msgSize actually contains the number of bits per byte
     * (not always 8 - see TI compiler for C30 and C40).
     */
    msgHdr.type = (uint32_T)EXT_CONNECT_RESPONSE;

	  /* forced '0'; see ext_comm.c (ExtConnect) for details, (FW-09-02) */
	  msgHdr.size = (uint32_T)0;	/* original: (uint32_T)8; */

    error = ExtSetHostMsg(extUD,sizeof(msgHdr),(char_T *)&msgHdr,&nSet);
    if (error || (nSet != sizeof(msgHdr))) {
        abort_LED(29);
        goto EXIT_POINT;
    }

    /* Send 2nd EXT_CONNECT_RESPONSE message containing the following 
     * fields:
     *
     * CS1 - checksum 1 (uint32_T)
     * CS2 - checksum 2 (uint32_T)
     * CS3 - checksum 3 (uint32_T)
     * CS4 - checksum 4 (uint32_T)
     * 
     * targetStatus  - the status of the target (uint32_T)
     *
     * nDataTypes    - # of data types        (uint32_T)
     * dataTypeSizes - 1 per nDataTypes       (uint32_T[])
     */

    {
        uint_T nMsgEls    = 4 +                        /* checkSums       */
                            1 +                        /* targetStatus    */
                            1 +                        /* nDataTypes      */
                            dtGetNumDataTypes(dtInfo); /* data type sizes */

        tmpBufSize = nMsgEls * sizeof(uint32_T);
        tmpBuf     = (uint32_T *)malloc((size_t)tmpBufSize);
        if (tmpBuf == NULL) {
            error = EXT_ERROR; goto EXIT_POINT;
        }
    }
    
    /* Send message header. */
    msgHdr.type = (uint32_T)EXT_CONNECT_RESPONSE;
    msgHdr.size = tmpBufSize;

    error = ExtSetHostMsg(extUD,sizeof(msgHdr),(char_T *)&msgHdr,&nSet);
    if (error || (nSet != sizeof(msgHdr))) {
        abort_LED(30);
        goto EXIT_POINT;
    }
   
    /* Checksums, target status & SL_DOUBLESize. */
    tmpBuf[0] = rteiGetChecksum0(ei);
    tmpBuf[1] = rteiGetChecksum1(ei);
    tmpBuf[2] = rteiGetChecksum2(ei);
    tmpBuf[3] = rteiGetChecksum3(ei);

    tmpBuf[4] = (uint32_T)modelStatus;

    /* nDataTypes and dataTypeSizes */
    tmpBuf[5] = (uint32_T)nDataTypes;
    (void)memcpy(&tmpBuf[6], dtSizes, (uint16_T)(sizeof(uint32_T)*nDataTypes));


    /* Send the message. */
    error = ExtSetHostMsg(extUD,tmpBufSize,(char_T *)tmpBuf,&nSet);
    if (error || (nSet != tmpBufSize)) {
        abort_LED(31);
        goto EXIT_POINT;
    }

⌨️ 快捷键说明

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