📄 ext_main.c
字号:
/*
* Copyright 1994-2001 The MathWorks, Inc.
*
* File: ext_main.c $Revision: 1.18 $
*
* Abstract:
* MEX glue for the mechanism to communicate with an externally running, RTW-
* generated program. Mechanisms are provided to:
*
* o download block parameters to the external program
* o upload data from the external program to Simulink
* o control the target program
*/
#include <windows.h> /* Sleep -- fw-03-05 */
#include "extsim.h" /* ext_mode data struct */
#include "ext_transport232.h" /* macro COMBUFSIZE */
/*
* Debugging print statement.
*/
#define EXT_MAIN_DEBUG (0)
#if EXT_MAIN_DEBUG
#define PRINTD(args) mexPrintf args
#else
#define PRINTD(args) /* do nothing */
#endif
/* Function: ExtCommMain =======================================================
* Abstract:
* Main entry point for external communications processing.
*/
PRIVATE void ExtCommMain(
int nlhs,
mxArray *plhs[],
int nrhs,
const mxArray *prhs[])
{
ExternalSim *ES;
/*
* Simulink directly passes a pointer to the ExternalSim data structure
* in the plhs array.
*/
if (nlhs == -1) {
ES = (ExternalSim *)plhs;
if (((int *)ES)[0] != EXTSIM_VERSION) {
esSetError(ES,
"\nThe version of the 'ExternalSim' structure passed by "
"Simulink and the version of the structure used by ext_main.c "
"are not consistent. The mex file is either out of date or "
"built with structure alignment not equal to 8. Ensure that "
"the external mode mex file was built using the include file: "
"<matlabroot>/rtw/ext_mode/extsim.h\n.");
goto EXIT_POINT;
}
/*
* Provide Simulink with a direct pointer to this function so that
* subsequent calls can be made more efficiently. Do not set this
* if your version of ext_comm is not "exception free" as described
* in the documentation for Simulink S-functions.
* See <matlabroot>/simulink/src/sfuntmpl_doc.c.
*/
esSetMexFuncGateWayFcn(ES,ExtCommMain);
} else {
mexPrintf("This external mex file is used by Simulink in external "
"mode\nfor communicating with Real-Time Workshop targets "
"using interprocess communications.\n");
goto EXIT_POINT;
}
/*
* Dispatch the message to appropriate routine in ext_comm.c.
*/
switch(esGetAction(ES)) {
case EXT_CONNECT:
/* Connect to target. */
if (esGetVerbosity(ES))
mexPrintf("action: EXT_CONNECT\n");
/* Initialise user communication buffers (defined in 's0_usertel_rxd.c') -- (FW-01-03) */
Init_ComVars();
/* initialise model state variables */
#ifdef MODELSTUCK
ModelIsRunning = 0;
NoDataPending = 0;
alarmCounter = 0;
#endif
ExtConnect(ES, nrhs, prhs);
break;
case EXT_DISCONNECT_REQUEST:
/* Request to terminate communication has been made - notify target. */
if (esGetVerbosity(ES))
mexPrintf("action: EXT_DISCONNECT_REQUEST\n");
/* disable download of user telegrams */
user_comm_enable = 0;
#if DEBUG_MSG_LVL >= 2
{
int_T i;
mexPrintf("EXT_DISCONNECT_REQUEST: user_comm_enable = 0\n");
for(i=0; i<num_user_channels_active; i++) {
mexPrintf("buffer_full[%d] = %d\n", user_txd_queue[i], userTelBuf[user_txd_queue[i]]->buffer_full);
}
}
#endif
ExtDisconnectRequest(ES, nrhs, prhs);
/* wait a second... otherwise, Simulink may crash (fw-03-05) */
//Sleep(1000);
break;
case EXT_DISCONNECT_CONFIRMED:
/* Terminate communication with target. */
if (esGetVerbosity(ES))
mexPrintf("action: EXT_DISCONNECT_CONFIRMED\n");
ExtDisconnectConfirmed(ES, nrhs, prhs);
break;
case EXT_SETPARAM:
/* Download parameters to be set on target. */
if (esGetVerbosity(ES))
mexPrintf("action: EXT_SETPARAM\n");
{
/* ensure that the communication buffers are sufficiently large */
uint_T requiredCBS = esGetCommBufSize(ES);
if(requiredCBS > COMBUFSIZE) {
/* alert user */
mexPrintf("\next_comm: Attempting to download a parameter set of %d bytes.\n", requiredCBS);
mexPrintf(" This exceeds the current size of the host communication buffers (%d bytes).\n", COMBUFSIZE);
mexPrintf(" Increase parameter COMBUFSIZE in 'ext_mode/ext_transport232.h' as well as the\n");
mexPrintf(" corresponding parameter RBUFSIZE in 'mc/mc_main.c' (1024 bytes) and recompile both host and target communication\n");
mexPrintf(" modules. To recompile the host communication library run MATLAB script file 'remex'. This should also copy the \n");
mexPrintf(" newly created library 'ext_comm.dll' to the appropriate system folder. You may have to restart MATLAB prior to\n");
mexPrintf(" running 'remex.m' (otherwise, MATLAB can't copy the newly created library file -- file locking...).\n");
esSetError(ES, "Insufficient buffer size (serial communication). See workspace window for details.\n");
goto EXIT_POINT;
}
}
ExtSendGenericMsg(ES, nrhs, prhs);
// #if DEBUG_MSG_LVL >= 4
// mexPrintf("Ext_main: aborted by the user\n");
// esSetError(ES, "Ext_main: aborted by the user\n");
// goto EXIT_POINT;
// #endif
break;
case EXT_GETPARAMS:
/* Upload interfaceable variables from target. */
if (esGetVerbosity(ES))
mexPrintf("action: EXT_GETPARAMS\n");
ExtGetParams(ES, nrhs, prhs);
break;
case EXT_SELECT_SIGNALS:
/* Select signals for data uploading. */
if (esGetVerbosity(ES))
mexPrintf("action: EXT_SELECT_SIGNALS\n");
ExtSendGenericMsg(ES, nrhs, prhs);
break;
case EXT_SELECT_TRIGGER:
/* Select signals for data uploading. */
if (esGetVerbosity(ES))
mexPrintf("action: EXT_SELECT_TRIGGER\n");
ExtSendGenericMsg(ES, nrhs, prhs);
break;
case EXT_ARM_TRIGGER:
/* Select signals for data uploading. */
if (esGetVerbosity(ES))
mexPrintf("action: EXT_ARM_TRIGGER\n");
/* enable download of user telegrams */
user_comm_enable = 1;
#if DEBUG_MSG_LVL >= 2
{
int_T i;
mexPrintf("EXT_ARM_TRIGGER: user_comm_enable = 1\n");
for(i=0; i<num_user_channels_active; i++) {
mexPrintf("buffer_full[%d] = %d\n", user_txd_queue[i], userTelBuf[user_txd_queue[i]]->buffer_full);
}
}
#endif
ExtSendGenericMsg(ES, nrhs, prhs);
/* wait a second... otherwise, Simulink may crash (fw-03-05) */
//Sleep(1000);
break;
case EXT_CANCEL_LOGGING:
/* Send message to target to cancel the current data loggin session. */
if (esGetVerbosity(ES))
mexPrintf("action: EXT_CANCEL_LOGGING\n");
/* disable download of user telegrams */
user_comm_enable = 0;
#if DEBUG_MSG_LVL >= 2
{
int_T i;
mexPrintf("EXT_CANCEL_LOGGING: user_comm_enable = 0\n");
for(i=0; i<num_user_channels_active; i++) {
mexPrintf("buffer_full[%d] = %d\n", user_txd_queue[i], userTelBuf[user_txd_queue[i]]->buffer_full);
}
}
#endif
ExtSendGenericMsg(ES, nrhs, prhs);
/* wait a second... otherwise, Simulink may crash (fw-03-05) */
//Sleep(1000);
return;
break;
case EXT_MODEL_START:
/* Start the external simulation. */
if (esGetVerbosity(ES))
mexPrintf("action: EXT_MODEL_START\n");
/* enable download of user telegrams */
user_comm_enable = 1;
#if DEBUG_MSG_LVL >= 2
{
int_T i;
mexPrintf("EXT_MODEL_START: user_comm_enable = 1\n");
for(i=0; i<num_user_channels_active; i++) {
mexPrintf("buffer_full[%d] = %d\n", user_txd_queue[i], userTelBuf[user_txd_queue[i]]->buffer_full);
}
}
#endif
#ifdef MODELSTUCK
ModelIsRunning = 1;
#endif
ExtSendGenericMsg(ES, nrhs, prhs);
break;
case EXT_MODEL_STOP:
/* Stop the external simulation and kill target program. */
if (esGetVerbosity(ES))
mexPrintf("action: EXT_MODEL_STOP\n");
/* disable download of user telegrams */
user_comm_enable = 0;
#if DEBUG_MSG_LVL >= 2
{
int_T i;
mexPrintf("EXT_MODEL_STOP: user_comm_enable = 0\n");
for(i=0; i<num_user_channels_active; i++) {
mexPrintf("buffer_full[%d] = %d\n", user_txd_queue[i], userTelBuf[user_txd_queue[i]]->buffer_full);
}
}
#endif
ExtSendGenericMsg(ES, nrhs, prhs);
/* wait a second... otherwise, Simulink may crash (fw-03-05) */
//Sleep(1000);
break;
case EXT_MODEL_PAUSE:
/* Pause the target (grt only). */
if (esGetVerbosity(ES))
mexPrintf("action: EXT_MODEL_PAUSE\n");
/* disable download of user telegrams */
user_comm_enable = 0;
#if DEBUG_MSG_LVL >= 2
{
int_T i;
mexPrintf("EXT_MODEL_PAUSE: user_comm_enable = 0\n");
for(i=0; i<num_user_channels_active; i++) {
mexPrintf("buffer_full[%d] = %d\n", user_txd_queue[i], userTelBuf[user_txd_queue[i]]->buffer_full);
}
}
#endif
ExtSendGenericMsg(ES, nrhs, prhs);
break;
case EXT_MODEL_STEP:
/* Run the model for 1 step - if paused (grt only). */
if (esGetVerbosity(ES))
mexPrintf("action: EXT_MODEL_STEP\n");
/* enable download of user telegrams */
user_comm_enable = 1;
#if DEBUG_MSG_LVL >= 2
{
int_T i;
mexPrintf("EXT_MODEL_STEP: user_comm_enable = 1\n");
for(i=0; i<num_user_channels_active; i++) {
mexPrintf("buffer_full[%d] = %d\n", user_txd_queue[i], userTelBuf[user_txd_queue[i]]->buffer_full);
}
}
#endif
ExtSendGenericMsg(ES, nrhs, prhs);
break;
case EXT_MODEL_CONTINUE:
/* Run the model for 1 step - if paused (grt only). */
if (esGetVerbosity(ES))
mexPrintf("action: EXT_MODEL_CONTINUE\n");
/* enable download of user telegrams */
user_comm_enable = 1;
#if DEBUG_MSG_LVL >= 2
{
int_T i;
mexPrintf("EXT_MODEL_CONTINUE: user_comm_enable = 1\n");
for(i=0; i<num_user_channels_active; i++) {
mexPrintf("buffer_full[%d] = %d\n", user_txd_queue[i], userTelBuf[user_txd_queue[i]]->buffer_full);
}
}
#endif
ExtSendGenericMsg(ES, nrhs, prhs);
break;
case EXT_GET_TIME:
/*
* Request the sim time from the target.
*
* NOTE:
* Skip verbosity. There are too many of these messages when
* autoupdating Simulink's status bar clock.
*/
if (esGetVerbosity(ES))
mexPrintf("action: EXT_GET_TIME\n");
ExtSendGenericMsg(ES, nrhs, prhs);
break;
/* FW-12-02 */
case EXT_RESET_SER_BUFFER_REQUEST:
#if DEBUG_MSG_LVL >= 2
mexPrintf("RequestDataTelegram: received request to clear COM serial buffer (re-synchronisation).\n");
mexPrintf("RequestDataTelegram: uploading diagnostic information...\n");
#endif
{
UserData *userData = (UserData *)esGetUserData(ES);
MsgHeader msgHdr;
boolean_T error = EXT_NO_ERROR;
int nGot = 0;
error = ExtGetTargetMsg(ES,sizeof(msgHdr),&nGot,(char_T *)&msgHdr);
if (error || (nGot != sizeof(msgHdr))) {
mexPrintf("RequestDataTelegram: error due to nGot != 8\n");
esSetError(ES, "ExtGetTargetMsg() call failed while checking target msg's\n");
}
#if DEBUG_MSG_LVL >= 2
mexPrintf("RequestDataTelegram: Errornous message: %d size %d\n",msgHdr.type,msgHdr.size);
#endif
/* reset COM output buffer */
#if DEBUG_MSG_LVL >= 2
printf("RequestDataTelegram: Clearing COM output buffer.\n");
#endif
PurgeComm(userData->hCom, PURGE_TXCLEAR);
}
break;
default:
esSetError(ES,"\nUnrecognized external communication action.");
goto EXIT_POINT;
} /* end switch */
EXIT_POINT:
return;
} /* end ExtCommMain */
/* Function: mexFunction =======================================================
* Abstract:
* Gateway from Matlab.
*/
void mexFunction(
int nlhs,
mxArray *plhs[],
int nrhs,
const mxArray *prhs[])
{
ExtCommMain(nlhs,plhs,nrhs,prhs);
} /* end mexFunction */
/* [EOF] ext_main.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -