📄 mc_main.c
字号:
/* Author : Raul Murillo, Frank Wornle
*
* File : mc_main.c (adapted from grt_main.c)
*
* Abstract:
* A Generic "Real-Time (single tasking or pseudo-multitasking,
* statically allocated data)" main that runs under most
* operating systems.
*
* Compiler specified defines:
* RT - Required.
* MODEL=modelname - Required.
* NUMST=# - Required. Number of sample times.
* NCSTATES=# - Required. Number of continuous states.
* TID01EQ=1 or 0 - Optional. Only define to 1 if sample time task
* id's 0 and 1 have equal rates.
* MULTITASKING - Optional. (use MT for a synonym).
* SAVEFILE - Optional (non-quoted) name of .mat file to create.
* Default is <MODEL>.mat
*/
/* modifications: (FW-02-03)
*
* (1) added target specific headers
* (2) removed unused header file rt_logging.h
* (3) removed unused conditional code sections (BORLAND)
* (4) added external mode header files
* (5) added 'extern' declarations to 'startModel' and 'TargetSimStatus'
* (6) removed variable GBLbuf (not used anymore) -- also removed all related references
* (7) added memory management variable 'pool'
* (8) added variables rtInf, rtMinusInf and rtNaN
* (9) added target specific macros (e. g. TIMING, RBUFSIZE, ...)
* (10) added TIMING macros to local function rtOneStep() and removed call to rtExtModeOneStep() [-> main()]
* (11) added local function Init_ComVars(), used to initialise the optional user communication
* (12) added local function init_c167()
* (13) introduced local functions model_init(), model_run() and model_clean() to improve
* the overall readability of the code. These functions are sections which previously
* belonged to main(); notice that rtExtModePauseIfNeeded has been disabled (this resets 'startModel' -> unwanted)
* (14) added local function init_timebase() and the corresponding interrupt service handler
* isr_timer1() [respectively isr_timer2() - if we're using cascaded timers]
* (15) adapted main() to call upon all previously defined local functions
*
*/
/* Microcontroller specific and system headers */
#include <mc9s12dp256.h> /* port definitions etc. */
#include <float.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* System macros (EXT_MODE, etc.) -- generated by 'gen_cpp_req_defines_h.tlc' */
#include "cpp_req_defines.h"
/* RTW headers */
#include "tmwtypes.h"
#include "rtmodel.h" /* this replaces 'simstruct.h' in R13 (cf. 'RTW 5.0 Release Notes: Upgrading...') */
#include "rt_sim.h"
//#include "rt_logging.h" /* this replaces 'rtw/c/src/rtwlog.h' (in rtw/c/libsrc; unused -> rem: FW-02-03) */
#include "rt_nonfinite.h"
#include "ext_work.h"
/* External Mode headers */
#ifdef EXT_MODE
#include "ext_svr.h" /* rt_ExtModeInit() */
#include "ext_share.h" /* included here 'coz it (re-)defines PUBLIC as 'empty' (cf. ext_svr_transport.h) */
#include "ext_svr_transport.h" /* *RecBufPtr, ExtInit(), put_data_buffer() */
#include "s0_usertel.h" /* global user communication admin variables (defined in ext_srv.c) */
#endif
#ifdef LCDUSE4ERRORS
#include "lcd.h" /* LCD_init() */
#endif
/* Toolbox headers */
#include "mc_signal.h" /* abort_LED, SCIx_Init, etc. */
#include "mc_timer.h" /* Init_timebase, ECT_Init, ECT_Start, etc. */
#include "pll.h" /* _SYSCLK etc. */
/*
* Free communication port
*/
#include "freePortComms.h" /* global FreePort communication admin variables */
/*
* Radio communication port
*/
#include "radioComms.h" /* global RF communication admin variables */
/*=========*
* Defines *
*=========*/
#ifndef TRUE
#define FALSE (0)
#define TRUE (1)
#endif
#ifndef EXIT_FAILURE
#define EXIT_FAILURE 1
#endif
#ifndef EXIT_SUCCESS
#define EXIT_SUCCESS 0
#endif
#define QUOTE1(name) #name
#define QUOTE(name) QUOTE1(name) /* need to expand name */
#ifndef RT
# error "must define RT"
#endif
#ifndef MODEL
# error "must define MODEL"
#endif
#ifndef NUMST
# error "must define number of sample times, NUMST"
#endif
#ifndef NCSTATES
# error "must define NCSTATES"
#endif
#ifndef SAVEFILE
# define MATFILE2(file) #file ".mat"
# define MATFILE1(file) MATFILE2(file)
# define MATFILE MATFILE1(MODEL)
#else
# define MATFILE QUOTE(SAVEFILE)
#endif
#define RUN_FOREVER -1.0
/* new in R13: this needs to be included to register the model name in rtModel (formerly: SimStruct) */
#define EXPAND_CONCAT(name1,name2) name1 ## name2
#define CONCAT(name1,name2) EXPAND_CONCAT(name1,name2)
#define RT_MODEL CONCAT(MODEL,_rtModel)
/*====================*
* External functions *
*====================*/
/* new in R13: this used to be the declaration 'extern SimStruct *MODEL(void)' */
extern RT_MODEL *MODEL(void);
extern void MdlInitializeSizes(void);
extern void MdlInitializeSampleTimes(void);
extern void MdlStart(void);
extern void MdlOutputs(int_T tid);
extern void MdlUpdate(int_T tid);
extern void MdlTerminate(void);
#if NCSTATES > 0
extern void rt_ODECreateIntegrationData(RTWSolverInfo *si);
extern void rt_ODEUpdateContinuousStates(RTWSolverInfo *si);
# define rt_CreateIntegrationData(S) \
rt_ODECreateIntegrationData(rtmGetRTWSolverInfo(S));
# define rt_UpdateContinuousStates(S) \
rt_ODEUpdateContinuousStates(rtmGetRTWSolverInfo(S));
# else
# define rt_CreateIntegrationData(S) \
rtsiSetSolverName(rtmGetRTWSolverInfo(S),"FixedStepDiscrete");
# define rt_UpdateContinuousStates(S) \
rtmSetT(S, rtsiGetSolverStopTime(rtmGetRTWSolverInfo(S)));
#endif
/*==================================*
* Global data local to this module *
*==================================*/
/* The structure RT_MODEL replaces the previously used SimStruct... (R13)
* Originally defined locally [in main()]. Now defined globally to provide access from within
* model_init(), model_run() and model_clean()
*/
static RT_MODEL *S;
/* new in R13: defined in 'ext_work.c', here only referenced */
#ifdef EXT_MODE
extern int_T volatile startModel;
extern TargetSimStatus volatile modelStatus;
#endif
// DEFINE global freePort communication admin variables ( initialised in mc_main->Init_ComVars() )
myUsrBuf *freecomTelBuf[MAX_FREECOM_CHANNELS];
#if (HAS_RFCOMMS > 0)
// DEFINE global radioComm communication admin variables ( initialised in mc_main->Init_ComVars() )
myUsrBuf *radiocomTelBuf[MAX_RADIOCOM_CHANNELS];
#endif
/* defining RUN_IMMEDIATELY builds code that doesn't wait for a start message */
/* fw-10-05 */
#ifdef RUN_IMMEDIATELY
/* flag to determine if this is the 'first run' following a power-up reset */
static unsigned int RunningAfterPowerUpReset = 1;
#endif
/* modification of grt_main (FW-02-03) */
//static struct {
// int_T stopExecutionFlag;
// int_T isrOverrun;
// int_T overrunFlags[NUMST];
// const char_T *errmsg;
//} GBLbuf;
/* rt_InitInfAndNaN (grt_main.c) does not compile correctly with the KEIL C166 (V3.11)
* -> lack of 32-bit data type for bit manipulations. This workaround uses the 4 byte
* float data type of the compiler (IEEE standard, little endian format).
* (taken from: S. Rebeschiess - mircos/mc_funct.c)
*/
real_T rtInf = 0x7f800000;
real_T rtMinusInf = 0xff800000;
real_T rtNaN = 0x7fffffff;
/* ======================= *
* target specific defines *
* ======================= */
#ifdef EXT_MODE
# define rtExtModeSingleTaskUpload(S) \
{ \
int stIdx; \
rtExtModeUploadCheckTrigger(); \
for (stIdx=0; stIdx<NUMST; stIdx++) { \
if (rtmIsSampleHit(S, stIdx, 0 /*unused*/)) { \
rtExtModeUpload(stIdx,rtmGetTaskTime(S,stIdx)); \
} \
} \
}
#else
# define rtExtModeSingleTaskUpload(S) /* Do nothing */
#endif
/*=================*
* Local functions *
*=================*/
/* note that simstruc_types.h undefines MULTITASKING if it has been defined as MULTITASKING = 0 */
/* (see cpp_req_defines.h -- fw-02-05 */
#ifndef MULTITASKING /* SINGLETASKING */
/* Function: rtOneStep ========================================================
*
* Abstract:
* Perform one step of the model. This function is modeled such that
* it could be called from an interrupt service routine (ISR) with minor
* modifications.
*/
static void rt_OneStep(void) {
real_T tnext;
/***********************************************
* Check and see if base step time is too fast *
***********************************************/
/* modification of grt_main (FW-02-03) */
// if (GBLbuf.isrOverrun++) {
// GBLbuf.stopExecutionFlag = 1;
// return;
// }
/***********************************************
* Check and see if error status has been set *
***********************************************/
/* modification of grt_main (FW-02-03) */
// if (rtmGetErrorStatus(S) != NULL) {
// GBLbuf.stopExecutionFlag = 1;
// return;
// }
/* modification of grt_main (FW-02-03) */
// /* new in R13: call to rt_MsgServerWork() and rt_UploadServerWork() */
// rtExtModeOneStep(rtmGetRTWExtModeInfo(S),
// (boolean_T *)&rtmGetStopRequested(S));
tnext = rt_SimGetNextSampleHit();
rtsiSetSolverStopTime(rtmGetRTWSolverInfo(S),tnext);
MdlOutputs(0);
/* new in R13: this macro comprises all upload related lines (cf. R12.1) */
/* the macro is defined in this file */
rtExtModeSingleTaskUpload(S);
/* modification of grt_main (FW-02-03) */
// GBLbuf.errmsg = rt_UpdateTXYLogVars(rtmGetRTWLogInfo(S),
// rtmGetTPtr(S));
// if (GBLbuf.errmsg != NULL) {
// GBLbuf.stopExecutionFlag = 1;
// return;
// }
MdlUpdate(0);
rt_SimUpdateDiscreteTaskSampleHits(rtmGetNumSampleTimes(S),
rtmGetTimingData(S),
rtmGetSampleHitPtr(S),
rtmGetTPtr(S));
if (rtmGetSampleTime(S,0) == CONTINUOUS_SAMPLE_TIME) {
rt_UpdateContinuousStates(S);
}
/* modification of grt_main (FW-02-03) */
// GBLbuf.isrOverrun--;
/* R13 replacement of UploadCheckEndTrigger, see wrapper in ext_work.c */
rtExtModeCheckEndTrigger();
/* modification of grt_main (FW-02-03) */
#ifdef EXT_MODE
put_data_buffer();
#endif
} /* end rtOneStep */
#else /* MULTITASKING */
# if TID01EQ == 1
# define FIRST_TID 1
# else
# define FIRST_TID 0
# endif
/* Function: rtOneStep ========================================================
*
* Abstract:
* Perform one step of the model. This function is modeled such that
* it could be called from an interrupt service routine (ISR) with minor
* modifications.
*
* This routine is modeled for use in a multitasking environment and
* therefore needs to be fully re-entrant when it is called from an
* interrupt service routine.
*
* Note:
* Error checking is provided which will only be used if this routine
* is attached to an interrupt.
*
*/
static void rt_OneStep(void)
{
int_T eventFlags[NUMST];
int_T i;
real_T tnext;
int_T *sampleHit = rtmGetSampleHitPtr(S);
/***********************************************
* Check and see if base step time is too fast *
***********************************************/
/* modification of grt_main (FW-02-03) */
// if (GBLbuf.isrOverrun++) {
// GBLbuf.stopExecutionFlag = 1;
// return;
// }
/***********************************************
* Check and see if error status has been set *
***********************************************/
/* modification of grt_main (FW-02-03) */
// if (rtmGetErrorStatus(S) != NULL) {
// GBLbuf.stopExecutionFlag = 1;
// return;
// }
/* modification of grt_main (FW-02-03) */
// rtExtModeOneStep(rtmGetRTWExtModeInfo(S),
// (boolean_T *)&rtmGetStopRequested(S));
/************************************************************************
* Update discrete events and buffer event flags locally so that ISR is *
* re-entrant. *
************************************************************************/
tnext = rt_SimUpdateDiscreteEvents(rtmGetNumSampleTimes(S),
rtmGetTimingData(S),
rtmGetSampleHitPtr(S),
rtmGetPerTaskSampleHitsPtr(S));
rtsiSetSolverStopTime(rtmGetRTWSolverInfo(S),tnext);
for (i=FIRST_TID+1; i < NUMST; i++) {
eventFlags[i] = sampleHit[i];
}
/*******************************************
* Step the model for the base sample time *
*******************************************/
MdlOutputs(FIRST_TID);
rtExtModeUploadCheckTrigger();
rtExtModeUpload(FIRST_TID,rtmGetTaskTime(S, FIRST_TID));
/* modification of grt_main (FW-02-03) */
// GBLbuf.errmsg = rt_UpdateTXYLogVars(rtmGetRTWLogInfo(S),
// rtmGetTPtr(S));
// if (GBLbuf.errmsg != NULL) {
// GBLbuf.stopExecutionFlag = 1;
// return;
// }
MdlUpdate(FIRST_TID);
if (rtmGetSampleTime(S,0) == CONTINUOUS_SAMPLE_TIME) {
rt_UpdateContinuousStates(S);
}
else {
rt_SimUpdateDiscreteTaskTime(rtmGetTPtr(S),
rtmGetTimingData(S), 0);
}
#if FIRST_TID == 1
rt_SimUpdateDiscreteTaskTime(rtmGetTPtr(S),
rtmGetTimingData(S),1);
#endif
/************************************************************************
* Model step complete for base sample time, now it is okay to *
* re-interrupt this ISR. *
************************************************************************/
/* modification of grt_main (FW-02-03) */
// GBLbuf.isrOverrun--;
/*********************************************
* Step the model for any other sample times *
*********************************************/
for (i=FIRST_TID+1; i<NUMST; i++) {
if (eventFlags[i]) {
/* modification of grt_main (FW-02-03) */
// if (GBLbuf.overrunFlags[i]++) { /* Are we sampling too fast for */
// GBLbuf.stopExecutionFlag=1; /* sample time "i"? */
// return;
// }
MdlOutputs(i);
rtExtModeUpload(i, rtmGetTaskTime(S,i));
MdlUpdate(i);
rt_SimUpdateDiscreteTaskTime(rtmGetTPtr(S),
rtmGetTimingData(S),i);
/* modification of grt_main (FW-02-03) */
// /* Indicate task complete for sample time "i" */
// GBLbuf.overrunFlags[i]--;
}
}
rtExtModeCheckEndTrigger();
/* modification of grt_main (FW-02-03) */
#ifdef EXT_MODE
put_data_buffer();
#endif
} /* end rtOneStep */
#endif /* MULTITASKING */
/*
* NOTE:
* The functions model_init(), model_run() and model_clean() replace subsequent
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -