]> rtime.felk.cvut.cz Git - jenkicar/rpp-simulink.git/blob - rpp/rpp/rpp_srmain.tlc
Merge branch 'master' of rtime:jenkicar/rpp-simulink
[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     /* Model includes */
42     #include "%<LibGetMdlPubHdrBaseName()>.h"
43
44     %if extMode == 1
45       /* External mode header file */
46       #include "ext_work.h"
47       #include <drv/sci.h>
48     %endif
49
50     %closefile tmpBuf
51     %<LibSetSourceFileSection(cFile, "Includes", tmpBuf)>
52     %%%%%%%%
53
54
55     %%%%%%%%
56     %openfile tmpBuf
57
58     /* Definitions */
59     #define STEP_SIZE_MILLIS %<CompiledModel.FundamentalStepSize>*1000.0
60     #define CONTROL_PRIORITY 3
61     #define WORKING_PRIORITY 2
62     #define EXTMODE_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 xSemaphoreHandle step_signal = NULL;
74     static xSemaphoreHandle initialized_signal = NULL;
75     %if extMode == 1
76       static xSemaphoreHandle ext_mode_ready = NULL;
77     %endif
78     static uint32_t steps_control = 0;
79     static uint32_t steps_working = 0;
80
81     %closefile tmpBuf
82     %<LibSetSourceFileSection(cFile, "Declarations", tmpBuf)>
83     %%%%%%%%
84
85
86     %%%%%%%%
87     %openfile tmpBuf
88
89     /**
90      * Model step control and overrun detection task.
91      */
92     void control_task(void* p)
93     {
94
95       xSemaphoreTake(initialized_signal, portMAX_DELAY);
96       %if extMode == 1
97         xSemaphoreTake(ext_mode_ready, portMAX_DELAY);
98       %endif
99
100         static const portTickType freq_ticks = STEP_SIZE_MILLIS / portTICK_RATE_MS;
101         portTickType last_wake_time = xTaskGetTickCount();
102
103         while (rtmGetErrorStatus(%<modelName>_M) == NULL && !rtmGetStopRequested(%<modelName>_M)) {
104
105             /* Wait until next step */
106             vTaskDelayUntil(&last_wake_time, freq_ticks);
107
108             if (WORKING) {
109                 /* Overrun detected */
110                 %<LibSetRTModelErrorStatus("\"Overrun\"")>;
111                 /* FIXME: Call overrun routine or set some overrun flag. */
112             } else {
113                 /* Release semaphore */
114                 xSemaphoreGive(step_signal);
115             }
116             steps_control++;
117
118             %if extMode == 1
119               rtExtModeCheckEndTrigger();
120             %endif
121
122         }
123
124         /* In case of shutdown, delete this task */
125         vTaskDelete(NULL);
126     }
127
128     /**
129      * Model step logic execution task.
130      */
131     void working_task(void* p)
132     {
133         /* Initialize model */
134         %<LibCallModelInitialize()>\
135
136         xSemaphoreGive(initialized_signal);
137
138         while (1) {
139
140             /* Lock semaphore */
141             if (xSemaphoreTake(step_signal, portMAX_DELAY)) {
142                 WORKING = TRUE;
143                 %<LibCallModelStep(0)>\
144                 steps_working++;
145                 WORKING = FALSE;
146             }
147         }
148
149         /* In case of shutdown, delete this task */
150         vTaskDelete(NULL);
151     }
152
153     %if extMode == 1
154       void ext_mode_comm_task(void* p)
155       {
156         drv_sci_set_crlf_conv_en(FALSE); /* Disable CR->CRLF conversion */
157
158         %<SLibGenERTExtModeInit()>
159         xSemaphoreGive(ext_mode_ready);
160
161         while (rtmGetErrorStatus(%<modelName>_M) == NULL && !rtmGetStopRequested(%<modelName>_M)) {
162           rtExtModeOneStep(rtmGetRTWExtModeInfo(%<modelName>_M), %<numSampleTimes>, (boolean_T *)&rtmGetStopRequested(%<modelName>_M));
163         }
164         rtExtModeShutdown(%<numSampleTimes>);
165         /* In case of shutdown, delete this task */
166         vTaskDelete(NULL);
167       }
168     %endif
169
170     /**
171      * Hardware initialization, task spawning and OS scheduler start.
172      */
173     void main(void)
174     {
175         /* Initialize RPP board */
176         rpp_init();
177
178         // Speed up the SCI
179         rpp_sci_setup(115200);
180
181         %if rppPrintMeta
182         %assign model_info = SPRINTF("'%s' - %s (TLC %s)\\r\\n", LibGetMdlPubHdrBaseName(), TLC_TIME, TLC_VERSION)
183         rpp_sci_printk("%<model_info>");
184         %endif
185
186         /* Create and lock semaphore */
187         vSemaphoreCreateBinary(step_signal);
188         xSemaphoreTake(step_signal, 0);
189         vSemaphoreCreateBinary(initialized_signal);
190         xSemaphoreTake(initialized_signal, 0);
191         %if extMode == 1
192           vSemaphoreCreateBinary(ext_mode_ready);
193           xSemaphoreTake(ext_mode_ready, 0);
194         %endif
195
196         /* Create tasks to step model and model task */
197         if (xTaskCreate(control_task, "control_task",
198             configMINIMAL_STACK_SIZE, NULL, CONTROL_PRIORITY, NULL) != pdPASS) {
199             rpp_sci_printk("ERROR: Cannot spawn control task.\r\n");
200             return;
201         }
202         if (xTaskCreate(working_task, "working_task",
203             %<rppModelTaskStack>, NULL, WORKING_PRIORITY, NULL) != pdPASS) {
204             rpp_sci_printk("ERROR: Cannot spawn model task.\r\n"
205             );
206             return;
207         }
208         %if extMode == 1
209           /* External mode */
210           rtParseArgsForExtMode(0, NULL);
211
212           if (xTaskCreate(ext_mode_comm_task, "ext_mode_comm_task", 1024, NULL, EXTMODE_PRIORITY, NULL) != pdPASS) {
213             rpp_sci_printk("ERROR: Cannot spawn model task.\r\n");
214             return;
215           }
216         %endif
217
218         /* Start FreeRTOS Scheduler */
219         vTaskStartScheduler();
220
221         /* We should never get here */
222         %<LibCallModelTerminate()>
223         rpp_sci_printk("ERROR: Problem allocating memory for idle task.\r\n");
224     }
225
226
227     #if configUSE_MALLOC_FAILED_HOOK == 1
228     /**
229      * FreeRTOS malloc() failed hook.
230      */
231      void vApplicationMallocFailedHook(void) {
232        rpp_sci_printk("ERROR: Memory allocation failed.\r\n");
233      }
234     #endif
235
236
237     #if configCHECK_FOR_STACK_OVERFLOW > 0
238     /**
239      * FreeRTOS stack overflow hook.
240      */
241     void vApplicationStackOverflowHook(xTaskHandle xTask, signed portCHAR *pcTaskName)
242     {
243       rpp_sci_printk("ERROR: Stack overflow : \"%s\".\r\n", pcTaskName);
244     }
245     #endif
246
247     %closefile tmpBuf
248     %<LibSetSourceFileSection(cFile, "Functions", tmpBuf)>
249     %%%%%%%%
250
251 %endfunction