📄 ext_svr.c
字号:
/*
* 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 + -