]> rtime.felk.cvut.cz Git - jenkicar/rpp-simulink.git/blob - rpp/rpp/rpp_mrmain.tlc
933c4ea0c59d1388085ba1cd6b868c0cf40c83d2
[jenkicar/rpp-simulink.git] / rpp / rpp / rpp_mrmain.tlc
1 %% Copyright (C) 2013-2015 Czech Technical University in Prague
2 %%
3 %% Authors:
4 %%     - Carlos Jenkins <carlos@jenkins.co.cr>
5 %%     - Michal Sojka <sojkam1@fel.cvut.cz>
6 %%
7 %% This document contains proprietary information belonging to Czech
8 %% Technical University in Prague. Passing on and copying of this
9 %% document, and communication of its contents is not permitted
10 %% without prior written authorization.
11 %%
12 %% File : rpp_mrmain.tlc
13 %% Abstract:
14 %%     Custom TLC file to generate an RPP "main" file.
15 %%
16 %%     This file generates the "main" file for the RPP target on top of the RPP
17 %%     library and the FreeRTOS operating system.
18 %%
19 %%     The mr prefix is standard to mark Multi Tasking main, which is the case. See 
20 %%     rpp_file_process.m description above for more information about this.
21 %%
22 %%     !!!!!!!!!!!!!!!!!!!!!!!!
23 %%     !!! This is not ready to use source code. It is just a concept with some ideas
24 %%     !!! from our experiments and has to be reworked.
25 %%     !!!!!!!!!!!!!!!!!!!!!!!!
26 %% References:
27 %%     Example in <matlabroot>/rtw/c/tlc/mw/bareboard_mrmain.tlc
28
29
30 %selectfile NULL_FILE
31
32 %function FcnMultiTaskingMain() void
33
34     %if GenerateSampleERTMain
35         %assign CompiledModel.GenerateSampleERTMain = TLC_FALSE
36     %endif
37
38
39     %assign cFile = LibCreateSourceFile("Source", "Custom", "ert_main")
40
41
42     %%%%%%%%
43     %openfile tmpBuf
44
45     /* Model includes */
46     #include "%<LibGetMdlPubHdrBaseName()>.h"
47
48     /* RPP runtime includes */
49     #include "rpp_simulink_runtime.h"
50
51     %if extMode == 1
52       /* External mode header file */
53       #include "ext_work.h"
54       #include <drv/sci.h>
55     %endif
56
57     %closefile tmpBuf
58     %<LibSetSourceFileSection(cFile, "Includes", tmpBuf)>
59     %%%%%%%%
60
61
62     %%%%%%%%
63     %openfile tmpBuf
64
65     /* Definitions */
66     #define STEP_SIZE_MILLIS %<CompiledModel.FundamentalStepSize>*1000.0
67     #define CONTROL_PRIORITY 3
68     #define WORKING_PRIORITY 2
69     #define EXTMODE_PRIORITY 1
70
71     %closefile tmpBuf
72     %<LibSetSourceFileSection(cFile, "Defines", tmpBuf)>
73     %%%%%%%%
74
75
76     %%%%%%%%
77     %openfile tmpBuf
78
79     static boolean_t working = FALSE;
80     static xSemaphoreHandle step_signal = NULL;
81     static xSemaphoreHandle initialized_signal = NULL;
82     %if extMode == 1
83       static xSemaphoreHandle ext_mode_ready = NULL;
84     %endif
85     static uint32_t steps_control = 0;
86     static uint32_t steps_working = 0;
87     boolean_t overrun_flag = FALSE;
88
89     %closefile tmpBuf
90     %<LibSetSourceFileSection(cFile, "Declarations", tmpBuf)>
91     %%%%%%%%
92
93
94     %%%%%%%%
95     %openfile tmpBuf
96
97     /**
98      * Model step control and overrun detection task.
99      */
100     void control_task(void* p)
101     {
102
103       xSemaphoreTake(initialized_signal, portMAX_DELAY);
104       %if extMode == 1
105         xSemaphoreTake(ext_mode_ready, portMAX_DELAY);
106       %endif
107
108         static const portTickType freq_ticks = STEP_SIZE_MILLIS / portTICK_RATE_MS;
109         portTickType last_wake_time = xTaskGetTickCount();
110
111     %% This condition has been added because of the warning:
112     %% "ert_main.c", line 46: warning #238-D: controlling expression is constant
113     %% caused by the expression (void*) 0 passed to the while statement. The rtmGetStopRequested
114     %% macro is defined to this constant if and only if the GenerateSampleERTMain is not set. So
115     %% The condition is not needed in this case as well.
116     %%
117     %% See <MATLAB_ROOT>/rtw/c/tlc/mw/rtmspecmacs.tlc at line 198.
118
119     %if !GenerateSampleERTMain
120         while (rtmGetErrorStatus(%<modelName>_M) == NULL) {
121     %else
122         while (rtmGetErrorStatus(%<modelName>_M) == NULL && !rtmGetStopRequested(%<modelName>_M)) {
123     %endif
124             /* Wait until next step */
125             vTaskDelayUntil(&last_wake_time, freq_ticks);
126
127             if (working) {
128                 /* Overrun detected */
129                 overrun_flag = TRUE;
130             } else {
131                 overrun_flag = FALSE;
132                 /* Release semaphore */
133                 xSemaphoreGive(step_signal);
134             }
135             steps_control++;
136
137             %if extMode == 1
138               rtExtModeCheckEndTrigger();
139             %endif
140
141         }
142
143         /* In case of shutdown, delete this task */
144         vTaskDelete(NULL);
145     }
146
147     /**
148      * Model step logic execution task.
149      */
150     void working_task(void* p)
151     {
152         %% This idea might be useful in the MR implementation
153             %if LibNumSynchronousSampleTimes() > 1
154                 static  int_T taskCounter[%<FcnNumST()>] = %<FcnInitializeTaskCounter()>;
155             %endif
156         %% ----
157         /* Initialize model */
158         %<LibCallModelInitialize()>\
159         /* Step the model for any subrate */
160         xSemaphoreGive(initialized_signal);
161
162         while (1) {
163             if (xSemaphoreTake(step_signal, portMAX_DELAY)) {
164                 working = TRUE;
165
166                 %<LibCallModelStep(0)>\
167                         
168                 %% This idea might be useful in the MR implementation
169
170                 %if LibNumSynchronousSampleTimes() > 1
171                   %foreach idx = LibGetNumSyncPeriodicTasks() - 1
172                     %assign tid = 1 + idx + tid01Eq
173                     /* Task %<tid> handling */
174                     if (taskCounter[%<tid>] == 0) {
175                       %<LibCallModelStep(tid)>\
176                     }
177                     if (++taskCounter[%<tid>] == %< FcnComputeTaskTickLimit(tid)>)
178                       taskCounter[%<tid>]=0;
179                   %endforeach
180                 %endif
181                 
182                 %% ----
183                                                 
184                 steps_working++;
185                 working = FALSE;
186             }
187         }
188
189         %% /* In case of shutdown, delete this task */
190         %% vTaskDelete(NULL);
191     }
192
193     %if extMode == 1
194       void ext_mode_comm_task(void* p)
195       {
196         drv_sci_set_crlf_conv_en(FALSE); /* Disable CR->CRLF conversion */
197
198         %<SLibGenERTExtModeInit()>
199         xSemaphoreGive(ext_mode_ready);
200
201         while (rtmGetErrorStatus(%<modelName>_M) == NULL && !rtmGetStopRequested(%<modelName>_M)) {
202           rtExtModeOneStep(rtmGetRTWExtModeInfo(%<modelName>_M), %<numSampleTimes>, (boolean_T *)&rtmGetStopRequested(%<modelName>_M));
203         }
204         rtExtModeShutdown(%<numSampleTimes>);
205         /* In case of shutdown, delete this task */
206         vTaskDelete(NULL);
207       }
208     %endif
209
210     /**
211      * Hardware initialization, task spawning and OS scheduler start.
212      */
213     void main(void)
214     {
215         /* Initialize RPP board */
216         %if EXISTS(::rpp_ain_present)
217             rpp_adc_init();
218         %endif
219         %if EXISTS(::rpp_din_present) || EXISTS(::rpp_dout_present)
220             rpp_gio_init(RPP_GIO_PORT_ALL);
221         %endif
222         rpp_sci_init();
223
224         // Speed up the SCI
225         rpp_sci_setup(115200);
226
227         %if rppPrintMeta
228         %assign model_info = SPRINTF("'%s' - %s (TLC %s)\\r\\n", LibGetMdlPubHdrBaseName(), TLC_TIME, TLC_VERSION)
229         rpp_sci_printk("%<model_info>");
230         %endif
231
232         /* Create and lock semaphore */
233         vSemaphoreCreateBinary(step_signal);
234         xSemaphoreTake(step_signal, 0);
235         vSemaphoreCreateBinary(initialized_signal);
236         xSemaphoreTake(initialized_signal, 0);
237         %if extMode == 1
238           vSemaphoreCreateBinary(ext_mode_ready);
239           xSemaphoreTake(ext_mode_ready, 0);
240         %endif
241
242         /* Create tasks to step model and model task */
243         if (xTaskCreate(control_task, "control_task",
244             configMINIMAL_STACK_SIZE, NULL, CONTROL_PRIORITY, NULL) != pdPASS) {
245             rpp_sci_printk("ERROR: Cannot spawn control task.\r\n");
246             return;
247         }
248         if (xTaskCreate(working_task, "working_task",
249             %<rppModelTaskStack>, NULL, WORKING_PRIORITY, NULL) != pdPASS) {
250             rpp_sci_printk("ERROR: Cannot spawn model task.\r\n"
251             );
252             return;
253         }
254         %if extMode == 1
255           /* External mode */
256           rtParseArgsForExtMode(0, NULL);
257
258           if (xTaskCreate(ext_mode_comm_task, "ext_mode_comm_task", 1024, NULL, EXTMODE_PRIORITY, NULL) != pdPASS) {
259             rpp_sci_printk("ERROR: Cannot spawn model task.\r\n");
260             return;
261           }
262         %endif
263
264         /* Start FreeRTOS Scheduler */
265         vTaskStartScheduler();
266
267         /* We should never get here */
268         %<LibCallModelTerminate()>
269         rpp_sci_printk("ERROR: Problem allocating memory for idle task.\r\n");
270     }
271
272
273     #if configUSE_MALLOC_FAILED_HOOK == 1
274     /**
275      * FreeRTOS malloc() failed hook.
276      */
277      void vApplicationMallocFailedHook(void) {
278        rpp_sci_printk("ERROR: Memory allocation failed.\r\n");
279      }
280     #endif
281
282
283     #if configCHECK_FOR_STACK_OVERFLOW > 0
284     /**
285      * FreeRTOS stack overflow hook.
286      */
287     void vApplicationStackOverflowHook(xTaskHandle xTask, signed portCHAR *pcTaskName)
288     {
289       rpp_sci_printk("ERROR: Stack overflow : \"%s\".\r\n", pcTaskName);
290     }
291     #endif
292
293     %closefile tmpBuf
294     %<LibSetSourceFileSection(cFile, "Functions", tmpBuf)>
295     %%%%%%%%
296
297 %endfunction