]> rtime.felk.cvut.cz Git - jenkicar/rpp-simulink.git/blob - rpp/rpp/rpp_srmain.tlc
Do not generate dead code in ert_main.c
[jenkicar/rpp-simulink.git] / rpp / rpp / rpp_srmain.tlc
1 %% Copyright (C) 2013-2014 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 %% References:
20 %%     Example in <matlabroot>/rtw/c/tlc/mw/bareboard_srmain.tlc
21
22
23 %selectfile NULL_FILE
24
25 %function FcnSingleTaskingMain() void
26
27     %if GenerateSampleERTMain
28         %assign CompiledModel.GenerateSampleERTMain = TLC_FALSE
29     %endif
30
31
32     %assign cFile = LibCreateSourceFile("Source", "Custom", "ert_main")
33
34
35     %%%%%%%%
36     %openfile tmpBuf
37
38     /* RPP includes */
39     #include "rpp/rpp.h"
40
41     /* RPP runtime includes */
42     #include "rpp_simulink_runtime.h"
43
44     /* Model includes */
45     #include "%<LibGetMdlPubHdrBaseName()>.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         while (rtmGetErrorStatus(%<modelName>_M) == NULL && !rtmGetStopRequested(%<modelName>_M)) {
108
109             /* Wait until next step */
110             vTaskDelayUntil(&last_wake_time, freq_ticks);
111
112             if (working) {
113                 /* Overrun detected */
114                 overrun_flag = TRUE;
115             } else {
116                 overrun_flag = FALSE;
117                 /* Release semaphore */
118                 xSemaphoreGive(step_signal);
119             }
120             steps_control++;
121
122             %if extMode == 1
123               rtExtModeCheckEndTrigger();
124             %endif
125
126         }
127
128         /* In case of shutdown, delete this task */
129         vTaskDelete(NULL);
130     }
131
132     /**
133      * Model step logic execution task.
134      */
135     void working_task(void* p)
136     {
137         /* Initialize model */
138         %<LibCallModelInitialize()>\
139
140         xSemaphoreGive(initialized_signal);
141
142         while (1) {
143
144             /* Lock semaphore */
145             if (xSemaphoreTake(step_signal, portMAX_DELAY)) {
146                 working = TRUE;
147                 %<LibCallModelStep(0)>\
148                 steps_working++;
149                 working = FALSE;
150             }
151         }
152
153         %% /* In case of shutdown, delete this task */
154         %% vTaskDelete(NULL);
155     }
156
157     %if extMode == 1
158       void ext_mode_comm_task(void* p)
159       {
160         drv_sci_set_crlf_conv_en(FALSE); /* Disable CR->CRLF conversion */
161
162         %<SLibGenERTExtModeInit()>
163         xSemaphoreGive(ext_mode_ready);
164
165         while (rtmGetErrorStatus(%<modelName>_M) == NULL && !rtmGetStopRequested(%<modelName>_M)) {
166           rtExtModeOneStep(rtmGetRTWExtModeInfo(%<modelName>_M), %<numSampleTimes>, (boolean_T *)&rtmGetStopRequested(%<modelName>_M));
167         }
168         rtExtModeShutdown(%<numSampleTimes>);
169         /* In case of shutdown, delete this task */
170         vTaskDelete(NULL);
171       }
172     %endif
173
174     /**
175      * Hardware initialization, task spawning and OS scheduler start.
176      */
177     void main(void)
178     {
179         /* Initialize RPP board */
180         rpp_init();
181
182         // Speed up the SCI
183         rpp_sci_setup(115200);
184
185         %if rppPrintMeta
186         %assign model_info = SPRINTF("'%s' - %s (TLC %s)\\r\\n", LibGetMdlPubHdrBaseName(), TLC_TIME, TLC_VERSION)
187         rpp_sci_printk("%<model_info>");
188         %endif
189
190         /* Create and lock semaphore */
191         vSemaphoreCreateBinary(step_signal);
192         xSemaphoreTake(step_signal, 0);
193         vSemaphoreCreateBinary(initialized_signal);
194         xSemaphoreTake(initialized_signal, 0);
195         %if extMode == 1
196           vSemaphoreCreateBinary(ext_mode_ready);
197           xSemaphoreTake(ext_mode_ready, 0);
198         %endif
199
200         /* Create tasks to step model and model task */
201         if (xTaskCreate(control_task, "control_task",
202             configMINIMAL_STACK_SIZE, NULL, CONTROL_PRIORITY, NULL) != pdPASS) {
203             rpp_sci_printk("ERROR: Cannot spawn control task.\r\n");
204             return;
205         }
206         if (xTaskCreate(working_task, "working_task",
207             %<rppModelTaskStack>, NULL, WORKING_PRIORITY, NULL) != pdPASS) {
208             rpp_sci_printk("ERROR: Cannot spawn model task.\r\n"
209             );
210             return;
211         }
212         %if extMode == 1
213           /* External mode */
214           rtParseArgsForExtMode(0, NULL);
215
216           if (xTaskCreate(ext_mode_comm_task, "ext_mode_comm_task", 1024, NULL, EXTMODE_PRIORITY, NULL) != pdPASS) {
217             rpp_sci_printk("ERROR: Cannot spawn model task.\r\n");
218             return;
219           }
220         %endif
221
222         /* Start FreeRTOS Scheduler */
223         vTaskStartScheduler();
224
225         /* We should never get here */
226         %<LibCallModelTerminate()>
227         rpp_sci_printk("ERROR: Problem allocating memory for idle task.\r\n");
228     }
229
230
231     #if configUSE_MALLOC_FAILED_HOOK == 1
232     /**
233      * FreeRTOS malloc() failed hook.
234      */
235      void vApplicationMallocFailedHook(void) {
236        rpp_sci_printk("ERROR: Memory allocation failed.\r\n");
237      }
238     #endif
239
240
241     #if configCHECK_FOR_STACK_OVERFLOW > 0
242     /**
243      * FreeRTOS stack overflow hook.
244      */
245     void vApplicationStackOverflowHook(xTaskHandle xTask, signed portCHAR *pcTaskName)
246     {
247       rpp_sci_printk("ERROR: Stack overflow : \"%s\".\r\n", pcTaskName);
248     }
249     #endif
250
251     %closefile tmpBuf
252     %<LibSetSourceFileSection(cFile, "Functions", tmpBuf)>
253     %%%%%%%%
254
255 %endfunction