📄 mc_main.c
字号:
* code section which previously belonged to main(). This considerably increases
* the overall readability of the code.
*/
/* Function: model_init ============================================================
*
* Abstract:
* initialises model
*/
static void model_init(void)
{
const char *status;
real_T finaltime = -2.0;
/* modification of grt_main (FW-02-03) */
// /****************************
// * Initialize global memory *
// ****************************/
//
// (void)memset(&GBLbuf, 0, sizeof(GBLbuf));
/************************
* Initialize the model *
************************/
//rt_InitInfAndNaN(sizeof(real_T));
S = MODEL();
if (rtmGetErrorStatus(S) != NULL) {
abort_LED(1);
}
if (finaltime >= 0.0 || finaltime == RUN_FOREVER) rtmSetTFinal(S,finaltime);
MdlInitializeSizes();
MdlInitializeSampleTimes();
status = rt_SimInitTimingEngine(rtmGetNumSampleTimes(S),
rtmGetStepSize(S),
rtmGetSampleTimePtr(S),
rtmGetOffsetTimePtr(S),
rtmGetSampleHitPtr(S),
rtmGetSampleTimeTaskIDPtr(S),
rtmGetTStart(S),
&rtmGetSimTimeStep(S),
&rtmGetTimingData(S));
if (status != NULL) {
abort_LED(2);
}
rt_CreateIntegrationData(S);
/* modification of grt_main (FW-02-03) */
// GBLbuf.errmsg = rt_StartDataLogging(rtmGetRTWLogInfo(S),
// rtmGetTFinal(S),
// rtmGetStepSize(S),
// &rtmGetErrorStatus(S));
// if (GBLbuf.errmsg != NULL) {
// abort_LED(3);
// }
/* initialise serial interface, enable buffering and set userData flag 'waitForStartMsg' to TRUE */
#ifdef EXT_MODE
rt_ExtModeInit();
#endif
#ifdef RUN_IMMEDIATELY
/* determine startup behaviour (direct / wait for start msg) */
/* fw-10-05 */
if(RunningAfterPowerUpReset) {
/* first run */
#ifdef EXT_MODE
ExtSetWaitForStartMsg(FALSE); /* project EDGAR: don't wait */
//ExtSetWaitForStartMsg(TRUE); /* default: wait */
#endif
RunningAfterPowerUpReset = 0; /* reset flag */
} else {
/* all subsequent runs */
/* this is only reached if the user has clicked 'stop' */
#ifdef EXT_MODE
ExtSetWaitForStartMsg(TRUE);
#endif
}
#endif
/*
* Pause until receive model start message.
*/
#ifdef EXT_MODE
rtExtModeWaitForStartMsg(rtmGetRTWExtModeInfo(S),
(boolean_T *)&rtmGetStopRequested(S));
#endif
MdlStart();
/* modification of grt_main (FW-02-03) */
// if (rtmGetErrorStatus(S) != NULL) {
// GBLbuf.stopExecutionFlag = 1;
// }
} /* end model_init */
/* Function: model_clean =============================================================
*
* Abstract:
* clean up and exit the model
*/
static void model_clean(void)
{
/********************
* Cleanup and exit *
********************/
/* modification of grt_main (FW-02-03) */
// rt_StopDataLogging(MATFILE,rtmGetRTWLogInfo(S));
rtExtModeShutdown();
/* modification of grt_main (FW-02-03) */
// if (GBLbuf.errmsg) {
// abort_LED(4);
// }
/* modification of grt_main (FW-02-03) */
// if (GBLbuf.isrOverrun) {
// abort_LED(5);
// }
if (rtmGetErrorStatus(S) != NULL) {
abort_LED(6);
}
/* modification of grt_main (FW-02-03) */
//#ifdef MULTITASKING
// else {
// int_T i;
// for (i=1; i<NUMST; i++) {
// if (GBLbuf.overrunFlags[i]) {
// abort_LED(6);
// }
// }
// }
//#endif
MdlTerminate();
} /* end model_clean */
/* Function: model_run =============================================================
*
* Abstract:
* run model
*/
void model_run(void)
{
/*************************************************************************
* Execute the model. You may attach rtOneStep to an ISR, if so replace *
* the call to rtOneStep (below) with a call to a background task *
* application. *
*************************************************************************/
/* modification of grt_main (FW-02-03) */
if (!rtmGetStopRequested(S) &&
(rtmGetTFinal(S) == RUN_FOREVER ||
rtmGetTFinal(S)-rtmGetT(S) > rtmGetT(S)*DBL_EPSILON)) {
/* modification of grt_main (FW-02-03) */
//rtExtModePauseIfNeeded(rtmGetRTWExtModeInfo(S),
// (boolean_T *)&rtmGetStopRequested(S));
rt_OneStep();
}
else {
/* modification of grt_main (FW-02-03) */
// now conditional... FW-02-03
if (!rtmGetStopRequested(S)) {
/* Execute model last time step */
rt_OneStep();
}
/* clean the model and leave. */
model_clean();
#ifdef EXT_MODE
/* reset flag 'startModel' to exit from while loop in main() */
startModel = FALSE;
#endif
}
} /* end model_run */
/* User communication and FreePort communication with the target board (FW-02-03) */
/* Function: Init_ComVars ===============================================
* Abstract:
* Initialise the communication variables used by the user communication
* modules s0_usertel_rxd and s0_usertel_txd as well as the FreePort
* communication variables used by freePortComms_txd and freePortComms_rxd
*/
static void Init_ComVars(void) {
int_T i;
#ifdef EXT_MODE
/* UserTel comms: set pointers to all TxD buffers and their respective buffer flags */
for(i=0; i<MAX_UCOM_CHANNELS; i++) {
/* initialise user communication buffer pointers, flags, buffer sizes and the txd queue with default values */
userTelBuf[i] = NULL;
user_txd_queue[i] = 0;
}
/* initialise number of channels to be scanned for (corrected by the respective S-Functions) */
num_user_channels_active = 0;
/* initialise index of the first channel to be scanned for */
next_user_channel_index = 0;
#endif /* EXT_MODE */
/* FreePort comms: reset pointers to all freecom buffers */
for(i=0; i<MAX_FREECOM_CHANNELS; i++) {
/* initialise user communication buffer pointers, flags, buffer sizes and the txd queue with default values */
freecomTelBuf[i] = NULL;
}
#if (HAS_RFCOMMS > 0)
/* RF comms: reset pointers to all radiocom buffers */
for(i=0; i<MAX_RADIOCOM_CHANNELS; i++) {
/* initialise RF communication buffer pointers, flags, buffer sizes and the txd queue with default values */
radiocomTelBuf[i] = NULL;
}
#endif
} /* end Init_ComVars */
/* Function: AllocateUserBuffer ===============================================
* Abstract:
* Allocate buffers for user communication - called upon from within mdlStart
* modules s0_usertel_rxd and s0_usertel_txd.
*/
myUsrBuf *AllocateUserBuffer(uint_T channel, uint16_T bufsize, uint8_T data_type_len) {
uint8_T *buf;
static myUsrBuf *admin = NULL;
int i;
/* allocate memory for admin structure of this instance's data buffer */
if((admin = (myUsrBuf *)calloc(1, sizeof(myUsrBuf))) == NULL) return NULL;
/* allocate memory for the buffer itself (buf_size '+ 4' -> telegram size, channel number, '0 0' [reserved]) */
/* the additional '+3' has been introduced to allow safe byte-swapping -- required on the 9S12... fw-03-05 */
/* (the order of every group of 4 bytes gets reversed -> uint8_T transmissions might just end up on '+1' -> '+3' makes it dword aligned) */
if((buf = (uint8_T *)calloc(bufsize + 4 + 3, sizeof(uint8_T))) == NULL) return NULL;
/* clear buffer */
for(i=0; i<(bufsize + 4 + 3); i++) buf[i] = 0;
/* store pointer to buf in the admin structure */
admin->buf = buf;
/* store size of the actual data buffer */
admin->buf_size = bufsize;
/* initialise the access_count field */
admin->access_count = 1;
/* initialise the buffer_full flag */
admin->buffer_full = 0;
/* initialise buffer */
/* set first field of the buffer to the number of bytes per user telegram (remains invariant)... */
buf[0] = (uint8_T)(bufsize + 4);
/* set second field of the buffer to the channel number (remains invariant)... */
buf[1] = (uint8_T)channel;
/* set third field of the buffer to the channel data type length: 1, 2, 4) (remains invariant)... */
buf[2] = data_type_len;
/* ... and clear the reserved byte (buf[3]) as well as the local data buffer */
(void)memset(&buf[3], 0, bufsize + 1);
/* return access pointer */
return admin;
}
/* Function ====================================================================
* Initialises port PORTA (LEDS), PORTB (general I/O), install interrupts
*/
static void init_micro(void) {
/* set system clock frequency to _BUSCLOCK MHz (24 or 4) */
PLL_Init();
/* enable all LEDs on the Dragon 12 rapid prototyping board */
#if TARGET_BOARD == 1
/* Dragon-12 */
DDRB = 0xff; /* set PORTB as output (LEDs) */
PORTB = 0x00; /* all LEDs off */
#endif
/* enable 7-segment display on the MiniDragon+ rapid prototyping board */
#if ((TARGET_BOARD == 2) | (TARGET_BOARD == 3))
/* MiniDragon+ */
DDRH = 0xff; /* set port H as output (7-segment display) */
PTH = 0x00; /* all segments off */
#endif
/* make timing signal pin an output */
#ifdef TIMING
setCycTiPinOutput;
#endif
/* if errors are to be displayed on the LCD display... */
#ifdef LCDUSE4ERRORS
LCD_init();
#endif
// debug target in RT -> debug log through the vacant SCI0 (release mode)
#if (DEBUG2SCI0 > 0)
SCI0_Init(BAUDRATE);
#endif
/* say hello... */
blinky(10000);
} /* end init_micro */
/*===================*
* Visible functions *
*===================*/
/* Function: main =============================================================
*
* Abstract:
* Execute model on a generic target such as a workstation.
*/
void main(void) {
#ifdef LCDUSE4ERRORS
unsigned int i;
static char_T myLCDtxt[16]= " ";
static char_T *myPtr = MODELSTR;
#endif
/* initialise some essential registers, install interrupts... */
init_micro();
/* forever... */
while(1) {
#ifdef LCDUSE4ERRORS
i = 0;
while(myPtr[i] != 0 && i<16) myLCDtxt[i] = myPtr[i++];
writeLine(myLCDtxt, 0);
writeLine("-> model ready ", 1);
#endif
#ifdef EXT_MODE
/* initialize RTW ring buffer. */
init_ringBuf();
#endif
/* initialise user communication variables (ExtMode / FreePort) */
Init_ComVars();
#if ((HAS_TIMERBLOCKS > 0) | (HAS_RFCOMMS > 0))
/* initialize ECT timer unit (base period defined by macro TIMER_BASEPERIOD) */
/* this needs to be done before model_init (fw-09-06) */
ECT_Init();
ECT_Start();
#endif
/* initialize model */
model_init();
/* initialize main time base (timer T7 / RTI) */
init_timebase(rtmGetStepSize(S));
/* START RT PROCESS */
#if CORE_TIMER == CORE_T7ISR
TIE |= 0x80; // enable channel 7 interrupt
#else
CRGINT_RTIE = 1; // CRG interrupt enable register, RTIE=1 -> enable RTI
#endif
/* make sure all interrupts are enabled (should already be the case) */
asm cli
#ifdef LCDUSE4ERRORS
writeLine("-> model running", 1);
#endif
#ifdef EXT_MODE
/* monitor serial interface & manage upload/download - until startModel is set to FALSE... */
while(startModel) {
/* new in R13: combined call to rt_MsgServerWork() & rt_UploadServerWork() -- (FW-02-03) */
rtExtModeOneStep(rtmGetRTWExtModeInfo(S), (boolean_T *)&rtmGetStopRequested(S));
}
/* disable all interrupts */
asm sei
/* stop timer */
#if CORE_TIMER == CORE_T7ISR
TIE &= ~0x80; // disable channel 7 interrupt
#else
CRGINT_RTIE = 0; // disable CRG interrupt
#endif
/* stop ECT */
#if HAS_TIMERBLOCKS > 0
/* stop ECT timer */
ECT_Stop();
#endif
/* disable serial interface (SCI1) */
SCI1CR2 &= ~0x2C;
/* required to avoid communication errors */
//blinky(100000);
/* currently not used -> requires 'freeportcom_[r/t]xd.dll' to be recompiled with tunable parameters */
/* fw-05-05 */
//
///* remove 'FreePortCom' buffer -> this should allow us to re-initialize comms with different settings */
//if(FreePortComBufPtr != NULL) {
//
// RemoveBuffer(FreePortComBufPtr);
// FreePortComBufPtr = NULL;
//
//}
#ifdef LCDUSE4ERRORS
writeLine("-> model stopped", 1);
#endif
#else /* EXT_MODE */
/* enable all interrupts */
asm cli
/* standalone applications -> do nothing, RT process is run by the timer interrupt (T7) */
while(1);
#endif
} /* end : forever... */
} /* end : main */
/* EOF: mc_main.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -