+++ /dev/null
-/*
- * Copyright 1994-2012 The MathWorks, Inc.
- *
- * File: ext_svr.c
- *
- * Abstract:
- * External mode server interface (TCPIP example). Provides functions
- * that get called by main routine (model-name.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
- *
- * Parameter downloading and data uploading supported for single and
- * multi-tasking targets.
- */
-
-/*****************
- * Include files *
- *****************/
-
-/*ANSI C headers*/
-#ifndef EXTMODE_DISABLEPRINTF
-#include <stdio.h>
-#endif
-
-#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 "rtwtypes.h"
-#include "rtw_extmode.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"
-#include "dt_info.h"
-
-/*Uncomment to test 4 byte reals*/
-/*#define real_T float*/
-
-/**********************
- * External Variables *
- **********************/
-extern int_T volatile startModel;
-extern TargetSimStatus volatile modelStatus;
-#ifdef VXWORKS
-extern SEM_ID uploadSem;
-extern SEM_ID pktSem;
-#endif
-extern boolean_T host_upstatus_is_uploading;
-
-/********************
- * Global Variables *
- ********************/
-
-/*
- * Flags.
- */
-PRIVATE boolean_T connected = FALSE;
-PRIVATE boolean_T commInitialized = FALSE;
-
-/*
- * Pointer to opaque user data (defined by ext_svr_transport.c).
- */
-PRIVATE ExtUserData *extUD = NULL;
-
-/*
- * Buffer used to receive packets.
- */
-PRIVATE int_T pktBufSize = 0;
-PRIVATE char *pktBuf = NULL;
-
-
-#ifndef EXTMODE_DISABLESIGNALMONITORING
-#ifndef EXTMODE_DISABLEPRINTF
-PRIVATE char ERRMSG_PROCESSSELECTSIGNAL[] =
- "\nError in UploadLogInfoInit(). Most likely a memory\n"
- "allocation error or an attempt to re-initialize the\n"
- "signal selection during the data logging process\n"
- "(i.e., multiple EXT_SELECT_SIGNAL packets were received\n"
- "before the logging session terminated or an\n"
- "EXT_CANCEL_LOGGING packet was received)\n";
-
-PRIVATE char ERRMSG_PROCESSSELECTTRIGGER[] =
- "\nError in UploadInitTrigger(). Most likely a memory\n"
- "allocation error or an attempt to re-initialize the\n"
- "trigger selection during the data logging process\n"
- "(i.e., multiple EXT_SELECT_TRIGGER packets were received\n"
- "before the logging session terminated or an\n"
- "EXT_CANCEL_LOGGING packet was received)\n";
-#else
-PRIVATE char ERRMSG_PROCESSSELECTSIGNAL[] = "";
-PRIVATE char ERRMSG_PROCESSSELECTTRIGGER[] = "";
-#endif
-#endif
-
-/*******************
- * Local Functions *
- *******************/
-
-/* Function: GrowRecvBufIfNeeded ===============================================
- * Abstract:
- * Allocate or increase the size of buffer for receiving packets from target.
- */
-PRIVATE boolean_T GrowRecvBufIfNeeded(const int pktSize)
-{
- if (pktSize > pktBufSize) {
- if (pktBuf != NULL) {
- free(pktBuf);
- pktBufSize = 0;
- }
-
- pktBuf = (char *)malloc(pktSize);
- if (pktBuf == NULL) return(EXT_ERROR);
-
- pktBufSize = pktSize;
- }
- 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;
-
- /* Get the header. */
- while(nGotTotal < pktSize) {
- error = ExtGetHostPkt(extUD,
- pktSize - nGotTotal, &nGot, (char_T *)((char_T *)pktHdr + nGotTotal));
- if (error) goto EXIT_POINT;
-
- nGotTotal += nGot;
-
- if (nGotTotal == 0) break;
- }
- assert((nGot == 0) || (nGotTotal == pktSize));
-
-EXIT_POINT:
- *hdrAvail = (boolean_T)(nGot > 0);
- 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) {
-#ifndef EXTMODE_DISABLEPRINTF
- fprintf(stderr,"ExtGetHostPkt() failed.\n");
-#endif
- 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 indefinitely - 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;
-
- error = GrowRecvBufIfNeeded(pktSize);
- if (error != EXT_NO_ERROR) {
-#ifndef EXTMODE_DISABLEPRINTF
- fprintf(stderr,"Previous pkt from host thrown away due to lack of memory.\n");
-#endif
- ClearPkt(pktSize);
- goto EXIT_POINT;
- }
-
- /* Get the data. */
- while(nGotTotal < pktSize) {
- error = ExtGetHostPkt(extUD,
- pktSize - nGotTotal, &nGot, (char_T *)(pktBuf + nGotTotal));
- if (error) {
-#ifndef EXTMODE_DISABLEPRINTF
- fprintf(stderr,"ExtGetHostPkt() failed.\n");
-#endif
- goto EXIT_POINT;
- }
-
- nGotTotal += nGot;
- }
-
-EXIT_POINT:
- return((error == EXT_NO_ERROR) ? pktBuf : NULL);
-} /* end GetPkt */
-
-
-#ifndef EXTMODE_DISABLESIGNALMONITORING
-/* Forward declaration */
-void UploadServerWork(int32_T, int_T numSampTimes);
-#endif
-
-/* Function: DisconnectFromHost ================================================
- * Abstract:
- * Disconnect from the host.
- */
-PRIVATE void DisconnectFromHost(int_T numSampTimes)
-{
- int i;
-
- for (i=0; i<NUM_UPINFOS; i++) {
- UploadPrepareForFinalFlush(i);
-
-#if defined(VXWORKS)
- /*
- * UploadPrepareForFinalFlush() has already called semGive(uploadSem)
- * two times. Now the server thread will wait until the upload thread
- * has processed all of the data in the buffers for the final upload
- * and exhausted the uploadSem semaphores. If the server thread
- * attempts to call UploadServerWork() while the upload thread is in
- * the middle of processing the buffers, the target code may crash
- * with a NULL pointer exception (the buffers are destroyed after
- * calling UploadLogInfoTerm).
- */
- while(semTake(uploadSem, NO_WAIT) != ERROR) {
- semGive(uploadSem);
- taskDelay(1000);
- }
-#else
-#ifndef EXTMODE_DISABLESIGNALMONITORING
- if (host_upstatus_is_uploading) {
- UploadServerWork(i, numSampTimes);
- }
-#endif
-#endif
-
- UploadLogInfoTerm(i, numSampTimes);
- }
-
- connected = FALSE;
- commInitialized = FALSE;
-
- 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)
-{
- int i;
- connected = FALSE;
- commInitialized = FALSE;
-
- 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);
-
- assert(connected);
- assert(!comminitialized);
-
- /*
- * 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))) {
-#ifndef EXTMODE_DISABLEPRINTF
- fprintf(stderr,
- "ExtSetHostPkt() failed for 1st EXT_CONNECT_RESPONSE.\n");
-#endif
- goto EXIT_POINT;
- }
-
- /* Send 2nd EXT_CONNECT_RESPONSE packet containing the following
- * fields:
- *
- * CS1 - checksum 1 (uint32_T)
- * CS2 - checksum 2 (uint32_T)
- * CS3 - checksum 3 (uint32_T)
- * CS4 - checksum 4 (uint32_T)
- *
- * intCodeOnly - flag indicating if target is integer only (uint32_T)
- *
- * MWChunkSize - multiword data type chunk size on target (uint32_T)
- *
- * targetStatus - the status of the target (uint32_T)
- *
- * nDataTypes - # of data types (uint32_T)
- * dataTypeSizes - 1 per nDataTypes (uint32_T[])
- */
-
- {
- int nPktEls = 4 + /* checkSums */
- 1 + /* intCodeOnly */
- 1 + /* MW chunk size */
- 1 + /* targetStatus */
- 1 + /* nDataTypes */
- dtGetNumDataTypes(dtInfo); /* data type sizes */
-
- tmpBufSize = nPktEls * sizeof(uint32_T);
- tmpBuf = (uint32_T *)malloc(tmpBufSize);
- if (tmpBuf == NULL) {
- error = EXT_ERROR; goto EXIT_POINT;
- }
- }
-
- /* Send packet header. */
- pktHdr.type = EXT_CONNECT_RESPONSE;
- pktHdr.size = tmpBufSize;
-
- error = ExtSetHostPkt(extUD,sizeof(pktHdr),(char_T *)&pktHdr,&nSet);
- if (error || (nSet != sizeof(pktHdr))) {
-#ifndef EXTMODE_DISABLEPRINTF
- fprintf(stderr,
- "ExtSetHostPkt() failed for 2nd EXT_CONNECT_RESPONSE.\n");
-#endif
- goto EXIT_POINT;
- }
-
- /* Checksums, target status & SL_DOUBLESize. */
- tmpBuf[0] = rteiGetChecksum0(ei);
- tmpBuf[1] = rteiGetChecksum1(ei);
- tmpBuf[2] = rteiGetChecksum2(ei);
- tmpBuf[3] = rteiGetChecksum3(ei);
-
-#if INTEGER_CODE == 0
- tmpBuf[4] = (uint32_T)0;
-#else
- tmpBuf[4] = (uint32_T)1;
-#endif
-
- tmpBuf[5] = (uint32_T)sizeof(uchunk_T);
-
- tmpBuf[6] = (uint32_T)modelStatus;
-
- /* nDataTypes and dataTypeSizes */
- {
- int i;
- tmpBuf[7] = (uint32_T)nDataTypes;
- for (i=0; i<nDataTypes; i++) {
- tmpBuf[8+i] = (uint32_T)dtSizes[i];
- }
- }
-
- /* Send the packet. */
- error = ExtSetHostPkt(extUD,tmpBufSize,(char_T *)tmpBuf,&nSet);
- if (error || (nSet != tmpBufSize)) {
-#ifndef EXTMODE_DISABLEPRINTF
- fprintf(stderr,
- "ExtSetHostPkt() failed.\n");
-#endif
- goto EXIT_POINT;
- }
-
- commInitialized = TRUE;
-
-EXIT_POINT:
- free(tmpBuf);
- return(error);
-} /* end ProcessConnectPkt */
-
-
-/* Function: SendPktHdrToHost ==================================================
- * Abstract:
- * Send a packet header to the host.
- */
-PRIVATE boolean_T SendPktHdrToHost(
- const ExtModeAction action,
- const int size) /* # of bytes to follow pkt header */
-{
- int_T nSet;
- PktHeader pktHdr;
- boolean_T error = EXT_NO_ERROR;
-
- pktHdr.type = (uint32_T)action;
- pktHdr.size = size;
-
- error = ExtSetHostPkt(extUD,sizeof(pktHdr),(char_T *)&pktHdr,&nSet);
- if (error || (nSet != sizeof(pktHdr))) {
- error = EXT_ERROR;
-#ifndef EXTMODE_DISABLEPRINTF
- fprintf(stderr,"ExtSetHostPkt() failed.\n");
-#endif
- goto EXIT_POINT;
- }
-
-EXIT_POINT:
- return(error);
-} /* end SendPktHdrToHost */
-
-
-/* Function: SendPktDataToHost =================================================
- * Abstract:
- * Send packet data to host. You are responsible for sending a header
- * prior to sending the header.
- */
-PRIVATE boolean_T SendPktDataToHost(const char *data, const int size)
-{
- int_T nSet;
- boolean_T error = EXT_NO_ERROR;
-
- error = ExtSetHostPkt(extUD,size,data,&nSet);
- if (error || (nSet != size)) {
- error = EXT_ERROR;
-#ifndef EXTMODE_DISABLEPRINTF
- fprintf(stderr,"ExtSetHostPkt() failed.\n");
-#endif
- goto EXIT_POINT;
- }
-
-EXIT_POINT:
- return(error);
-} /* end SendPktDataToHost */
-
-
-/* Function: SendPktToHost =====================================================
- * Abstract:
- * Send a packet to the host. Packets can be of two forms:
- * o packet header only
- * the type is used as a flag to notify Simulink of an event
- * that has taken place on the target (event == action == type)
- * o pkt header, followed by data
- */
-PUBLIC boolean_T SendPktToHost(
- const ExtModeAction action,
- const int size, /* # of bytes to follow pkt header */
- const char *data)
-{
- boolean_T error = EXT_NO_ERROR;
-
-#ifdef VXWORKS
- semTake(pktSem, WAIT_FOREVER);
-#endif
-
- error = SendPktHdrToHost(action,size);
- if (error != EXT_NO_ERROR) goto EXIT_POINT;
-
- if (data != NULL) {
- error = SendPktDataToHost(data, size);
- if (error != EXT_NO_ERROR) goto EXIT_POINT;
- } else {
- assert(size == 0);
- }
-
-EXIT_POINT:
-#ifdef VXWORKS
- semGive(pktSem);
-#endif
- return(error);
-} /* end SendPktToHost */
-
-
-/* Function: SendResponseStatus ===============================================
- *
- */
-PRIVATE boolean_T SendResponseStatus(const ExtModeAction response,
- const ResponseStatus status,
- int32_T upInfoIdx)
-{
- int32_T msg[2];
- boolean_T error = EXT_NO_ERROR;
-
- msg[0] = (int32_T)status;
- msg[1] = upInfoIdx;
-
- error = SendPktToHost(response,2*sizeof(int32_T),(char_T *)&msg);
- return(error);
-
-} /* end SendResponseStatus */
-
-
-#ifndef EXTMODE_DISABLEPARAMETERTUNING
-/* Function: ProcessSetParamPkt ================================================
- * Receive and process the EXT_SETPARAM packet.
- */
-PRIVATE boolean_T ProcessSetParamPkt(RTWExtModeInfo *ei,
- const int pktSize)
-{
- int32_T msg;
- const char *pkt;
- boolean_T error = EXT_NO_ERROR;
-
- /*
- * Receive packet and set parameters.
- */
- pkt = GetPkt(pktSize);
- if (pkt == NULL) {
- msg = (int32_T)NOT_ENOUGH_MEMORY;
- SendPktToHost(EXT_SETPARAM_RESPONSE,sizeof(int32_T),(char_T *)&msg);
- error = EXT_ERROR;
- goto EXIT_POINT;
- }
- SetParam(ei, pkt);
-
- msg = (int32_T)STATUS_OK;
- error = SendPktToHost(EXT_SETPARAM_RESPONSE,sizeof(int32_T),(char_T *)&msg);
- if (error != EXT_NO_ERROR) goto EXIT_POINT;
-
-EXIT_POINT:
- return(error);
-} /* end ProcessSetParamPkt */
-#endif /* ifndef EXTMODE_DISABLEPARAMETERTUNING */
-
-#ifndef EXTMODE_DISABLEPARAMETERTUNING
-/* Function: ProcessGetParamsPkt ===============================================
- * Respond to the hosts request for the parameters by gathering up all the
- * params and sending them to the host.
- */
-PRIVATE boolean_T ProcessGetParamsPkt(RTWExtModeInfo *ei)
-{
- int_T i;
- int_T nBytesTotal;
- boolean_T error = EXT_NO_ERROR;
- const DataTypeTransInfo *dtInfo = rteiGetModelMappingInfo(ei);
- const DataTypeTransitionTable *dtTable = dtGetParamDataTypeTrans(dtInfo);
-
- if (dtTable != NULL) {
- /*
- * We've got some params in the model. Send their values to the
- * host.
- */
- int_T nTrans = dtGetNumTransitions(dtTable);
- const uint_T *dtSizes = dtGetDataTypeSizes(dtInfo);
-
- #ifdef VERBOSE
- #ifndef EXTMODE_DISABLEPRINTF
- printf("\nUploading initial parameters....\n");
- #endif
-#endif
-
- /*
- * Take pass 1 through the transitions to figure out how many
- * bytes we're going to send.
- */
- nBytesTotal = 0;
- for (i=0; i<nTrans; i++) {
- int_T dt = dtTransGetDataType(dtTable, i);
- int_T dtSize = dtSizes[dt];
- int_T nEls = dtTransNEls(dtTable, i); /* complexity accounted for in trans tbl num of els */
- int_T nBytes = dtSize * nEls;
-
- nBytesTotal += nBytes;
- }
-
- /*
- * Send the packet header.
- */
- error = SendPktHdrToHost(EXT_GETPARAMS_RESPONSE,nBytesTotal);
- if (error != EXT_NO_ERROR) goto EXIT_POINT;
-
- /*
- * Take pass 2 through the transitions and send the parameters.
- */
- for (i=0; i<nTrans; i++) {
- char_T *tranAddress = dtTransGetAddress(dtTable, i);
- int_T dt = dtTransGetDataType(dtTable, i);
- int_T dtSize = dtSizes[dt];
- int_T nEls = dtTransNEls(dtTable, i); /* complexity accounted for in trans tbl num of els */
- int_T nBytes = dtSize * nEls;
-
- error = SendPktDataToHost(tranAddress, nBytes);
- if (error != EXT_NO_ERROR) goto EXIT_POINT;
- }
- } else {
- /*
- * We've got no params in the model.
- */
- error = SendPktHdrToHost(EXT_GETPARAMS_RESPONSE,0);
- if (error != EXT_NO_ERROR) goto EXIT_POINT;
- }
-
-EXIT_POINT:
- return(error);
-} /* end ProcessGetParamsPkt */
-#endif /* ifndef EXTMODE_DISABLEPARAMETERTUNING */
-
-
-#ifndef EXTMODE_DISABLESIGNALMONITORING
-/* Function: ProcessSelectTriggerSignalPkt ===========================================
- * Receive and process the EXT_SELECT_TRIGGER or EXT_SELECT_SIGNALS packet.
- */
-PRIVATE boolean_T ProcessSelectTriggerSignalPkt(const ExtModeAction ACTION_ID,
- RTWExtModeInfo *ei,
- const int pktSize,
- int_T numSampTimes,
- char* errMsg)
-{
- const char *pkt;
- int32_T upInfoIdx;
- boolean_T error = EXT_NO_ERROR;
-
- pkt = GetPkt(pktSize);
- if (pkt == NULL) {
- SendResponseStatus(ACTION_ID, NOT_ENOUGH_MEMORY, -1);
- return(EXT_ERROR);
- }
-
- (void)memcpy(&upInfoIdx, pkt, sizeof(int32_T)); /* Extract upInfoIdx */
- switch(ACTION_ID) {
- case EXT_SELECT_TRIGGER_RESPONSE:
-#ifndef EXTMODE_DISABLEPRINTF
- PRINT_VERBOSE(
- ("got EXT_SELECT_TRIGGER packet for upInfoIdx : %d\n", upInfoIdx));
-#endif
- error = UploadInitTrigger(ei, pkt+sizeof(int32_T), upInfoIdx);
- break;
- case EXT_SELECT_SIGNALS_RESPONSE:
-#ifndef EXTMODE_DISABLEPRINTF
- PRINT_VERBOSE(
- ("got EXT_SELECT_SIGNALS packet for upInfoIdx : %d\n", upInfoIdx));
-#endif
- error = UploadLogInfoInit(ei, numSampTimes, pkt+sizeof(int32_T), upInfoIdx);
- break;
- default:
- break;
- }
-
- if (error != EXT_NO_ERROR) {
- SendResponseStatus(ACTION_ID, NOT_ENOUGH_MEMORY, upInfoIdx);
-#ifndef EXTMODE_DISABLEPRINTF
- printf("%s\n", errMsg);
-#endif
- return(error);
- }
-
- error = SendResponseStatus(ACTION_ID, STATUS_OK, upInfoIdx);
- return(error); /* Can be EXT_NO_ERROR */
-} /* end ProcessSelectTriggerSignalPkt */
-#endif /* ifndef EXTMODE_DISABLESIGNALMONITORING */
-
-
-#ifndef EXTMODE_DISABLESIGNALMONITORING
-/* Function: ProcessCancelLoggingArmTriggerPkt ===========================================
- * Receive and process the EXT_CANCEL_LOGGING or EXT_ARM_TRIGGER packet.
- */
-PRIVATE boolean_T ProcessCancelLoggingArmTriggerPkt(const ExtModeAction ACTION_ID,
- const int pktSize,
- int_T numSampTimes)
-{
- const char *pkt;
- int32_T upInfoIdx;
- boolean_T error = EXT_NO_ERROR;
-
- pkt = GetPkt(pktSize);
- if (pkt == NULL) {
- SendResponseStatus(ACTION_ID, NOT_ENOUGH_MEMORY, -1);
- return(EXT_ERROR);
- }
-
- (void)memcpy(&upInfoIdx, pkt, sizeof(int32_T)); /* Extract upInfoIdx */
-
- switch(ACTION_ID) {
- case EXT_CANCEL_LOGGING_RESPONSE:
-#ifndef EXTMODE_DISABLEPRINTF
- PRINT_VERBOSE(
- ("got EXT_CANCEL_LOGGING packet for upInfoIdx : %d\n", upInfoIdx));
-#endif
- UploadCancelLogging(upInfoIdx);
- break;
- case EXT_ARM_TRIGGER_RESPONSE:
-#ifndef EXTMODE_DISABLEPRINTF
- PRINT_VERBOSE(
- ("got EXT_ARM_TRIGGER packet for upInfoIdx : %d\n", upInfoIdx));
-#endif
- UploadArmTrigger(upInfoIdx, numSampTimes);
- break;
- default:
- break;
- }
-
- error = SendResponseStatus(ACTION_ID, STATUS_OK, upInfoIdx);
- return(error); /* Can be EXT_NO_ERROR */
-} /* end ProcessCancelLoggingArmTriggerPkt */
-#endif /* ifndef EXTMODE_DISABLESIGNALMONITORING */
-
-
-#ifdef EXTMODE_DISABLEPARAMETERTUNING
-PRIVATE boolean_T AcknowledgeSetParamPkt(const int pktSize)
-{
- int32_T msg;
- const char *pkt;
- boolean_T error = EXT_NO_ERROR;
-
- pkt = GetPkt(pktSize);
- msg = (int32_T)STATUS_OK;
- error = SendPktToHost(EXT_SETPARAM_RESPONSE, sizeof(int32_T), (char_T *)&msg);
- return(error);
-}
-#endif /* ifdef EXTMODE_DISABLEPARAMETERTUNING */
-
-#ifdef EXTMODE_DISABLESIGNALMONITORING
-PRIVATE boolean_T AcknowledgeSignalActionPkt(const int pktSize, const ExtModeAction ACTION_ID)
-{
- const char *pkt;
- int32_T upInfoIdx;
- boolean_T error = EXT_NO_ERROR;
-
- pkt = GetPkt(pktSize);
- (void)memcpy(&upInfoIdx, pkt, sizeof(int32_T));
- error = SendResponseStatus(ACTION_ID, STATUS_OK, upInfoIdx);
- return(error);
-}
-#endif /* ifdef EXTMODE_DISABLESIGNALMONITORING */
-
-/*********************
- * Visible Functions *
- *********************/
-
-
-/* Function: ExtParseArgsAndInitUD =============================================
- * Abstract:
- * Pass remaining arguments (main program should have NULL'ed out any args
- * that it processed) to external mode.
- *
- * The actual, transport-specific parsing routine (implemented in
- * ext_svr_transport.c) MUST NULL out all entries of argv that it processes.
- * The main program depends on this in order to determine if any unhandled
- * command line options were specified (i.e., if the main program detects
- * any non-null fields after the parse, it throws an error).
- *
- * Returns an error string on failure, NULL on success.
- *
- * NOTES:
- * The external mode UserData is created here so that the specified command-
- * line options can be stored.
- */
-PUBLIC const char_T *ExtParseArgsAndInitUD(const int_T argc,
- const char_T *argv[])
-{
- const char_T *error = NULL;
-
- /*
- * Create the user data.
- */
- extUD = ExtUserDataCreate();
- if (extUD == NULL) {
- error = "Could not create external mode user data. Out of memory.\n";
- goto EXIT_POINT;
- }
-
- /*
- * Parse the transport-specific args.
- */
- error = ExtProcessArgs(extUD,argc,argv);
- if (error != NULL) goto EXIT_POINT;
-
-EXIT_POINT:
- if (error != NULL) {
- ExtUserDataDestroy(extUD);
- extUD = NULL;
- }
- return(error);
-} /* end ExtParseArgsAndInitUD */
-
-
-/* Function: ExtWaitForStartPkt ================================================
- * Abstract:
- * Return true if waiting for host to tell us when to start.
- */
-PUBLIC boolean_T ExtWaitForStartPkt(void)
-{
- return(ExtWaitForStartPktFromHost(extUD));
-} /* end ExtWaitForStartPkt */
-
-
-#ifndef EXTMODE_DISABLESIGNALMONITORING
-/* Function: UploadServerWork =================================================
- * Abstract:
- * Upload model signals to host for a single upInfo.
- */
-void UploadServerWork(int32_T upInfoIdx, int_T numSampTimes)
-{
- int_T i;
- ExtBufMemList upList;
- boolean_T error = EXT_NO_ERROR;
-
-#ifdef VXWORKS
- /*
- * Don't spin the CPU unless we've got data to upload.
- * The upload.c/UploadBufAddTimePoint function gives the sem
- * each time that data is added.
- */
-taskUnsafe();
- semTake(uploadSem, WAIT_FOREVER);
-taskSafe();
-#endif
-
- if (!connected) goto EXIT_POINT;
-
- UploadBufGetData(&upList, upInfoIdx, numSampTimes);
- while(upList.nActiveBufs > 0) {
- for (i=0; i<upList.nActiveBufs; i++) {
- const BufMem *bufMem = &upList.bufs[i];
-
- /*
- * We call SendPktDataToHost() instead of SendPktToHost() because
- * the packet header is combined with packet payload. We do this
- * to avoid the overhead of making two calls for each upload
- * packet - one for the head and one for the payload.
- */
- error = SendPktDataToHost(
- bufMem->section1,
- bufMem->nBytes1);
- if (error != EXT_NO_ERROR) {
-#ifndef EXTMODE_DISABLEPRINTF
- fprintf(stderr,"SendPktDataToHost() failed on data upload.\n");
-#endif
- goto EXIT_POINT;
- }
-
- if (bufMem->nBytes2 > 0) {
-
- error = SendPktDataToHost(
- bufMem->section2,
- bufMem->nBytes2);
- if (error != EXT_NO_ERROR) {
-#ifndef EXTMODE_DISABLEPRINTF
- fprintf(stderr,"SendPktDataToHost() failed on data upload.\n");
-#endif
- goto EXIT_POINT;
- }
- }
- /* confirm that the data was sent */
- UploadBufDataSent(upList.tids[i], upInfoIdx);
- }
- UploadBufGetData(&upList, upInfoIdx, numSampTimes);
- }
-
-EXIT_POINT:
- if (error != EXT_NO_ERROR) {
- /* An error in this function is caused by a physical failure in the
- * external mode connection. We assume this failure caused the host
- * to disconnect. The target must be disconnected and returned to a
- * state where it is running and can be re-connected to by the host.
- */
- ForceDisconnectFromHost(numSampTimes);
- }
-}
-/* end UploadServerWork */
-#endif /* ifndef EXTMODE_DISABLESIGNALMONITORING */
-
-#ifndef EXTMODE_DISABLESIGNALMONITORING
-/* Function: rt_UploadServerWork ===============================================
- * Abstract:
- * Wrapper function that calls UploadServerWork once for each upInfo
- */
-PUBLIC void rt_UploadServerWork(int_T numSampTimes)
-{
- int i;
-
- for (i=0; i<NUM_UPINFOS; i++) {
- UploadServerWork(i, numSampTimes);
- }
-} /* end rt_UploadServerWork */
-#endif /* ifndef EXTMODE_DISABLESIGNALMONITORING */
-
-/* Function: rt_ExtModeInit ====================================================
- * Abstract:
- * Called once at program startup to do any initialization related to external
- * mode.
- */
-PUBLIC boolean_T rt_ExtModeInit(void)
-{
- int i;
- boolean_T error = EXT_NO_ERROR;
-
-#ifdef TMW_EXTMODE_TESTING_REQ
-# ifndef TMW_EXTMODE_TESTING
-#ifndef EXTMODE_DISABLEPRINTF
- fprintf(stderr,"Error: External mode tests should use the external mode test harness.\n");
-#endif
- error = EXT_ERROR;
-# endif
-#endif
- if (error != EXT_NO_ERROR) goto EXIT_POINT;
-
- error = ExtInit(extUD);
- if (error != EXT_NO_ERROR) goto EXIT_POINT;
-
- for (i=0; i<NUM_UPINFOS; i++) {
- UploadLogInfoReset(i);
- }
-
- rtExtModeTestingInit();
-
-EXIT_POINT:
- return(error);
-} /* end rt_ExtModeInit */
-
-
-/* Function: rt_ExtModeSleep ===================================================
- * Abstract:
- * Called by grt_main, ert_main, and grt_malloc_main to "pause". It attempts
- * to do this in a way that does not hog the processor.
- */
-#ifndef VXWORKS
-PUBLIC void rt_ExtModeSleep(
- long sec, /* number of seconds to wait */
- long usec) /* number of micro seconds to wait */
-{
- ExtModeSleep(extUD,sec,usec);
-} /* end rt_ExtModeSleep */
-#endif
-
-
-/* Function: rt_PktServerWork ==================================================
- * Abstract:
- * If not connected, establish communication of the packet line and the
- * data upload line. If connected, send/receive packets and parameters
- * on the packet line.
- */
-PUBLIC void rt_PktServerWork(RTWExtModeInfo *ei,
- int_T numSampTimes,
- boolean_T *stopReq)
-{
- PktHeader pktHdr;
- boolean_T hdrAvail;
- boolean_T error = EXT_NO_ERROR;
- boolean_T disconnectOnError = FALSE;
-
- /*
- * If not connected, attempt to make connection to host.
- */
- if (!connected) {
- rtExtModeTestingKillIfOrphaned(FALSE);
-
- error = ExtOpenConnection(extUD,&connected);
- if (error != EXT_NO_ERROR) goto EXIT_POINT;
- }
-
- /*
- * If ExtOpenConnection is not blocking and there are no pending
- * requests to open a connection, we'll still be unconnected.
- */
- if (!connected) goto EXIT_POINT; /* nothing to do */
-
- /*
- * Process packets.
- */
-
- /* Wait for a packet. */
- error = GetPktHdr(&pktHdr, &hdrAvail);
- if (error != EXT_NO_ERROR) {
-#ifndef EXTMODE_DISABLEPRINTF
- fprintf(stderr, "\nError occurred getting packet header.\n");
-#endif
- disconnectOnError = TRUE;
- goto EXIT_POINT;
- }
- rtExtModeTestingKillIfOrphaned(hdrAvail);
-
- if (!hdrAvail) goto EXIT_POINT; /* nothing to do */
-
- /*
- * This is the first packet. Should contain the string:
- * 'ext-mode'. Its contents are not important to us.
- * It is used as a flag to start the handshaking process.
- */
- if (!commInitialized) {
- pktHdr.type = EXT_CONNECT;
- }
-
- /*
- * At this point we know that we have a packet: process it.
- */
-#ifdef VXWORKS
- taskSafe();
-#endif
- switch(pktHdr.type) {
-
- case EXT_GET_TIME:
- {
- /* Skip verbosity print out - we get too many of these */
- PRINT_VERBOSE(("got EXT_GET_TIME packet.\n"));
- time_T t = rteiGetT(ei);
-
- error = SendPktToHost(
- EXT_GET_TIME_RESPONSE,sizeof(time_T),
- (char_T *)&t);
- if (error != EXT_NO_ERROR) goto EXIT_POINT;
- break;
- }
-
- case EXT_ARM_TRIGGER:
- {
-#ifndef EXTMODE_DISABLESIGNALMONITORING
- error = ProcessCancelLoggingArmTriggerPkt(EXT_ARM_TRIGGER_RESPONSE, pktHdr.size, numSampTimes);
- if (error != EXT_NO_ERROR) goto EXIT_POINT;
-#else
- error = AcknowledgeSignalActionPkt(pktHdr.size, EXT_ARM_TRIGGER_RESPONSE);
- if (error != EXT_NO_ERROR) goto EXIT_POINT;
-#endif
- break;
- }
-
- case EXT_SELECT_SIGNALS:
- {
-#ifndef EXTMODE_DISABLESIGNALMONITORING
- error = ProcessSelectTriggerSignalPkt(EXT_SELECT_SIGNALS_RESPONSE, ei, pktHdr.size, numSampTimes, ERRMSG_PROCESSSELECTSIGNAL);
- if (error != EXT_NO_ERROR) goto EXIT_POINT;
-#else
- error = AcknowledgeSignalActionPkt(pktHdr.size, EXT_SELECT_SIGNALS_RESPONSE);
- if (error != EXT_NO_ERROR) goto EXIT_POINT;
-#endif
- break;
- }
-
- case EXT_SELECT_TRIGGER:
- {
-#ifndef EXTMODE_DISABLESIGNALMONITORING
- error = ProcessSelectTriggerSignalPkt(EXT_SELECT_TRIGGER_RESPONSE, ei, pktHdr.size, -1, ERRMSG_PROCESSSELECTTRIGGER);
- if (error != EXT_NO_ERROR) goto EXIT_POINT;
-#else
- error = AcknowledgeSignalActionPkt(pktHdr.size, EXT_SELECT_TRIGGER_RESPONSE);
- if (error != EXT_NO_ERROR) goto EXIT_POINT;
-#endif
- break;
- }
-
- case EXT_CONNECT:
- {
- PRINT_VERBOSE(("got EXT_CONNECT packet.\n"));
- error = ProcessConnectPkt(ei);
- if (error != EXT_NO_ERROR) goto EXIT_POINT;
- break;
- }
-
- case EXT_SETPARAM:
- {
-#ifndef EXTMODE_DISABLEPARAMETERTUNING
- PRINT_VERBOSE(("got EXT_SETPARAM packet.\n"));
- error = ProcessSetParamPkt(ei, pktHdr.size);
- if (error != EXT_NO_ERROR) goto EXIT_POINT;
-#else
- PRINT_VERBOSE(("discard EXT_SETPARAM packet.\n"));
- error = AcknowledgeSetParamPkt(pktHdr.size);
- if (error != EXT_NO_ERROR) goto EXIT_POINT;
-#endif
- break;
- }
-
- case EXT_GETPARAMS:
- {
-#ifndef EXTMODE_DISABLEPARAMETERTUNING
- PRINT_VERBOSE(("got EXT_GETPARAMS packet.\n"));
- error = ProcessGetParamsPkt(ei);
- if (error != EXT_NO_ERROR) goto EXIT_POINT;
-#endif
- break;
- }
-
- case EXT_DISCONNECT_REQUEST:
- {
- PRINT_VERBOSE(("got EXT_DISCONNECT_REQUEST packet.\n"));
-
- /*
- * Note that from the target's point of view this is
- * more a "notify" than a "request". The host needs to
- * have this acknowledged before it can begin closing
- * the connection.
- */
- error = SendPktToHost(EXT_DISCONNECT_REQUEST_RESPONSE, 0, NULL);
- if (error != EXT_NO_ERROR) goto EXIT_POINT;
-
- DisconnectFromHost(numSampTimes);
-
- break;
- }
-
- case EXT_DISCONNECT_REQUEST_NO_FINAL_UPLOAD:
- {
- PRINT_VERBOSE(("got EXT_DISCONNECT_REQUEST_NO_FINAL_UPLOAD packet.\n"));
-
- /*
- * The target receives this packet when the host is
- * immediately terminating the extmode communication due
- * to some error. The target should not send back a
- * response or a final upload of data because the host is
- * expecting neither. The target must be disconnected and
- * returned to a state where it is running and can be
- * re-connected to by the host.
- */
- ForceDisconnectFromHost(numSampTimes);
-
- break;
- }
-
- case EXT_MODEL_START:
- PRINT_VERBOSE(("got EXT_MODEL_START packet.\n"));
-#ifdef VXWORKS
- {
- extern SEM_ID startStopSem;
- semGive(startStopSem);
- }
-#endif
- startModel = TRUE;
- error = SendPktToHost(EXT_MODEL_START_RESPONSE, 0, NULL);
- if (error != EXT_NO_ERROR) goto EXIT_POINT;
- break;
-
- case EXT_MODEL_STOP:
- PRINT_VERBOSE(("got EXT_MODEL_STOP packet.\n"));
- *stopReq = TRUE;
- break;
-#ifndef EXTMODE_DISABLETESTING
- case EXT_MODEL_PAUSE:
- PRINT_VERBOSE(("got EXT_MODEL_PAUSE packet.\n"));
- modelStatus = TARGET_STATUS_PAUSED;
- startModel = FALSE;
-
- error = SendPktToHost(EXT_MODEL_PAUSE_RESPONSE, 0, NULL);
- if (error != EXT_NO_ERROR) goto EXIT_POINT;
- break;
- case EXT_MODEL_STEP:
- PRINT_VERBOSE(("got EXT_MODEL_STEP packet.\n"));
- if ((modelStatus == TARGET_STATUS_PAUSED) && !startModel) {
- startModel = TRUE;
- }
-
- error = SendPktToHost(EXT_MODEL_STEP_RESPONSE, 0, NULL);
- if (error != EXT_NO_ERROR) goto EXIT_POINT;
- break;
- case EXT_MODEL_CONTINUE:
- PRINT_VERBOSE(("got EXT_MODEL_CONTINUE packet.\n"));
- if (modelStatus == TARGET_STATUS_PAUSED) {
- modelStatus = TARGET_STATUS_RUNNING;
- startModel = FALSE;
- }
-
- error = SendPktToHost(EXT_MODEL_CONTINUE_RESPONSE, 0, NULL);
- if (error != EXT_NO_ERROR) goto EXIT_POINT;
-#endif
- break;
-
- case EXT_CANCEL_LOGGING:
- {
-#ifndef EXTMODE_DISABLESIGNALMONITORING
- error = ProcessCancelLoggingArmTriggerPkt(EXT_CANCEL_LOGGING_RESPONSE, pktHdr.size, numSampTimes);
- if (error != EXT_NO_ERROR) goto EXIT_POINT;
-#else
- error = AcknowledgeSignalActionPkt(pktHdr.size, EXT_CANCEL_LOGGING_RESPONSE);
- if (error != EXT_NO_ERROR) goto EXIT_POINT;
-#endif
- break;
- }
-
- default:
-#ifndef EXTMODE_DISABLEPRINTF
- fprintf(stderr,"received invalid packet.\n");
-#endif
- break;
- } /* end switch */
-
-EXIT_POINT:
- if (error != EXT_NO_ERROR) {
- if (disconnectOnError) {
-#ifndef EXTMODE_DISABLEPRINTF
- fprintf(stderr,
- "Error occurred in rt_PktServerWork.\n"
- "Disconnecting from host!\n");
-#endif
- /* An error in this function which causes disconnectOnError to be
- * set to true is caused by a physical failure in the external mode
- * connection. We assume this failure caused the host to disconnect.
- * The target must be disconnected and returned to a state
- * where it is running and can be re-connected to by the host.
- */
- ForceDisconnectFromHost(numSampTimes);
- }
- }
-#ifdef VXWORKS
- taskUnsafe();
-#endif
-} /* end rt_PktServerWork */
-
-
-/* Function: rt_PktServer ======================================================
- * Abstract:
- * Call rt_PktServerWork forever. Used only for RTOS (e.g., Tornado/VxWorks
- * when running as a low priority task.
- */
-#ifdef VXWORKS
-PUBLIC void rt_PktServer(RTWExtModeInfo *ei,
- int_T numSampTimes,
- boolean_T *stopReq)
-{
- for(;;) {
- rt_PktServerWork(ei,numSampTimes,stopReq);
- }
-}
-#endif
-
-
-/* Function: rt_UploadServer ===================================================
- * Abstract:
- * Call rt_UploadServerWork forever. Used only for RTOS (e.g.,
- * Tornado/VxWorks when running as a low priority task.
- */
-#ifdef VXWORKS
-#ifndef EXTMODE_DISABLESIGNALMONITORING
-PUBLIC void rt_UploadServer(int_T numSampTimes)
-{
- for(;;) {
- rt_UploadServerWork(numSampTimes);
- }
-} /* end rt_UploadServer */
-#endif /* ifndef EXTMODE_DISABLESIGNALMONITORING */
-#endif
-
-
-/* Function: rt_SetPortInExtUD =================================================
- * Abstract:
- * Set the port in the external mode user data structure.
- */
-#ifdef VXWORKS
-PUBLIC void rt_SetPortInExtUD(const int_T port)
-{
- ExtUserDataSetPort(extUD, port);
-} /* end rt_SetPortInExtUD */
-#endif
-
-/* Function: ExtModeShutdown ==================================================
- * Abstract:
- * Called when target program terminates to enable cleanup of external
- * mode for a given upInfo.
- */
-PRIVATE void ExtModeShutdown(int32_T upInfoIdx, int_T numSampTimes)
-{
- /*
- * 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 uploading is in progress).
- */
- UploadPrepareForFinalFlush(upInfoIdx);
-#ifndef EXTMODE_DISABLESIGNALMONITORING
- UploadServerWork(upInfoIdx, numSampTimes);
-#endif
-
- UploadLogInfoTerm(upInfoIdx, numSampTimes);
-
- if (pktBuf != NULL) {
- free(pktBuf);
- pktBuf = NULL;
- }
-
-} /* end ExtModeShutdown */
-
-/* Function: rt_ExtModeShutdown ================================================
- * Abstract:
- * Called when target program terminates to enable cleanup of external
- * mode.
- */
-PUBLIC boolean_T rt_ExtModeShutdown(int_T numSampTimes)
-{
- int i;
- boolean_T error = EXT_NO_ERROR;
-
- for (i=0; i<NUM_UPINFOS; i++) {
- ExtModeShutdown(i, numSampTimes);
- }
-
- if (commInitialized) {
- error = SendPktToHost(EXT_MODEL_SHUTDOWN, 0, NULL);
- if (error != EXT_NO_ERROR) {
-#ifndef EXTMODE_DISABLEPRINTF
- fprintf(stderr,
- "\nError sending EXT_MODEL_SHUTDOWN packet to host.\n");
-#endif
- }
- commInitialized = FALSE;
- }
- if (connected) {
- connected = FALSE;
- modelStatus = TARGET_STATUS_WAITING_TO_START;
- }
-
- ExtShutDown(extUD);
- ExtUserDataDestroy(extUD);
-
- rtExtModeTestingRemoveBatMarker();
-
- return(error);
-} /* end rt_ExtModeShutdown */
-
-#ifndef EXTMODE_DISABLESIGNALMONITORING
-/* Function: rt_UploadCheckTrigger =============================================
- * Abstract:
- * Wrapper function that calls UploadCheckTrigger once for each upInfo
- */
-PUBLIC void rt_UploadCheckTrigger(int_T numSampTimes)
-{
- int i;
- for (i=0; i<NUM_UPINFOS; i++) {
- UploadCheckTrigger(i, numSampTimes);
- }
-} /* end rt_UploadCheckTrigger */
-
-/* Function: rt_UploadCheckEndTrigger ==========================================
- * Abstract:
- * Wrapper function that calls UploadCheckTrigger once for each upInfo
- */
-PUBLIC void rt_UploadCheckEndTrigger(void)
-{
- int i;
-
- for (i=0; i<NUM_UPINFOS; i++) {
- UploadCheckEndTrigger(i);
- }
-} /* end rt_UploadCheckEndTrigger */
-
-/* Function: rt_UploadBufAddTimePoint ==========================================
- * Abstract:
- * Wrapper function that calls UploadBufAddTimePoint once for each upInfo
- */
-PUBLIC void rt_UploadBufAddTimePoint(int_T tid, real_T taskTime)
-{
- int i;
-
- for (i=0; i<NUM_UPINFOS; i++) {
- UploadBufAddTimePoint(tid, taskTime, i);
- }
-} /* end rt_UploadBufAddTimePoint */
-#endif /* ifndef EXTMODE_DISABLESIGNALMONITORING */
-
-/* [EOF] ext_svr.c */