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

📄 ext_svr_transport.c

📁 simulink real-time workshop for dragon12 development board from
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * Copyright 1994-2002 The MathWorks, Inc.
 *
 * File: ext_svr_transport.c     $Revision: 1.11 $
 *
 * Abstract:
 *  Target-side, transport-dependent external mode functions and defs.  This    
 *  example file implements host/target communication using TCPIP.  To
 *  implement other transport mechanisms, modify the functions in the
 *  'Visible Functions' section of this file.
 *
 * Functionality supplied by this module includes:
 *
 *      o definition of user data
 *      o is host message pending
 *      o get bytes from host message line
 *      o set bytes on host message line
 *      o set bytes on data upload line
 *      o create user data
 *      o destroy user data
 *      o initialize external mode
 *
 * The files relating to target-side external mode are:
 *  xx_main.c
 *      The main program harness for the generated code.  There is a different
 *      main.c for each target (i.e., grt_main.c for grt, rt_main.c for
 *      VXWORKS, etc).  This program controls the execution of the model.
 *      When compiled for external mode, this program contains the
 *      external mode "instrumentation" (i.e., function calls) into External
 *      Mode to enable data uploading and downloading).
 *
 *      [THIS FILE SHOULD NOT NEED TO BE MODIFIED FOR DIFFERENT TRANSPORT
 *       MECHANISMS] 
 *
 *  ext_svr.c
 *      The server for external mode.  This file is the interface between the
 *      model and external mode and essentially contains the boilerplate
 *      code for external mode.  It generally contains:
 *          o transport-independent functions (wrappers) for external 
 *            communication
 *          o function dispatch for some of the more involved external mode
 *            tasks (i.e., dispatch for setting params, etc).
 *      The code is transport-independent (i.e., should not have to change
 *      whether using sockets, shared memory, etc).  Note that updown.c
 *      is the module that takes care of most of the detailed, dirty work
 *      such as decoding the set param message and installing the new
 *      parameter values into the parameter struct (rtP).
 *
 *      [THIS FILE SHOULD NOT NEED TO BE MODIFIED FOR DIFFERENT TRANSPORT
 *       MECHANISMS] 
 *
 *  ext_svr_transport.c
 *      Transport-dependent external mode code (e.g., set bytes on host, get
 *      bytes from host, etc).
 *
 *      [THIS FILE NEEDS TO BE MODIFIED TO IMPLEMENT VARIOUS DATA TRANSPORT
 *       MECHANISMS]
 *
 *  ext_ext_transport_share.h
 *      Definitions that are specific to the implemented transport mechanism
 *      and that are required on both he host and the target.
 *
 *      [THIS FILE NEEDS TO BE MODIFIED TO IMPLEMENT VARIOUS DATA TRANSPORT
 *       MECHANISMS]
 *
 *  updown.c
 *      Transport-independent guts of external mode.  Most direct interaction
 *      with target memory occurs in this file.  For example:
 *          o decode set param message & install new param values into
 *            parameter array
 *          o Add data to upload buffers.
 *          o Monitor triggers and change trigger state.
 *          o and on, and on, and on....
 *
 *      [THIS FILE SHOULD NOT NEED TO BE MODIFIED FOR DIFFERENT TRANSPORT
 *       MECHANISMS] 
 */


/*
 * Explanation of the EXT_BLOCKING:
 *
 * Depending on the implementation of the main program (e.g., grt_main.c,
 * rt_main.c), the EXT_BLOCKING flag must be set to either 0 or 1.  Let's
 * look at two examples:
 *
 *   grt_main.c (grt):
 *   grt_main is a real time template that essentially runs a simulation - in
 *   non-real-time - in a single thread.  As seen in grt, the calls to the
 *   upload & msg servers are "in the loop".  If any function related to
 *   external mode were to block, the real time code, would be prevented from
 *   running.  In this case, we prevent blocking, and poll instead.
 *
 *  rt_main.c (tornado/vxworks)
 *  rt_main.c is a full blown, real-time, multi-tasking target.  The
 *  upload and msg servers are called via background (low priority) tasks.
 *  In this case, it is o.k. for the transport function to block as the blocked
 *  tasks will simply be pre-empted in order to enable the model to run.  It
 *  is desirable to block instead of to poll to free up the cpu for any other
 *  potential work.
 */


/* modifications: (FW-02-03)
 *
 * (1)  added header file <math.h>  (needed in ExtInit())
 * (2)  added target specific header files
 * (3)  added header files simstruc_types.h and updown.h, needed to access 'ExtBufMemList'
 * (4)  removed definition of the structure ExtUserData -> now in ext_svr_transport.h
 * (5)  deleted unused conditional code sections (VXWORKS, UNIX, IBM_RS, GLNX86, SUN4, BLOCKING)
 * (6)  added header file "updown.h" (declaration of ExtBufMemList, used in put_data_buf() )
 * (7)  modified definition of structure ExtUserData
 * (8)  added section DEFINES
 * (9)  added section GLOBAL VARIABLES
 * (10) removed PRIVATE function PassiveSocketShutdown() and replaced it with 
 *      the  handler serial_RX_irq() as well as the low-level access functions
 *      get_data_sp() and put_data_sp()
 * (11) added VISIBLE functions init_ringBuf() and put_data_buffer()
 * (12) replaced VISIBLE function ExtInit()
 * (13) removed unused VISIBLE functions: ExtOpenConnection(), ExtCloseConnection(),
 *      ExtShutDown(), ExtProcessArgs() and ExtUserDataSetPort()
 * (14) replaced VISIBLE functions ExtGetHostMsg(), ExtSetHostMsg() and ExtSetHostData()
 * (15) added new VISIBLE function ExtSetHostUserData()
 * (16) removed contents of (now non-functional) VISIBLE function ExtModeSleep()
 *
 */


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>					/* ceil */

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


#include <mc9s12dp256.h>		      /* port definitions etc. */
#include "buffer.h"	            	/* (ring)buffer macros */
#include "mc_signal.h"    			/* blinky, SCIx_Init(), etc. */

#include "tmwtypes.h"
#include "updown_util.h"
#include "ext_share.h"
#include "ext_svr_transport.h"		/* ExtUserData */

#include "simstruc_types.h"			  /* RTWExtModeInfo, needed in updown.h */
#include "updown.h"					      /* ExtBufMemList */




/*=============*
 * Global data *
 *=============*/

/* size of the reception ring buffer */
#define RBUFSIZE	1024						// increase this value for block diagrams with many parameters!!
           												// e. g.: f14.c -> 980 bytes, shower.c -> 6604
//#define RBUFSIZE	8192					// e. g.: shower.c

/* serial communication ring buffer (reception) -- this buffer can be static */
static struct BufferTyp	*RecBufPtr = NULL;


/* RTW ring buffer */
ringBuf_tag ringBuf;

/* controls the buffering of data, defined in ext_svr.c */
extern boolean_T volatile bufenable;



/***************** PRIVATE FUNCTIONS ******************************************
 *                                                                            *
 *  THE FOLLOWING FUNCTIONS ARE SPECIFIC TO THE TCPIP EXAMPLE OF HOST-        *
 *  TARGET COMMUNICATION.  SEE THE 'VISIBLE FUNCTIONS' SECTION FOR THE        *
 *  GENERIC SET OF FUNCTIONS THAT ARE CALLED BY EXTERNAL MODE.  TO IMPLEMENT  *
 *  A CUSTOM VERSION OF EXTERNAL MODE  (E.G. SHARED MEMORY, SERIAL CABLE, ETC)*
 *  THE BODIES OF THE FUNCTIONS IN THE 'VISIBLE FUNCTIONS' SECTION MUST BE    *
 *  REPLACED.                                                                 *
 *                                                                            *
 ******************************************************************************/


/* ==============================================================================
 * Function: SCI[0/1]_RX_ isr ===================================================
 * Abstract:
 *  This is the Interrupt Serial Routine for SCI[0/1] - services with reception,
 *  data is stored in the reception ring buffer
 ============================================================================== */


/* make sure we're using the right port... */
#if SCI0_COMMS == 1


#pragma CODE_SEG __NEAR_SEG NON_BANKED /* Interrupt section for this module. Placement will be in NON_BANKED area. */

/* MATLAB communication ISR */
__interrupt void SCI0_RX_isr(void) {

char_T inVal;

	// set sertime_pin high (timing -> scope)
	#ifdef TIMING
	setSerTiPin;
	#endif

  /* determine cause of interrupt */
  if((SCI0SR1 & RDRF_mask) != 0) {
    
    /* Receive Data Register Full -> fetch character and store */
  	inVal = SCI0DRL;    						/* get value from register SCI0DRL */
	  InBuffer(inVal, RecBufPtr);			/* write character to the (ring) buffer */

  }  
  
	// reset sertime_pin (timing -> scope)
	#ifdef TIMING
	clrSerTiPin;
	#endif

} /* SCI0_RX_isr */


#else /* SCI0_COMMS != 1 -> SCI1_COMMS == 1 (must be, otherwise this file would not have been included) */


#pragma CODE_SEG __NEAR_SEG NON_BANKED /* Interrupt section for this module. Placement will be in NON_BANKED area. */


/* MATLAB communication ISR */
__interrupt void SCI1_RX_isr(void) {

char_T inVal;

	// set sertime_pin high (timing -> scope)
	#ifdef TIMING
	setSerTiPin;
	#endif

  /* determine cause of interrupt */
  if((SCI1SR1 & RDRF_mask) != 0) {
    
    /* Receive Data Register Full -> fetch character and store */
  	inVal = SCI1DRL;    						/* get value from register SCI1DRL */
	  InBuffer(inVal, RecBufPtr);			/* write character to the (ring) buffer */

  }  
  
	// reset sertime_pin (timing -> scope)
	#ifdef TIMING
	clrSerTiPin;
	#endif

} /* SCI1_RX_isr */

#endif /* SCI1_COMMS == 1 */


#pragma CODE_SEG DEFAULT



/* Function: get_data_sp ====================================================
 * Abstract:
 *  Gets data from the reception buffer. Data in this buffer has been put by 
 *  by the ISR of the serial port. Therefore this function never acceses the 
 *  RS232 serial port.
 */
static int_T get_data_sp(
    const int_T  nBytesToGet,
    int_T        *nBytesGot, /* out */
    char_T       *dst)       /* out */
{
char_T *bufPtr		= dst;
uint_T  i			= 0;
uint_T  attempts	= 0;
uint_T  nBuf;

	

	/* determine the amount of data currently stored in the reception buffer */
	nBuf = Buffercounter(RecBufPtr);

	if(nBuf > 0) {
	
	  /* something in the buffer */

		/* start timeout timer (RTI) */
    //RTI_counter = 0;   /* reset RTI counter */
    //CRGFLG = 0x80;     /* clear RTIF flag (used as timeout flag) */
    //RTICTL = 0x3F;     /* start RTI, period = 262.14 ms (max) */

		while (nBuf < nBytesToGet) {

			/* on timeout -> exit from the while loop */
			//if(RTI_counter == TIMEOUT) break;

			/* check if the buffer counter has increased */
			if(Buffercounter(RecBufPtr) > nBuf) {
				
				/* new data has arrived -> update variable 'nBuf' and reset timer */
				nBuf = Buffercounter(RecBufPtr);
        //RTI_counter = 0;     /* reset RTI_counter */
        //CRGFLG = 0x80;       /* clear RTIF flag (used as timeout flag) */
        //RTICTL = 0x3F;       /* (re-)start RTI, period = 262.14 ms (max) */

			}

		}

		/* only return data if no timeout has occurred */
		//if(RTI_counter != TIMEOUT) {
		
			/* 'nBytesToGet' of data can now be read from the reception ring buffer */
			for (i=0; i<nBytesToGet; i++) {
				OutBuffer(RecBufPtr, *bufPtr++, char_T);
			}

			/* correct the information on the number of bytes currently stored in RecBuf */
			nBuf -= nBytesToGet;

		//}
			
		/* stop timer */
    //RTICTL = 0;

	} /* nBuf > 0 */

	
	/* return actual number of bytes which have been read from the reception buffer (0 or nBytesToGet) */
	*nBytesGot = i;

	/* also return the actual number of bytes in the buffer */
	return nBuf;

} /* End of get_data_sp  */




/* Function: put_data_sp ====================================================
 * Abstract:
 *  Sends nbyte via the serial port ('S0')
 */
static void put_data_sp(    
    const uint_T nBytesToSet,
    const char_T *src,
    int_T        *nBytesSet) 
{
uint_T    i;

	for (i = 0; i < nBytesToSet; i++) {
	
	  /* make sure we're using the right port... */
	  #if SCI0_COMMS == 1

    while((SCI0SR1 & TDRE_mask) == 0){};  // wait until the end of a possibly ongoing transmission
    SCI0DRL = src[i];                     // send character
    
    #else /* SCI1_COMMS == 1 */
    
    while((SCI1SR1 & TDRE_mask) == 0){};  // wait until the end of a possibly ongoing transmission
    SCI1DRL = src[i];                     // send character
    
    #endif
    

	}
	*nBytesSet = i;

}  /* end of put_data_sp */



/***************** VISIBLE FUNCTIONS ******************************************
 *                                                                            *
 *  YOU MUST REPLACE EACH OF THE FOLLOWING FUNCTIONS TO IMPLEMENT A CUSTOM    *
 *  VERSION OF EXTERNAL MODE.                                                 *
 *                                                                            *
 *  ALSO SEE <MATLABROOT>/RTW/C/SRC/EXT_TRANSPORT_SHARE.H FOR ADDING DEFS FOR *
 *  YOUR CUSTOM IMPLEMENTATION THAT ARE REQUIRED BY BOTH THE HOST AND THE     *
 *  TARGET.                                                                   *
 *                                                                            *
 ******************************************************************************/


/* Function: init_ringBuf ==================================================
 * Abstract:
 *  Initialises the ring buffer.
 */
PUBLIC void init_ringBuf(void) {

	ringBuf.head = 0;
	ringBuf.tail = 0;
	ringBuf.size = RB_SIZE;
	ringBuf.nRecords = 0;
	(void)memset(&ringBuf.buf, 0, (uint16_T)ringBuf.size);

} /* init_ringBuf */


/* Function: put_data_buffer ===============================================
 * Abstract:
 *  Put model signals into general buffer
 */
PUBLIC void put_data_buffer(void) {

int_T         i;
ExtBufMemList upList;


    /* only allow data logging if 'bufenable' (formerly called 'connected') is TRUE */
    if (!bufenable) return; 
 
    UploadBufGetData(&upList);
    while(upList.nActiveBufs > 0) { 

      //PORTB |= 0x02;					/* LED2 on */
  
      for (i=0; i<upList.nActiveBufs; i++) {
         
         const BufMem *bufMem = &upList.bufs[i];

			  /* Check whether head has reached the end of the buffer. If so mark the byte with '0' so *
			   * that ext_svr knows which was the last packet sent, and set the head to offset zero.    */
			  if ((ringBuf.head + bufMem->nBytes1 + bufMem->nBytes2 + 3) > ringBuf.size) {
				  //*(ringBuf.buf + ringBuf.head) = 0;
				  *(ringBuf.buf + ringBuf.head + 3) = 0;   /* '+3' to account for byte inversion... fw-03-05 */
				  ringBuf.head = 0;
				  /* If tail = 0 the buffer is full. This case is not detected in the condiction below */
				  if (ringBuf.tail == 0) {
					  //abort_LED(43);
					  //UploadCancelLogging();
					  //break;
				  } 
			  }
			  /* Check whether the buffer is full.*/ 
			  /* 9 comes from 8 + 1, where 8 are the bytes for the TRIGGER_TERMINATING message */
			  if ((((signed) (ringBuf.head - ringBuf.tail)) < 0) && \
				  ((ringBuf.head + bufMem->nBytes1 + bufMem->nBytes2 + 3 + 9) > ringBuf.tail )) {
				
				  /* buffer wrapped (head < tail) and not enough space to store next telegram */
				  /* -> do nothing... tail's going to move, then there should be enough space... */
				  /* fw-03-05 */
				  //abort_LED(77);

⌨️ 快捷键说明

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