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