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

📄 ext_serial_utils.c

📁 RT9S12 target document
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
* Copyright 1994-2003 The MathWorks, Inc.
*
* File: ext_serial_utils.c     $Revision: 1.1.6.4 $
*
* Absract:
*  External mode shared data structures and functions used by the external
*  communication, mex link, and generated code.  This file is for definitions
*  related to custom external mode implementations (e.g., tcpip, serial).
*  See ext_share.h for definitions common to all implementations of external
*  mode (ext_share.h should NOT be modified).
*/

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


/***************** TRANSPORT-DEPENDENT DEFS AND INCLUDES **********************/

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

#include "tmwtypes.h"
#include "ext_share.h"
#include "simstruc_types.h"
#include "ext_svr.h"
#include "ext_serial_port.h"
#include "ext_serial_pkt.h"

/* this file is used by both host and target... */
#ifndef MATLAB_MEX_FILE

/* TARGET ONLY ------------------- */

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

#if COMMSTATE_ON_PTT == 1

/* Microcontroller specific and system headers */
#if MC9S12_TYPE == DP256
#include <mc9s12dp256.h>		      /* port definitions etc. */
#elif MC9S12_TYPE == C128
#include <mc9s12c128.h>			      /* port definitions etc. */
#elif MC9S12_TYPE == C32
#include <mc9s12c32.h>			      /* port definitions etc. */
#endif

#endif

#ifdef HOSTALIVECHECK
/* flag is reset to TRUE with every properly received ACK_PACKET;
 * flag is set to FALSE when the target buffer is full (-> most likely cause: host inactive)
 * used to control the writing of new data into the circBuf
 *
 * fw-07-07
 */

/* stop buffering data when the target buffer is full and the host seems busy */
extern boolean_T   HostIsAlive;     /* defined in mc_main.c */
#endif

#else

/* HOST ONLY --------------------- */

#define abort_LED(err)    /* nothing */

#ifndef CIRCBUFSIZE
#define CIRCBUFSIZE 2000  /* default (host) */
#endif

#ifndef FIFOBUFSIZE
#define FIFOBUFSIZE  400  /* default (host) */
#endif

/* FIFOHOSTFACTOR should be > 2 (the larger, the more stable the host after long blockages of Simulink (e.g. menu open)
 * The memory needed on the host is: FIFOBUFNUM * FIFOBUFSIZE = CIRCBUFSIZE * FIFOHOSTFACTOR... at least: 2000 * FIFOHOSTFACTOR
 * An insanely high factor of '50' thus leads to a memory requirement of 2k * 50 = 100 kByte, nothing on a PC. With a factor '50'
 * a DP9S12 based target with a target buffer size of 2k target should survive a host blockage of approx. 10 minutes... 
 * ... in theory :)  
 *
 * fw-07-07
 */
#define FIFOHOSTFACTOR	50

#define FIFOBUFNUM   CIRCBUFSIZE/FIFOBUFSIZE * FIFOHOSTFACTOR

/* used here to activate/deactivate the deadlock emergency control (ExtSetPkt)   --   fw-07-07 */
/* HostSimStatus is an enum defined in ext_share.h */
extern HostSimStatus  HostStatus;

#endif

#include "debugMsgs.h"            /* macros PRINT_DEBUG_MSG_LVL1 to PRINT_DEBUG_MSG_LVL5,  fw-06-07 */


/* Display clear text messages of what packet has been sent/received (debug mode only) */
#if DEBUG_MSG_LVL > 0

static const char       *debugTelTypeStrings[3]= {
   "Packet type is UNDEFINED_PACKET",
   "Packet type is EXTMODE_PACKET",
   "Packet type is ACK_PACKET"
};

#ifdef MATLAB_MEX_FILE
#define numActionStrings   34
extern const char       *debugActionStrings[];  /* defined in ext_comm.c, 34 strings */
#endif  /* MATLAB_MEX_FILE */

// monitor the number of stored packets (queue: FIFOPkt)
static unsigned int     numFIFOPkts=0;

#endif



/* defined in 'ext_work.c', here only referenced */
extern int_T           volatile  startModel;

/*
 * Buffers used for storing incoming and outgoing packets.
 */
PRIVATE ExtSerialPacket buffer1st;
PRIVATE ExtSerialPacket buffer2nd;
PRIVATE ExtSerialPacket *InBuffer= &buffer1st;
PRIVATE ExtSerialPacket *OutBuffer= &buffer2nd;

/*
* If waitForAck is true, a packet can not be sent until the other side sends
* an ack indicating there is space to store the unsent packet.
*/
PRIVATE boolean_T       waitForAck=false;


/* needed for host sided communication module... fw-06-07 */
#ifdef MATLAB_MEX_FILE
/*
* NOTE:  When adding or removing a valid baud rate, both the baudRates and
*        baudRatesStr variables must be modified!
*/
PRIVATE const uint32_T  baudRates[]= {
   1200,
   2400,
   4800,
   9600,
   14400,
   19200,
   38400,
   56000,
   57600,
   115200
};
PRIVATE const char_T    *baudRatesStr="baud rate must be one of the following:\n"
"\t1200, 2400, 4800, 9600, 14400,\n"
"\t19200, 38400, 56000, 57600, 115200\n";
#endif

/*
* The maximum number of bytes a serial packet may contain.  Serial pkts
* larger than the maximum size will be broken up into multiple pkts
* (each equal to or less than the max size) for transmission.
*/
#define MAX_SERIAL_PKT_SIZE FIFOBUFSIZE

/*
* The maximum number of (maximum sized) packets that can be stored at
* any one time.
*/
#define NUM_FIFO_BUFFERS FIFOBUFNUM

typedef struct FIFOBuffer_tag {

      char                 pktBuf[MAX_SERIAL_PKT_SIZE];
      uint32_T             size;
      uint32_T             offset;
      struct FIFOBuffer_tag *next;

} FIFOBuffer;

PRIVATE FIFOBuffer *FreeFIFOHead=NULL;
PRIVATE FIFOBuffer *FreeFIFOTail=NULL;
PRIVATE FIFOBuffer *PktFIFOHead=NULL;
PRIVATE FIFOBuffer *PktFIFOTail=NULL;

PRIVATE bool isFIFOEmpty(FIFOBuffer *head, FIFOBuffer *tail) {

   if((head==NULL)&&(tail==NULL)) {

      return true;

   }

   return false;

}

PRIVATE void InsertFIFO(FIFOBuffer **head, FIFOBuffer **tail, FIFOBuffer *buf) {

   if(isFIFOEmpty(*head, *tail)) {

      *head= *tail=buf;
      buf->next=NULL;

   }
   else {

      assert(*head != NULL);
      assert(*tail != NULL);

      (*tail)->next=buf;
      *tail=buf;
      buf->next=NULL;

   }

}

PRIVATE FIFOBuffer * RemoveFIFO(FIFOBuffer **head, FIFOBuffer **tail) {

   FIFOBuffer  *buf=NULL;

   if(isFIFOEmpty(*head, *tail)) {

      return NULL;

   }
   else {

      assert(*head != NULL);
      assert(*tail != NULL);

      buf= *head;
      *head=buf->next;
      if(*head==NULL) {

         *tail=NULL;

      }
      buf->next=NULL;

   }

   return buf;

}

PRIVATE bool isFIFOFreeEmpty(void) {

   return isFIFOEmpty(FreeFIFOHead, FreeFIFOTail);

}

PRIVATE bool isFIFOPktEmpty(void) {

   return isFIFOEmpty(PktFIFOHead, PktFIFOTail);

}

PRIVATE void InsertFIFOFree(FIFOBuffer *buf) {

   InsertFIFO(&FreeFIFOHead, &FreeFIFOTail, buf);

}

PRIVATE FIFOBuffer * RemoveFIFOFree(void) {

   return RemoveFIFO(&FreeFIFOHead, &FreeFIFOTail);

}

PRIVATE void InsertFIFOPkt(FIFOBuffer *buf) {

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

   #if DEBUG_MSG_LVL > 0
   numFIFOPkts++;
   PRINT_DEBUG_MSG_LVL3("Number of stored messages in FIFOPkt: ");
   PRINT_DEBUG_MSG_LVL3_UDec((uint16_T)(numFIFOPkts));
   PRINT_DEBUG_MSG_NL3;
   #endif

   InsertFIFO(&PktFIFOHead, &PktFIFOTail, buf);

}

PRIVATE FIFOBuffer * RemoveFIFOPkt(void) {

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

   #if DEBUG_MSG_LVL > 0
   PRINT_DEBUG_MSG_LVL3("Fetching last previously stored packet...");
   PRINT_DEBUG_MSG_NL3;
   numFIFOPkts--;
   PRINT_DEBUG_MSG_LVL3("Number of stored messages left in FIFOPkt: ");
   PRINT_DEBUG_MSG_LVL3_UDec((uint16_T)(numFIFOPkts));
   PRINT_DEBUG_MSG_NL3;
   #endif

   return RemoveFIFO(&PktFIFOHead, &PktFIFOTail);

}

PRIVATE FIFOBuffer * GetFIFOPkt(void) {

   return PktFIFOHead;

}

PRIVATE boolean_T AddToFIFOFree(void) {

   int         i;
   boolean_T   error=EXT_NO_ERROR;

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

   PRINT_DEBUG_MSG_LVL3("Allocating memory for (another) ");
   PRINT_DEBUG_MSG_LVL3_UDec((uint16_T)NUM_FIFO_BUFFERS);
   PRINT_DEBUG_MSG_LVL3_Raw(" free FIFO buffers");
   PRINT_DEBUG_MSG_NL3;
   for(i=0 ; i<NUM_FIFO_BUFFERS ; i++) {

      FIFOBuffer  *buf=calloc(1, sizeof(FIFOBuffer));
      if(buf==NULL) {

         abort_LED(22);

         error=EXT_ERROR;
         goto EXIT_POINT;

      }
      InsertFIFOFree(buf);

   }
   EXIT_POINT:return(error);

}

PRIVATE void SavePkt(char *mem, int size) {

   FIFOBuffer  *buf = RemoveFIFOFree();

   #ifdef MATLAB_MEX_FILE
   /* The ack protocol NO LONGER ensures there is available space to save the pkt.   --  fw-07-07 */
   if(buf == NULL) {

	   
	   //mexPrintf("Allocating more FIFO buffers... \n");
	   
	   /* allocate another FIFOBUFNUM buffers... */
       if(AddToFIFOFree() != EXT_NO_ERROR) {

           /* out of memory... */
           mexErrMsgTxt("Out of memory while trying to allocate more FIFO buffers...\n\r");
       
	   }

	   /* now get one of the newly allocated (free) FIFOs... */
	   buf = RemoveFIFOFree();

   } /* buf == NULL */
   #endif

   assert(buf!=NULL);

   /* The max transmission size ensures we never exceed memory when copying. */
   assert(size<=MAX_SERIAL_PKT_SIZE);

   memcpy(buf->pktBuf, mem, size);
   buf->size=size;
   buf->offset=0;

   InsertFIFOPkt(buf);

}


#if DEBUG_MSG_LVL > 0
/* Debug function: display actually received contents... */
PRIVATE void DisplayActualReceivedPacket(ExtSerialPacket *pkt) {
  
   int            i;
   unsigned char  *myPtr = (unsigned char *)pkt;
   uint32_T       mySize = pkt->size;
   
   PRINT_DEBUG_MSG_LVL1_Raw("[");
   
   /* header (2), type (1), size (4) */
   for(i=0; i<7; i++) {
     PRINT_DEBUG_MSG_LVL1_Raw(" 0x");
     PRINT_DEBUG_MSG_LVL1_UHex((uint16_T)(*myPtr++));
   }
   
   /* data */
   for(i=0; i<mySize; i++) {
     PRINT_DEBUG_MSG_LVL1_Raw(" 0x");
     PRINT_DEBUG_MSG_LVL1_UHex((uint16_T)*((unsigned char *)&(pkt->Buffer[i])));
   }
   
   /* data */
   myPtr = (unsigned char *)&pkt->tail;
   for(i=0; i<2; i++) {
     PRINT_DEBUG_MSG_LVL1_Raw(" 0x");
     PRINT_DEBUG_MSG_LVL1_UHex((uint16_T)(*myPtr++));
   }
   
   PRINT_DEBUG_MSG_LVL1_Raw(" ]\n\r");

}
#endif



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

/* Forward declaration */
PRIVATE boolean_T ExtSetPkt(ExtSerialPort *, char *, int, int *, PacketTypeEnum);

/* Function: ExtGetPktBlocking =================================================
* Abstract:
*  Blocks until a packet is available on the comm line.  If the incoming packet
*  is an ACK, the packet is processed and thrown away.  Otherwise, the packet
*  is saved.
*
*  EXT_NO_ERROR is returned on success, EXT_ERROR on failure.
*/
PRIVATE boolean_T ExtGetPktBlocking(ExtSerialPort *portDev) {

⌨️ 快捷键说明

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