Subversion Repositories shark

Rev

Rev 1416 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1342 giacomo 1
#include "tmwtypes.h"
2
#include "rtmodel.h"
3
#include "rt_sim.h"
4
#include "rt_logging.h"
5
#include "rt_nonfinite.h"
6
 
7
#include "ext_work.h"
8
#include "rt_nonfinite.h"
9
 
10
#include "kernel/kern.h"
1418 giacomo 11
#include "modules/cabs.h"
1342 giacomo 12
 
1418 giacomo 13
#include "rtw.h"
14
 
1342 giacomo 15
/*=========*
16
 * Defines *
17
 *=========*/
18
 
19
#ifndef TRUE
20
#define FALSE (0)
21
#define TRUE  (1)
22
#endif
23
 
24
#ifndef EXIT_FAILURE
25
#define EXIT_FAILURE  1
26
#endif
27
#ifndef EXIT_SUCCESS
28
#define EXIT_SUCCESS  0
29
#endif
30
 
31
#define QUOTE1(name) #name
32
#define QUOTE(name) QUOTE1(name)    /* need to expand name    */
33
 
34
#define RUN_FOREVER -1.0
35
 
36
#define EXPAND_CONCAT(name1,name2) name1 ## name2
37
#define CONCAT(name1,name2) EXPAND_CONCAT(name1,name2)
38
#define RT_MODEL            CONCAT(MODEL,_rtModel)
39
 
40
extern RT_MODEL *MODEL(void);
41
 
42
extern void MdlInitializeSizes(void);
43
extern void MdlInitializeSampleTimes(void);
44
extern void MdlStart(void);
45
extern void MdlOutputs(int_T tid);
46
extern void MdlUpdate(int_T tid);
47
extern void MdlTerminate(void);
48
 
49
real_T rtInf;
50
real_T rtMinusInf;
51
real_T rtNaN;
52
 
1418 giacomo 53
CAB    input_cid[NINPUTCAB];
54
CAB    output_cid[NOUTPUTCAB];
55
 
1415 giacomo 56
#ifdef EXT_MODE
57
#  define rtExtModeSingleTaskUpload(S)    \
58
   {                                      \
59
        int stIdx;                        \
60
        rtExtModeUploadCheckTrigger();    \
61
        for (stIdx=0; stIdx<NUMST; stIdx++) {                   \
62
            if (rtmIsSampleHit(S, stIdx, 0 /*unused*/)) {       \
63
                rtExtModeUpload(stIdx,rtmGetTaskTime(S,stIdx)); \
64
            }                                                   \
65
        }                                                       \
66
   }
67
#else
68
#  define rtExtModeSingleTaskUpload(S) /* Do nothing */
69
#endif
70
 
1402 giacomo 71
#if NCSTATES > 0
72
  extern void rt_ODECreateIntegrationData(RTWSolverInfo *si);
73
  extern void rt_ODEUpdateContinuousStates(RTWSolverInfo *si);
74
 
75
# define rt_CreateIntegrationData(S) \
76
    rt_ODECreateIntegrationData(rtmGetRTWSolverInfo(S));
77
# define rt_UpdateContinuousStates(S) \
78
    rt_ODEUpdateContinuousStates(rtmGetRTWSolverInfo(S));
79
# else
1342 giacomo 80
# define rt_CreateIntegrationData(S)  \
81
      rtsiSetSolverName(rtmGetRTWSolverInfo(S),"FixedStepDiscrete");
82
# define rt_UpdateContinuousStates(S) \
83
      rtmSetT(S, rtsiGetSolverStopTime(rtmGetRTWSolverInfo(S)));
1402 giacomo 84
#endif
1342 giacomo 85
 
86
/*==================================*
87
 * Global data local to this module *
88
 *==================================*/
1368 giacomo 89
 
90
RT_MODEL  *S;
91
const char *status;
92
real_T     finaltime = -2.0;
93
volatile int simulation_run;                                                                                                                            
1342 giacomo 94
static struct {
95
  int_T    stopExecutionFlag;
96
  int_T    isrOverrun;
97
  int_T    overrunFlags[NUMST];
98
  const char_T *errmsg;
99
} GBLbuf;
100
 
101
/* Function: rt_InitInfAndNaN ==================================================
102
 * Abstract:
103
 *      Initialize the rtInf, rtMinusInf, and rtNaN needed by the
104
 *      generated code. NaN is initialized as non-signaling. Assumes IEEE.
105
 */
106
void rt_InitInfAndNaN(int_T realSize)
107
{
108
    short one = 1;
109
    enum {
110
        LittleEndian,
111
        BigEndian
112
    } machByteOrder = (*((char *) &one) == 1) ? LittleEndian : BigEndian;
113
 
114
    switch (realSize) {  
115
      case 4:
116
        switch (machByteOrder) {
117
          case LittleEndian: {
118
              typedef struct {
119
                  uint32_T fraction : 23;
120
                  uint32_T exponent  : 8;
121
                  uint32_T sign      : 1;
122
              } LittleEndianIEEEDouble;
123
 
124
              (*(LittleEndianIEEEDouble*)&rtInf).sign      = 0;
125
              (*(LittleEndianIEEEDouble*)&rtInf).exponent  = 0xFF;
126
              (*(LittleEndianIEEEDouble*)&rtInf).fraction  = 0;
127
              rtMinusInf = rtInf;
128
              rtNaN = rtInf;
129
              (*(LittleEndianIEEEDouble*)&rtMinusInf).sign = 1;
130
              (*(LittleEndianIEEEDouble*)&rtNaN).fraction  = 0x7FFFFF;
131
          }
132
          break;
133
          case BigEndian: {
134
              typedef struct {
135
                  uint32_T sign      : 1;
136
                  uint32_T exponent  : 8;
137
                  uint32_T fraction  : 23;
138
              } BigEndianIEEEDouble;
139
 
140
              (*(BigEndianIEEEDouble*)&rtInf).sign      = 0;
141
              (*(BigEndianIEEEDouble*)&rtInf).exponent  = 0xFF;
142
              (*(BigEndianIEEEDouble*)&rtInf).fraction  = 0;
143
              rtMinusInf = rtInf;
144
              rtNaN = rtInf;
145
              (*(BigEndianIEEEDouble*)&rtMinusInf).sign = 1;
146
              (*(BigEndianIEEEDouble*)&rtNaN).fraction  = 0x7FFFFF;
147
          }
148
          break;
149
        }
150
        break;    
151
 
152
      case 8:
153
        switch (machByteOrder) {
154
          case LittleEndian: {
155
              typedef struct {
156
                  struct {
157
                      uint32_T fraction2;
158
                  } wordH;
159
                  struct {
160
                      uint32_T fraction1 : 20;
161
                      uint32_T exponent  : 11;
162
                      uint32_T sign      : 1;
163
                  } wordL;
164
              } LittleEndianIEEEDouble;
165
 
166
              (*(LittleEndianIEEEDouble*)&rtInf).wordL.sign      = 0;
167
              (*(LittleEndianIEEEDouble*)&rtInf).wordL.exponent  = 0x7FF;
168
              (*(LittleEndianIEEEDouble*)&rtInf).wordL.fraction1 = 0;
169
              (*(LittleEndianIEEEDouble*)&rtInf).wordH.fraction2 = 0;
170
 
171
              rtMinusInf = rtInf;
172
              (*(LittleEndianIEEEDouble*)&rtMinusInf).wordL.sign = 1;
173
              (*(LittleEndianIEEEDouble*)&rtNaN).wordL.sign      = 0;
174
              (*(LittleEndianIEEEDouble*)&rtNaN).wordL.exponent  = 0x7FF;
175
              (*(LittleEndianIEEEDouble*)&rtNaN).wordL.fraction1 = 0xFFFFF;
176
              (*(LittleEndianIEEEDouble*)&rtNaN).wordH.fraction2 = 0xFFFFFFFF;
177
          }
178
          break;
179
          case BigEndian: {
180
              typedef struct {
181
                  struct {
182
                      uint32_T sign      : 1;
183
                      uint32_T exponent  : 11;
184
                      uint32_T fraction1 : 20;
185
                  } wordL;
186
                  struct {
187
                      uint32_T fraction2;
188
                  } wordH;
189
              } BigEndianIEEEDouble;
190
 
191
              (*(BigEndianIEEEDouble*)&rtInf).wordL.sign      = 0;
192
              (*(BigEndianIEEEDouble*)&rtInf).wordL.exponent  = 0x7FF;
193
              (*(BigEndianIEEEDouble*)&rtInf).wordL.fraction1 = 0;
194
              (*(BigEndianIEEEDouble*)&rtInf).wordH.fraction2 = 0;
195
 
196
              rtMinusInf = rtInf;
197
              (*(BigEndianIEEEDouble*)&rtMinusInf).wordL.sign = 1;
198
              (*(BigEndianIEEEDouble*)&rtNaN).wordL.sign      = 0;
199
              (*(BigEndianIEEEDouble*)&rtNaN).wordL.exponent  = 0x7FF;
200
              (*(BigEndianIEEEDouble*)&rtNaN).wordL.fraction1 = 0xFFFFF;
201
              (*(BigEndianIEEEDouble*)&rtNaN).wordH.fraction2 = 0xFFFFFFFF;
202
          }
203
          break;
204
        }
205
        break;
206
      default:
1369 giacomo 207
        cprintf("Error: Unable to initialize rtInf, rtMinusInf and rtNaN\n");
1342 giacomo 208
        sys_end();
209
        break;
210
    }
211
 
212
} /* end rt_InitInfAndNaN */
213
 
214
/* Function: rtOneStep ========================================================
215
 *
216
 * Abstract:
217
 *      Perform one step of the model. This function is modeled such that
218
 *      it could be called from an interrupt service routine (ISR) with minor
219
 *      modifications.
220
 */
221
static void rt_OneStep(RT_MODEL *S)
222
{
223
    real_T tnext;
1415 giacomo 224
 
1342 giacomo 225
    /***********************************************
226
     * Check and see if base step time is too fast *
227
     ***********************************************/
1415 giacomo 228
 
1342 giacomo 229
    if (GBLbuf.isrOverrun++) {
230
        GBLbuf.stopExecutionFlag = 1;
231
        return;
232
    }
1415 giacomo 233
 
1342 giacomo 234
    /***********************************************
235
     * Check and see if error status has been set  *
236
     ***********************************************/
1415 giacomo 237
 
1342 giacomo 238
    if (rtmGetErrorStatus(S) != NULL) {
239
        GBLbuf.stopExecutionFlag = 1;
240
        return;
241
    }
1415 giacomo 242
 
1342 giacomo 243
    /* enable interrupts here */
1415 giacomo 244
 
1342 giacomo 245
    rtExtModeOneStep(rtmGetRTWExtModeInfo(S),
1415 giacomo 246
                        (boolean_T *)&rtmGetStopRequested(S));
247
 
1342 giacomo 248
    tnext = rt_SimGetNextSampleHit();
249
    rtsiSetSolverStopTime(rtmGetRTWSolverInfo(S),tnext);
1415 giacomo 250
 
1342 giacomo 251
    MdlOutputs(0);
1415 giacomo 252
 
253
    rtExtModeSingleTaskUpload(S);
254
 
255
    if (GBLbuf.errmsg != NULL) {
256
        GBLbuf.stopExecutionFlag = 1;
257
        return;
258
    }
259
 
1342 giacomo 260
    MdlUpdate(0);
261
    rt_SimUpdateDiscreteTaskSampleHits(rtmGetNumSampleTimes(S),
262
                                       rtmGetTimingData(S),
263
                                       rtmGetSampleHitPtr(S),
264
                                       rtmGetTPtr(S));
1415 giacomo 265
 
1342 giacomo 266
    if (rtmGetSampleTime(S,0) == CONTINUOUS_SAMPLE_TIME) {
267
        rt_UpdateContinuousStates(S);
268
    }
1415 giacomo 269
 
1342 giacomo 270
    GBLbuf.isrOverrun--;
1415 giacomo 271
 
1342 giacomo 272
    rtExtModeCheckEndTrigger();
273
 
274
} /* end rtOneStep */
275
 
1368 giacomo 276
void Init_RealTime_Workshop() {
1342 giacomo 277
 
1368 giacomo 278
    /****************************
1342 giacomo 279
     * Initialize global memory *
280
     ****************************/
1368 giacomo 281
 
1342 giacomo 282
    (void)memset(&GBLbuf, 0, sizeof(GBLbuf));  
283
 
1368 giacomo 284
    /************************
1342 giacomo 285
     * Initialize the model *
286
     ************************/
1368 giacomo 287
 
1342 giacomo 288
    rt_InitInfAndNaN(sizeof(real_T));
289
 
290
    S = MODEL();
291
    if (rtmGetErrorStatus(S) != NULL) {
1369 giacomo 292
        cprintf("Error: Model registration: %s\n",
1342 giacomo 293
                      rtmGetErrorStatus(S));
294
        sys_end();
295
    }
1368 giacomo 296
 
1342 giacomo 297
    if (finaltime >= 0.0 || finaltime == RUN_FOREVER) rtmSetTFinal(S,finaltime);
298
 
299
    MdlInitializeSizes();
300
    MdlInitializeSampleTimes();
301
 
302
    status = rt_SimInitTimingEngine(rtmGetNumSampleTimes(S),
303
                                    rtmGetStepSize(S),
304
                                    rtmGetSampleTimePtr(S),
305
                                    rtmGetOffsetTimePtr(S),
306
                                    rtmGetSampleHitPtr(S),
307
                                    rtmGetSampleTimeTaskIDPtr(S),
308
                                    rtmGetTStart(S),
309
                                    &rtmGetSimTimeStep(S),
310
                                    &rtmGetTimingData(S));
311
 
312
    if (status != NULL) {
1369 giacomo 313
        cprintf("Error: Failed to initialize sample time engine: %s\n", status);
1342 giacomo 314
        sys_end();
315
    }
1368 giacomo 316
 
1342 giacomo 317
    rt_CreateIntegrationData(S);
318
 
319
    rtExtModeCheckInit();
320
    rtExtModeWaitForStartMsg(rtmGetRTWExtModeInfo(S),
321
                             (boolean_T *)&rtmGetStopRequested(S));
322
 
1368 giacomo 323
    cprintf("\n** Starting the model **\n");
1342 giacomo 324
 
325
    MdlStart();
326
    if (rtmGetErrorStatus(S) != NULL) {
327
      GBLbuf.stopExecutionFlag = 1;
328
    }
329
 
330
     /*************************************************************************
331
     * Execute the model.  You may attach rtOneStep to an ISR, if so replace *
332
     * the call to rtOneStep (below) with a call to a background task        *
333
     * application.                                                          *
334
     *************************************************************************/
335
 
336
    if (rtmGetTFinal(S) == RUN_FOREVER) {
337
        cprintf("\n**May run forever. Model stop time set to infinity.**\n");
338
    }
339
 
1368 giacomo 340
}
1342 giacomo 341
 
1368 giacomo 342
void Close_RealTime_Workshop() {
1342 giacomo 343
 
344
    /********************
345
     * Cleanup and exit *
346
     ********************/
347
 
348
    rtExtModeShutdown();
349
 
350
    if (GBLbuf.errmsg) {
1369 giacomo 351
        cprintf("Error: %s\n",GBLbuf.errmsg);
1342 giacomo 352
        sys_end();
353
    }
354
 
355
    if (GBLbuf.isrOverrun) {
1369 giacomo 356
        cprintf("Error: %s: ISR overrun - base sampling rate is too fast\n",QUOTE(MODEL));
1342 giacomo 357
        sys_end();
358
    }
359
 
360
    if (rtmGetErrorStatus(S) != NULL) {
1369 giacomo 361
        cprintf("Error: %s\n", rtmGetErrorStatus(S));
1342 giacomo 362
        sys_end();
363
    }
364
 
1368 giacomo 365
    MdlTerminate();
1344 giacomo 366
 
1368 giacomo 367
}
368
 
369
TASK RTW_body(void *arg) {
370
 
371
    simulation_run = 1;
372
 
373
    while (!GBLbuf.stopExecutionFlag &&
374
           (rtmGetTFinal(S) == RUN_FOREVER ||
375
            rtmGetTFinal(S)-rtmGetT(S) > rtmGetT(S)*DBL_EPSILON)) {
376
 
377
        rtExtModePauseIfNeeded(rtmGetRTWExtModeInfo(S),
378
                               (boolean_T *)&rtmGetStopRequested(S));
379
 
380
        if (rtmGetStopRequested(S)) break;
381
        rt_OneStep(S);
382
 
383
        task_endcycle();
384
 
385
    }
386
 
387
    if (!GBLbuf.stopExecutionFlag && !rtmGetStopRequested(S)) {
388
        /* Execute model last time step */
389
        rt_OneStep(S);
390
    }
391
 
392
    simulation_run = 0;
393
 
394
    return NULL;
395
 
396
}
397
 
1418 giacomo 398
TASK INPUT_body(void *input_port) {
1403 giacomo 399
 
1418 giacomo 400
    real_T *input, *p;
401
    int in = (int)(input_port);
1403 giacomo 402
 
1418 giacomo 403
    if (in >= NINPUTCAB) return NULL;
1403 giacomo 404
 
405
    input = (real_T *)rtmGetU(S);
406
 
407
    while(1) {
408
 
1418 giacomo 409
        /* Get CAB message */
410
        p = (real_T *)cab_getmes(input_cid[in]);
1403 giacomo 411
 
1418 giacomo 412
        /* Set INPUT port */
413
        input[in] = *p;
414
 
415
        /* Release CAB message */
416
        cab_unget(input_cid[in], p);
417
 
1403 giacomo 418
        task_endcycle();
419
 
420
    }
421
 
422
    return NULL;
423
 
424
}
425
 
1418 giacomo 426
TASK OUTPUT_body(void *output_port) {
427
 
428
    real_T *output, *p;
429
    int out = (int)(output_port);
430
    char cname[20];
431
 
432
    if (out >= NOUTPUTCAB) return NULL;                                    
433
 
434
    sprintf(cname,"OUTPUT%d",out);
435
    output_cid[out] = cab_create(cname, sizeof(real_T), 2);
1416 giacomo 436
 
437
    output = (real_T *)rtmGetY(S);
438
 
439
    while(1) {
1418 giacomo 440
 
441
        /* Reserve a message */
442
        p = (real_T *)cab_reserve(output_cid[out]);
1416 giacomo 443
 
1418 giacomo 444
        /* Save data */
445
        *p = output[out];
446
 
447
        /* Put CAB message */
448
        cab_putmes(output_cid[out], p);
1416 giacomo 449
 
450
        task_endcycle();
451
 
452
    }
453
 
454
    return NULL;
455
 
456
}
457
 
1368 giacomo 458
int main() {
459
 
1416 giacomo 460
    HARD_TASK_MODEL     RTW_task,INPUT_task,OUTPUT_task;
461
    PID                 RTW_pid,INPUT_pid,OUTPUT_pid;
1368 giacomo 462
 
1418 giacomo 463
    int i;
464
 
1416 giacomo 465
    int RTW_period;
466
    int RTW_wcet;
467
 
468
    int INPUT_period;
469
    int INPUT_wcet;
470
 
471
    int OUTPUT_period;
472
    int OUTPUT_wcet;
473
 
1368 giacomo 474
    Init_RealTime_Workshop();
475
 
1418 giacomo 476
    for (i=0;i<NINPUTCAB;i++) input_cid[i] = -1;
477
    for (i=0;i<NOUTPUTCAB;i++) output_cid[i] = -1;
478
 
1416 giacomo 479
    RTW_period =(int)(rtmGetStepSize(S) * 1000000.0);
480
    RTW_wcet = (int)(rtmGetStepSize(S) * 1000000.0 * 0.45);
481
 
482
    INPUT_period = (int)(10000.0);
1418 giacomo 483
    INPUT_wcet = (int)(10000.0 * 0.10);
1416 giacomo 484
 
1418 giacomo 485
    OUTPUT_period = (int)(10000.0);
486
    OUTPUT_wcet = (int)(10000.0 * 0.10);
1416 giacomo 487
 
488
    cprintf("Task Setup\n");
489
    cprintf("RTW    (P %8d W %8d)\n",RTW_period,RTW_wcet);
490
    cprintf("INPUT  (P %8d W %8d)\n",INPUT_period,INPUT_wcet);
491
    cprintf("OUTPUT (P %8d W %8d)\n",OUTPUT_period,OUTPUT_wcet);
492
 
1368 giacomo 493
    hard_task_default_model(RTW_task);
1416 giacomo 494
    hard_task_def_mit(RTW_task,RTW_period);
495
    hard_task_def_wcet(RTW_task,RTW_wcet);
1368 giacomo 496
    hard_task_def_usemath(RTW_task);
497
    hard_task_def_ctrl_jet(RTW_task);
498
 
499
    RTW_pid = task_create("RTW",RTW_body,&RTW_task,NULL);
500
    if (RTW_pid == NIL) {
1416 giacomo 501
        cprintf("Error: Cannot create RealTime Workshop [RTW] Task\n");
1368 giacomo 502
        sys_end();
503
    }
504
 
1403 giacomo 505
    hard_task_default_model(INPUT_task);
1416 giacomo 506
    hard_task_def_mit(INPUT_task,INPUT_period);
507
    hard_task_def_wcet(INPUT_task,INPUT_wcet);
1418 giacomo 508
    /* Set input port number */
509
    hard_task_def_arg(INPUT_task,(void *)(0));
1403 giacomo 510
    hard_task_def_usemath(INPUT_task);
511
    hard_task_def_ctrl_jet(INPUT_task);
512
 
1418 giacomo 513
    INPUT_pid = task_create("INPUT0",INPUT_body,&INPUT_task,NULL);
1403 giacomo 514
    if (INPUT_pid == NIL) {
1418 giacomo 515
        cprintf("Error: Cannot create RealTime Workshop [INPUT0] Task\n");
1403 giacomo 516
        sys_end();
517
    }
518
 
1416 giacomo 519
    hard_task_default_model(OUTPUT_task);
520
    hard_task_def_mit(OUTPUT_task,OUTPUT_period);
521
    hard_task_def_wcet(OUTPUT_task,OUTPUT_wcet);
1418 giacomo 522
    /* Set output port number */
523
    hard_task_def_arg(OUTPUT_task,(void *)(0));
1416 giacomo 524
    hard_task_def_usemath(OUTPUT_task);
525
    hard_task_def_ctrl_jet(OUTPUT_task);
526
 
1418 giacomo 527
    OUTPUT_pid = task_create("OUTPUT0",OUTPUT_body,&OUTPUT_task,NULL);
1416 giacomo 528
    if (OUTPUT_pid == NIL) {
1418 giacomo 529
        cprintf("Error: Cannot create RealTime Workshop [OUTPUT0] Task\n");
1416 giacomo 530
        sys_end();
531
    }
532
 
1403 giacomo 533
    task_activate(INPUT_pid);
1368 giacomo 534
    task_activate(RTW_pid);
1416 giacomo 535
    task_activate(OUTPUT_pid);
1368 giacomo 536
 
1418 giacomo 537
    activate_sensors();
538
    activate_actuators();
539
 
1368 giacomo 540
    while(simulation_run);
541
 
542
    Close_RealTime_Workshop();
543
 
544
    sys_end();
545
 
1342 giacomo 546
    return 0;
547
 
1368 giacomo 548
}