]> rtime.felk.cvut.cz Git - jenkicar/rpp-simulink.git/blob - rpp/rpp/rpp_srmain.tlc
Fixed some really stupid one white space bug.
[jenkicar/rpp-simulink.git] / rpp / rpp / rpp_srmain.tlc
1 %% Copyright (C) 2013 Czech Technical University in Prague
2 %%
3 %% Authors:
4 %%     - Carlos Jenkins <carlos@jenkins.co.cr>
5 %%
6 %% This program is free software; you can redistribute it and/or modify
7 %% it under the terms of the GNU General Public License as published by
8 %% the Free Software Foundation; either version 2 of the License, or
9 %% (at your option) any later version.
10 %%
11 %% This program is distributed in the hope that it will be useful,
12 %% but WITHOUT ANY WARRANTY; without even the implied warranty of
13 %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 %% GNU General Public License for more details.
15 %%
16 %% You should have received a copy of the GNU General Public License
17 %% along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 %%
19 %% File : rpp_srmain.tlc
20 %% Abstract:
21 %%     Custom TLC file to generate an RPP "main" file.
22 %%
23 %%     This file generates the "main" file for the RPP target on top of the RPP
24 %%     library and the FreeRTOS operating system.
25 %%
26 %% References:
27 %%     Example in <matlabroot>/rtw/c/tlc/mw/bareboard_srmain.tlc
28
29
30 %selectfile NULL_FILE
31
32 %function FcnSingleTaskingMain() 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     /* RPP includes */
46     #include "rpp/rpp.h"
47
48     /* Model includes */
49     #include "%<LibGetMdlPubHdrBaseName()>.h"
50
51     %closefile tmpBuf
52     %<LibSetSourceFileSection(cFile, "Includes", tmpBuf)>
53     %%%%%%%%
54
55
56     %%%%%%%%
57     %openfile tmpBuf
58
59     /* Definitions */
60     #define STEP_SIZE_MILLIS %<CompiledModel.FundamentalStepSize>*1000.0
61     #define CONTROL_PRIORITY 2
62     #define WORKING_PRIORITY 1
63
64     %closefile tmpBuf
65     %<LibSetSourceFileSection(cFile, "Defines", tmpBuf)>
66     %%%%%%%%
67
68
69     %%%%%%%%
70     %openfile tmpBuf
71
72     static boolean_t WORKING = FALSE;
73     static boolean_t SHUTDOWN = FALSE;
74     static xSemaphoreHandle step_signal = NULL;
75     static uint32_t steps_control = 0;
76     static uint32_t steps_working = 0;
77
78     %closefile tmpBuf
79     %<LibSetSourceFileSection(cFile, "Declarations", tmpBuf)>
80     %%%%%%%%
81
82
83     %%%%%%%%
84     %openfile tmpBuf
85
86     /**
87      * Model step control and overrun detection task.
88      */
89     void control_task(void* p)
90     {
91
92         static const portTickType freq_ticks = STEP_SIZE_MILLIS / portTICK_RATE_MS;
93         portTickType last_wake_time = xTaskGetTickCount();
94
95         while(!SHUTDOWN) {
96
97             /* Wait until next step */
98             vTaskDelayUntil(&last_wake_time, freq_ticks);
99
100             if(WORKING) {
101                 /* Overrun detected */
102                 %<LibSetRTModelErrorStatus("\"Overrun\"")>;
103                 /* FIXME: Call overrun routine or set some overrun flag. */
104             } else {
105                 /* Release semaphore */
106                 xSemaphoreGive(step_signal);
107             }
108             steps_control++;
109
110         }
111
112         /* In case of shutdown, delete this task */
113         vTaskDelete(NULL);
114     }
115
116     /**
117      * Model step logic execution task.
118      */
119     void working_task(void* p)
120     {
121         while(!SHUTDOWN) {
122
123             /* Lock semaphore */
124             if(xSemaphoreTake(step_signal, portMAX_DELAY)) {
125                 WORKING = TRUE;
126                 %<LibCallModelStep(0)>\
127                 steps_working++;
128                 WORKING = FALSE;
129             }
130         }
131
132         /* In case of shutdown, delete this task */
133         vTaskDelete(NULL);
134     }
135
136
137     /**
138      * Hardware initialization, task spawning and OS scheduler start.
139      */
140     void main(void)
141     {
142         /* Initialize RPP board */
143         rpp_init();
144
145         %if rppPrintMeta
146         %assign model_info = SPRINTF("'%s' - %s (TLC %s)\\r\\n", LibGetMdlPubHdrBaseName(), TLC_TIME, TLC_VERSION)
147         rpp_sci_printf((const char*)
148                 "%<model_info>"
149             );
150         %endif
151
152         /* Initialize model */
153         %<LibCallModelInitialize()>\
154
155         /* Create and lock semaphore */
156         vSemaphoreCreateBinary(step_signal);
157         xSemaphoreTake(step_signal, 0);
158
159         /* Create tasks to step model and model task */
160         if(xTaskCreate(control_task, (const signed char*)"control_task",
161             configMINIMAL_STACK_SIZE, NULL, CONTROL_PRIORITY, NULL) != pdPASS) {
162             #ifdef DEBUG
163             rpp_sci_printf((const char*)
164                 "ERROR: Cannot spawn control task.\r\n"
165             );
166             #endif
167             while(TRUE) {
168                 asm("nop");
169             }
170         }
171         if(xTaskCreate(working_task, (const signed char*)"working_task",
172             %<rppModelTaskStack>, NULL, WORKING_PRIORITY, NULL) != pdPASS) {
173             #ifdef DEBUG
174             rpp_sci_printf((const char*)
175                 "ERROR: Cannot spawn model task.\r\n"
176             );
177             #endif
178             while(TRUE) {
179                 asm(" nop");
180             }
181         }
182
183         /* Start FreeRTOS Scheduler */
184         vTaskStartScheduler();
185
186         /* We should never get here */
187         %<LibCallModelTerminate()>\
188         #ifdef DEBUG
189         rpp_sci_printf((const char*)
190                 "ERROR: Problem allocating memory for idle task.\r\n"
191             );
192         #endif
193         while(TRUE) {
194             asm(" nop");
195         }
196     }
197
198
199     #if configUSE_MALLOC_FAILED_HOOK == 1
200     /**
201      * FreeRTOS malloc() failed hook.
202      */
203     void vApplicationMallocFailedHook(void) {
204         #ifdef DEBUG
205         rpp_sci_printf((const char*)
206                 "ERROR: manual memory allocation failed.\r\n"
207             );
208         #endif
209     }
210     #endif
211
212
213     #if configCHECK_FOR_STACK_OVERFLOW > 0
214     /**
215      * FreeRTOS stack overflow hook.
216      */
217     void vApplicationStackOverflowHook(xTaskHandle xTask,
218                                        signed portCHAR *pcTaskName) {
219         #ifdef DEBUG
220         rpp_sci_printf((const char*)
221                 "ERROR: Stack overflow : \"%s\".\r\n", pcTaskName
222             );
223         #endif
224     }
225     #endif
226
227     %closefile tmpBuf
228     %<LibSetSourceFileSection(cFile, "Functions", tmpBuf)>
229     %%%%%%%%
230
231 %endfunction