📄 ext_svr.c
字号:
/*
* Copyright 1994-2006 The MathWorks, Inc.
*
* File: ext_svr.c $Revision: 1.1.6.8 $
*
* 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 ExtWaitForStartPkt: return true if waiting for host to start
* o rt_ExtModeInit: external mode initialization
* o rt_ExtModeSleep: pause the process
* o rt_PktServerWork: server for setting/getting packets from host
* o rt_PktServer: server dispatcher - for multi-tasking targets
* o rt_UploadServerWork: server for setting data upload packets 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.
*/
/*
* Adapted for rtmc9s12-Target, fw-09-7
*/
/*****************
* Include files *
*****************/
/*ANSI C headers*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if defined(VXWORKS)
/*VxWorks headers*/
# include <selectLib.h>
# include <sockLib.h>
# include <inetLib.h>
# include <ioLib.h>
# include <taskLib.h>
#endif
/*Real Time Workshop headers*/
#include "tmwtypes.h"
#include "simstruc_types.h"
#include "ext_types.h"
#include "ext_share.h"
#include "ext_test.h"
#include "ext_svr_transport.h"
#include "updown.h"
#include "updown_util.h" /* assert */
#include "dt_info.h"
#include "mc_signal.h" /* abort_LED */
#include "debugMsgs.h" /* macros PRINT_DEBUG_MSG_LVL3 to PRINT_DEBUG_MSG_LVL5, fw-06-07 */
#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 LCDUSE4ERRORS
#include "lcd.h" /* writeLine() */
#endif
#ifndef __LCC__
#define UNUSED_PARAM(p) (void)((p))
#else
#define UNUSED_PARAM(p) /* nothing */
#endif
#if DEBUG_MSG_LVL > 0
/* TXactiveControl is defined in ext_share.h (used on host and target) -- fw-07-07 */
#ifdef TXactiveControl
#define numDebugMsgs 36
#else
#define numDebugMsgs 35
#endif
static const char *debugActionStrings[numDebugMsgs] = {
/* connection actions */
"Packet type is EXT_CONNECT",
"Packet type is EXT_DISCONNECT_REQUEST",
"Packet type is EXT_DISCONNECT_REQUEST_NO_FINAL_UPLOAD",
"Packet type is EXT_DISCONNECT_CONFIRMED",
/* parameter upload/download actions */
"Packet type is EXT_SETPARAM",
"Packet type is EXT_GETPARAMS",
/* data upload actions */
"Packet type is EXT_SELECT_SIGNALS",
"Packet type is EXT_SELECT_TRIGGER",
"Packet type is EXT_ARM_TRIGGER",
"Packet type is EXT_CANCEL_LOGGING",
/* model control actions */
"Packet type is EXT_MODEL_START",
"Packet type is EXT_MODEL_STOP",
"Packet type is EXT_MODEL_PAUSE",
"Packet type is EXT_MODEL_STEP",
"Packet type is EXT_MODEL_CONTINUE",
/* data request actions */
"Packet type is EXT_GET_TIME",
/*================================
* Packets/actions from target.
*==============================*/
/* responses */
"Packet type is EXT_CONNECT_RESPONSE", /* must not be 0! */
"Packet type is EXT_DISCONNECT_REQUEST_RESPONSE",
"Packet type is EXT_SETPARAM_RESPONSE",
"Packet type is EXT_GETPARAMS_RESPONSE",
"Packet type is EXT_MODEL_SHUTDOWN",
"Packet type is EXT_GET_TIME_RESPONSE",
"Packet type is EXT_MODEL_START_RESPONSE",
"Packet type is EXT_MODEL_PAUSE_RESPONSE",
"Packet type is EXT_MODEL_STEP_RESPONSE",
"Packet type is EXT_MODEL_CONTINUE_RESPONSE",
"Packet type is EXT_UPLOAD_LOGGING_DATA",
"Packet type is EXT_SELECT_SIGNALS_RESPONSE",
"Packet type is EXT_SELECT_TRIGGER_RESPONSE",
"Packet type is EXT_ARM_TRIGGER_RESPONSE",
"Packet type is EXT_CANCEL_LOGGING_RESPONSE",
/*
* This packet is sent from the target to signal the end of a data
* collection event (e.g., each time that the duration is reached).
* This packet only applies to normal mode (see
* EXT_TERMINATE_LOG_SESSION)
*/
"Packet type is EXT_TERMINATE_LOG_EVENT",
/*
* This packet is sent from the target at the end of each data logging
* session. This occurs either at the end of a oneshot or at the end
* of normal mode (i.e., the last in a series of oneshots).
*/
"Packet type is EXT_TERMINATE_LOG_SESSION",
#ifdef TXactiveControl
/* TXactive control (rtmc9s12-target) -- fw-07-07 */
"Packet type is EXT_DATA_UPLD_NOACK_REQUEST",
#endif
/* used to break assumed deadlock situations -- fw-07-07 */
"Packet type is EXT_BREAK_DEADLOCK",
"Packet type is EXTENDED = 255" /* reserved for extending beyond 254 ID's */
};
static const char *debugStatusStrings[5]= {
"TARGET_STATUS_NOT_CONNECTED",
"TARGET_STATUS_WAITING_TO_START",
"TARGET_STATUS_STARTING",
"TARGET_STATUS_RUNNING",
"TARGET_STATUS_PAUSED"
};
#endif /* DEBUG_MSG_LVL */
/**********************
* External Variables *
**********************/
extern int_T volatile startModel;
extern TargetSimStatus volatile modelStatus;
#ifdef VXWORKS
extern SEM_ID uploadSem;
#endif
/********************
* Global Variables *
********************/
/*
* Flags.
*/
PRIVATE boolean_T connected=FALSE;
PRIVATE boolean_T commInitialized=FALSE;
#ifdef TXactiveControl
PRIVATE boolean_T TXactive=FALSE; /* set in rt_PktServerWork upon receipt of an EXT_DATA_UPLD_REQUEST -- fw-07-07 */
#endif
/*
* Pointer to opaque user data (structure ExtUserData is defined in ext_svr_transport.c).
*/
PRIVATE ExtUserData *extUD=NULL;
/*
* Buffer used to receive packets.
*/
PRIVATE int_T pktBufSize=0;
PRIVATE char *pktBuf=NULL;
/*******************
* Local Functions *
*******************/
/* Function: GrowRecvBufIfNeeded ===============================================
* Abstract:
* Allocate or increase the size of buffer for receiving packets from target.
*/
PRIVATE boolean_T GrowRecvBufIfNeeded(const int pktSize) {
// local function name... debugging only
#if DEBUG_MSG_LVL > 0
const char *funct_name="GrowRecvBufIfNeeded";
#endif
PRINT_DEBUG_MSG_LVL3("IN\n\r");
if(pktSize>pktBufSize) {
if(pktBuf!=NULL) {
//PRINT_DEBUG_MSG_LVL1("Freeing memory of previously allocated packet reception buffer\n\r");
free(pktBuf);
pktBufSize=0;
}
//PRINT_DEBUG_MSG_LVL1("Allocating memory for packet to be received next (ext_svr.c, ");
//PRINT_DEBUG_MSG_LVL1_UDec((uint16_T)pktSize);
//PRINT_DEBUG_MSG_LVL1_Raw(" bytes)");
//PRINT_DEBUG_MSG_NL1;
pktBuf=(char*)malloc(pktSize);
if(pktBuf==NULL) {
abort_LED(45);
return EXT_ERROR;
}
pktBufSize=pktSize;
}
PRINT_DEBUG_MSG_LVL3("OUT\n\r");
return EXT_NO_ERROR;
} /* end GrowRecvBufIfNeeded */
/* Function: GetPktHdr =========================================================
* Abstract:
* Attempts to retrieve a packet 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 packets and none were
* available.
*/
PRIVATE boolean_T GetPktHdr(PktHeader *pktHdr, boolean_T *hdrAvail) {
int_T nGot=0; /* assume */
int_T nGotTotal=0;
int_T pktSize=sizeof(PktHeader);
boolean_T error=EXT_NO_ERROR;
// local function name... debugging only
#if DEBUG_MSG_LVL > 0
const char *funct_name="GetPktHdr";
#endif
PRINT_DEBUG_MSG_LVL3("IN\n\r");
/* Get the header. */
while(nGotTotal<pktSize) {
error=ExtGetHostPkt(extUD, pktSize-nGotTotal, &nGot, (char_T*)((char_T*)pktHdr+nGotTotal));
if(error!=EXT_NO_ERROR) {
/* should never happen, errors are caught in ExtGetHostPkt -- fw-07-07 */
abort_LED(46); // just in case...
goto EXIT_POINT;
}
nGotTotal+=nGot;
if(nGotTotal==0)
break;
}
assert((nGot==0)||(nGotTotal==pktSize));
EXIT_POINT:*hdrAvail=(boolean_T)(nGot>0);
PRINT_DEBUG_MSG_LVL3("OUT, error status: ");
PRINT_DEBUG_MSG_LVL3_UDec(error);
PRINT_DEBUG_MSG_NL3;
return error;
} /* end GetPktHdr */
/* Function: ClearPkt ==========================================================
* Abstract:
* Remove the data from the communication line one byte at a time. This
* function is called when there was not enough memory to receive an entire
* packet. Since the data was never received, it must be discarded so that
* other packets can be sent.
*/
PRIVATE void ClearPkt(const int pktSize) {
int_T nGot;
boolean_T error=EXT_NO_ERROR;
int_T nGotTotal=0;
static char buffer;
/* Get and discard the data one char at a time. */
while(nGotTotal<pktSize) {
error=ExtGetHostPkt(extUD, 1, &nGot, (char_T*)&buffer);
if(error) {
abort_LED(47);
//fprintf(stderr,"ExtGetHostPkt() failed.\n");
goto EXIT_POINT;
}
nGotTotal+=nGot;
}
EXIT_POINT:return;
} /* end ClearPkt */
/* Function: GetPkt ============================================================
* 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 pktBuf. If the buf needs to be grown to accommodate the package,
* 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 * GetPkt(const int pktSize) {
int_T nGot;
boolean_T error=EXT_NO_ERROR;
int_T nGotTotal=0;
// local function name... debugging only
#if DEBUG_MSG_LVL > 0
const char *funct_name="GetPkt";
#endif
PRINT_DEBUG_MSG_LVL2("IN\n\r");
error=GrowRecvBufIfNeeded(pktSize);
if(error!=EXT_NO_ERROR) {
abort_LED(48);
//fprintf(stderr,"Previous pkt from host thrown away due to lack of memory.\n");
ClearPkt(pktSize);
goto EXIT_POINT;
}
/* Get the data. */
while(nGotTotal<pktSize) {
error=ExtGetHostPkt(extUD, pktSize-nGotTotal, &nGot, (char_T*)(pktBuf+nGotTotal));
if(error) {
abort_LED(49);
//fprintf(stderr,"ExtGetHostPkt() failed.\n");
goto EXIT_POINT;
}
nGotTotal+=nGot;
}
EXIT_POINT:PRINT_DEBUG_MSG_LVL2("OUT\n\r");
return((error==EXT_NO_ERROR)?pktBuf:NULL);
} /* end GetPkt */
/* Forward declaration */
void UploadServerWork(int32_T, int_T numSampTimes);
/* Function: DisconnectFromHost ================================================
* Abstract:
* Disconnect from the host.
*/
PRIVATE void DisconnectFromHost(bool sendFinalUpload, int_T numSampTimes) {
int i;
// local function name... debugging only
#if DEBUG_MSG_LVL > 0
const char *funct_name="DisconnectFromHost";
#endif
for(i=0; i<NUM_UPINFOS; i++) {
if(sendFinalUpload) {
UploadPrepareForFinalFlush(i);
UploadServerWork(i, numSampTimes);
UploadLogInfoTerm(i, numSampTimes);
}
}
connected=FALSE;
commInitialized=FALSE;
//PRINT_DEBUG_MSG_LVL1("connected = FALSE\n\r");
//PRINT_DEBUG_MSG_LVL1("commInitialized = FALSE\n\r");
ExtCloseConnection(extUD);
} /* end DisconnectFromHost */
/* Function: ForceDisconnectFromHost ===========================================
* Abstract:
* Force a disconnect from the host. This is not a graceful shutdown and
* should only be used when the integrity of the external mode connection
* is in question. To shutdown the connection gracefully, use
* DisconnectFromHost().
*/
PRIVATE void ForceDisconnectFromHost(int_T numSampTimes) {
// local function name... debugging only
#if DEBUG_MSG_LVL > 0
const char *funct_name="ForceDisconnectFromHost";
#endif
int i;
connected=FALSE;
commInitialized=FALSE;
//PRINT_DEBUG_MSG_LVL1("connected = FALSE\n\r");
//PRINT_DEBUG_MSG_LVL1("commInitialized = FALSE\n\r");
for(i=0; i<NUM_UPINFOS; i++) {
UploadEndLoggingSession(i, numSampTimes);
}
ExtForceDisconnect(extUD);
} /* end ForceDisconnectFromHost */
/* Function: ProcessConnectPkt =================================================
* Abstract:
* Process the EXT_CONNECT packet and send response to host.
*/
PRIVATE boolean_T ProcessConnectPkt(RTWExtModeInfo *ei) {
int_T nSet;
PktHeader pktHdr;
int_T tmpBufSize;
uint32_T *tmpBuf=NULL;
boolean_T error=EXT_NO_ERROR;
const DataTypeTransInfo *dtInfo=rteiGetModelMappingInfo(ei);
uint_T *dtSizes=dtGetDataTypeSizes(dtInfo);
int_T nDataTypes=dtGetNumDataTypes(dtInfo);
// local function name... debugging only
#if DEBUG_MSG_LVL > 0
const char *funct_name="ProcessConnectPkt";
#endif
assert(connected);
assert(!comminitialized);
PRINT_DEBUG_MSG_LVL3("IN\n\r");
/*
* Send the 1st of two EXT_CONNECT_RESPONSE packets to the host.
* The packet consists purely of the pktHeader. In this special
* case the pktSize actually contains the number of bits per byte
* (not always 8 - see TI compiler for C30 and C40).
*/
pktHdr.type=(uint32_T)EXT_CONNECT_RESPONSE;
pktHdr.size=(uint32_T)8; /* 8 bits per byte */
error=ExtSetHostPkt(extUD, sizeof(pktHdr), (char_T*)&pktHdr, &nSet);
if(error||(nSet!=sizeof(pktHdr))) {
abort_LED(50);
//fprintf(stderr,
// "ExtSetHostPkt() failed for 1st EXT_CONNECT_RESPONSE.\n");
goto EXIT_POINT;
}
/* Send 2nd EXT_CONNECT_RESPONSE packet containing the following
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -