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

📄 ext_svr_serial_transport.c

📁 RT9S12 target document
💻 C
字号:
/*
 * Copyright 1994-2003 The MathWorks, Inc.
 *
 * File: ext_svr_transport.c     $Revision: 1.1.6.5 $
 *
 * Abstract:
 *  Target-side, transport-dependent external mode functions and defs.  This    
 *  example file implements host/target communication using serial
 *  communication.  To implement a custom transport layer, use the template
 *  in ext_svr_custom_transport.c.
 *
 * Functionality supplied by this module includes:
 *
 *      o definition of user data
 *      o is host packet pending
 *      o get bytes from host comm line
 *      o set bytes on host comm line
 *      o close connection with host
 *      o open connection with host
 *      o create user data
 *      o destroy user data
 *      o process command line arguments
 *      o initialize external mode
 *      o terminate external mode
 */


/*
 * 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 & pkt 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 pkt 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.
 */

/* 
 * Adapted for rtmc9s12-Target, fw-09-7
 */


/***************** TRANSPORT-INDEPENDENT INCLUDES *****************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "updown_util.h"
#include "tmwtypes.h"
#include "ext_types.h"
#include "ext_share.h"

/***************** TRANSPORT-DEPENDENT INCLUDES *******************************/

/*
 *  grt - single thread (See "Explanation of the EXT_BLOCKING" above)
 */
# define EXT_BLOCKING (0)

#include "ext_serial_port.h"
#include "ext_serial_pkt.h"
#include "ext_serial_utils.c"

#include "mc_signal.h"                   /* abort_LED */

/* System macros (EXT_MODE, etc.) -- generated by 'gen_cpp_req_defines_h.tlc' */
#include "cpp_req_defines.h"
#include "debugMsgs.h"            /* macros PRINT_DEBUG_MSG_LVL1 to PRINT_DEBUG_MSG_LVL1,  fw-06-07 */



/***************** DEFINE USER DATA HERE **************************************/

typedef struct ExtUserData_tag {

      boolean_T      waitForStartPkt;
      int16_T        port;
      int32_T        baud;
      ExtSerialPort  *portDev;

} ExtUserData;


/***************** PRIVATE FUNCTIONS ******************************************/


/***************** VISIBLE FUNCTIONS ******************************************/

/* Function: ExtInit ===========================================================
 * Abstract:
 *  Called once at program startup to do any initialization related to external
 *  mode.  For the serial example, there is very little to do.  EXT_NO_ERROR is
 *  returned on success, EXT_ERROR on failure.
 *
 * NOTES:
 *  o This function should not block.
 */
boolean_T ExtInit(ExtUserData *UD) {

   boolean_T   error=EXT_NO_ERROR;

   UD->portDev=ExtOpenSerialConnection(UD->port, UD->baud);
   if(UD->portDev==NULL) {

      abort_LED(40);

      //fprintf(stderr,"ExtOpenSerialConnection() call failed.\n");
      error=EXT_ERROR;
      goto EXIT_POINT;

   }

   EXIT_POINT:return(error);

} /* end ExtInit */


/* Function: ExtOpenConnection =================================================
 * Abstract:
 *  Called when the target is not currently connected to the host, this 
 *  function attempts to open the connection.  In some cases, this may be
 *  trivial (e.g., shared memory, serial cable).  Whether or not the connection
 *  was made is returned by reference via the 'outConnectionMade' arg.
 *
 *  Returns EXT_NO_ERROR on success, EXT_ERROR otherwise.
 *
 * NOTES:
 *  o blocks if EXT_BLOCKING == 1, poll for pending connections otherwise.  When
 *    polling, there may be no open requests pending.  In this case, this 
 *    function returns without making the connection.  This is NOT an error.
 */
boolean_T ExtOpenConnection(ExtUserData *UD, boolean_T *outConnectionMade) {

   // local function name... debugging only
   #if DEBUG_MSG_LVL > 0
   const char  *funct_name="ExtOpenConnection";
   #endif

   PRINT_DEBUG_MSG_LVL3("IN\n\r");

   *outConnectionMade=(UD->portDev==NULL)?false:true;
   //PRINT_DEBUG_MSG_LVL1("connected = ");
   //PRINT_DEBUG_MSG_LVL1_UDec((uint16_T)(*outConnectionMade));
   //PRINT_DEBUG_MSG_NL1;

   PRINT_DEBUG_MSG_LVL3("OUT, error status: 0\n\r");

   return EXT_NO_ERROR;

} /* end ExtOpenConnection */


/* Function: ExtCloseConnection ================================================
 * Abstract:
 *  Called when the target needs to disconnect from the host (disconnect
 *  procedure is initiated by the host).
 */
void ExtCloseConnection(ExtUserData *UD) {

   ExtClearSerialConnection();

} /* end ExtCloseConnection */


/* Function: ExtShutDown =======================================================
 * Abstract:
 *  Called when the target program is terminating.
 */
void ExtShutDown(ExtUserData *UD) {

   if(UD->portDev!=NULL) {

      if(ExtCloseSerialConnection(UD->portDev)!=EXT_NO_ERROR) {

         abort_LED(41);
         //fprintf(stderr, "ExtCloseSerialConnection() returned an error.\n");
      }
      UD->portDev=NULL;

   }

} /* end ExtShutDown */


/* Function: ExtWaitForStartPktFromHost ========================================
 * Abstract:
 *  Return true if the model should not start executing until told to do so
 *  by the host.
 */
boolean_T ExtWaitForStartPktFromHost(ExtUserData *UD) {

   return(UD->waitForStartPkt);

} /* end ExtWaitForStartPktFromHost */


/* Function: ExtSetWaitForStartPktFromHost =====================================
 * Abstract:
 *  Set the waitForStartPkt flag.
 *  fw-06-07
 */
void ExtSetWaitForStartPktFromHost(ExtUserData *UD, boolean_T state) {

   UD->waitForStartPkt=state;

} /* end ExtSetWaitForStartPktFromHost */


/* Function: ExtUserDataCreate =================================================
 * Abstract:
 *  Create the user data.
 */
ExtUserData * ExtUserDataCreate(void) {

   static ExtUserData   UD;

   UD.waitForStartPkt=TRUE;
   #if SCI0_COMMS == MCOM
   UD.port=0;           /* SCI0 */
   #else
   UD.port=1;           /* SCI1 */
   #endif
   UD.baud=BAUDRATE;
   UD.portDev=NULL;

   return &UD;

} /* end ExtUserDataCreate */


/* Function: ExtUserDataDestroy ================================================
 * Abstract:
 *  Destroy the user data.
 */
void ExtUserDataDestroy(ExtUserData *UD) {

} /* end ExtUserDataDestroy */


/* Function: ExtUserDataSetPort ================================================
 * Abstract:
 *  Set the port in the external mode user data structure.
 */
#ifdef VXWORKS
void ExtUserDataSetPort(ExtUserData *UD, const int_T port) {

   UD->port=port;

} /* end ExtUserDataSetPort */
#endif


/* Function: ExtGetHostPkt =====================================================
 * Abstract:
 *  Attempts to get the specified number of bytes from the comm line.  The number
 *  of bytes read is returned via the 'nBytesGot' parameter.  EXT_NO_ERROR is
 *  returned on success, EXT_ERROR is returned on failure.
 *
 * NOTES:
 *  o it is not an error for 'nBytesGot' to be returned as 0
 *  o blocks if no data available and EXT_BLOCKING == 1, polls otherwise
 *  o not guaranteed to read total requested number of bytes
 */
boolean_T ExtGetHostPkt(const ExtUserData *UD, const int nBytesToGet, int *nBytesGot, /* out */
    char *dst)       /* out */ {

   boolean_T   error=EXT_NO_ERROR;

   // local function name... debugging only
   #if DEBUG_MSG_LVL > 0
   const char  *funct_name="ExtGetHostPkt";
   #endif

   PRINT_DEBUG_MSG_LVL3("IN\n\r");

   #if EXT_BLOCKING == 0
   /* Prevent blocking - poll */
   {
      boolean_T   pending;

      /* !! modified definition of ExtPktPending (ext_serial_utils.c) to pass on info about nBytesToGet !! */
      /* fw-07-07 */
      error=ExtPktPending(UD->portDev, &pending, nBytesToGet);
      if(error!=EXT_NO_ERROR) {

         abort_LED(42);

         goto EXIT_POINT;

      }

      if(!pending) {

         *nBytesGot=0;
         goto EXIT_POINT;

      }
   }
   #endif

   error=ExtGetPkt(UD->portDev, dst, nBytesToGet, nBytesGot);
   if(error!=EXT_NO_ERROR) {

      abort_LED(43);

      goto EXIT_POINT;

   }

EXIT_POINT:

   PRINT_DEBUG_MSG_LVL3("OUT, error status: ");
   PRINT_DEBUG_MSG_LVL3_UDec(error);
   PRINT_DEBUG_MSG_NL3;

   return error;

} /* end ExtGetHostPkt */


/* Function: ExtSetHostPkt =====================================================
 * Abstract:
 *  Sets (sends) the specified number of bytes on the comm line.  As long as
 *  an error does not occur, this function is guaranteed to set the requested
 *  number of bytes.  The number of bytes set is returned via the 'nBytesSet'
 *  parameter.  EXT_NO_ERROR is returned on success, EXT_ERROR is returned on
 *  failure.
 *
 * NOTES:
 *  o it is always o.k. for this function to block if no room is available
 */
boolean_T ExtSetHostPkt(const ExtUserData *UD, const int         nBytesToSet, const char *src, int *nBytesSet) /* out */ {

   boolean_T   error=EXT_NO_ERROR;

   // local function name... debugging only
   #if DEBUG_MSG_LVL > 0
   const char  *funct_name="ExtSetHostPkt";
   #endif

   PRINT_DEBUG_MSG_LVL3("IN\n\r");

   error=ExtSetPktWithACK(UD->portDev, (char*)src, (int)nBytesToSet, EXTMODE_PACKET);
   if(error!=EXT_NO_ERROR) {

      abort_LED(44);

      goto EXIT_POINT;

   }

   *nBytesSet=nBytesToSet;

   EXIT_POINT:PRINT_DEBUG_MSG_LVL3("OUT, error status: ");
   PRINT_DEBUG_MSG_LVL3_UDec(error);
   PRINT_DEBUG_MSG_NL3;

   return error;

} /* end ExtSetHostPkt */


/* Function: ExtModeSleep ======================================================
 * Abstract:
 *  Called by grt_main, ert_main, and grt_malloc_main to "pause" (hopefully in
 *  a way that does not hog the CPU) execution.  
 *
 *  In this TCPIP example, we simply do a select with an appropriate time
 *  out on the sFd socket.  The process will pause for the specified time,
 *  or until data (or a request connect) arrives on sFd.
 *
 */
#ifndef VXWORKS
void ExtModeSleep(const ExtUserData *UD, const long        sec, /* # of secs to wait        */
    const long        usec) /* # of micros secs to wait */ {

   /* How do we do this for for serial connection? */

   /* Don't do this on a bareboard system. This is for when ext mode is in
    * a separate task. Then what? */

} /* end ExtModeSleep */
#endif


/* Function: ExtForceDisconnect ================================================
 * Abstract:
 *  Called by rt_UploadServerWork() in ext_svr.c when there is an extmode
 *  communication error (e.g. a tcp/ip disconnection between the host and target
 *  caused by a cable problem or extremely high network traffic).  In this case,
 *  we want the target to disconnect from the host even if it can't communicate
 *  with the host because we assume that the communication problem caused the
 *  host to disconnect.  This function will perform all steps necessary to
 *  shutdown the communication and leave the target in a state ready to be
 *  reconnected.
 */
void ExtForceDisconnect(ExtUserData *UD) {

   ExtSerialPortDisconnect(UD->portDev);
   UD->portDev=NULL;

}


/* [EOF] ext_svr_serial_transport.c */

⌨️ 快捷键说明

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