]> rtime.felk.cvut.cz Git - jenkicar/rpp-simulink.git/blob - rpp/rpp/rpp_srmain.tlc
Merge branches 'master' and 'rm48/master'
[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                 overrun_flag = FALSE;
128                 /* Release semaphore */
129                 xSemaphoreGive(step_signal);
130             }
131             steps_control++;
132
133             %if extMode == 1
134               rtExtModeCheckEndTrigger();
135             %endif
136
137         }
138
139         /* In case of shutdown, delete this task */
140         vTaskDelete(NULL);
141     }
142
143     /**
144      * Model step logic execution task.
145      */
146     void working_task(void* p)
147     {
148         /* Initialize model */
149         %<LibCallModelInitialize()>\
150         /* Step the model for any subrate */
151         xSemaphoreGive(initialized_signal);
152
153         while (1) {
154             if (xSemaphoreTake(step_signal, portMAX_DELAY)) {
155                 working = TRUE;
156                 %<LibCallModelStep(0)>\
157                 steps_working++;
158                 working = FALSE;
159             }
160         }
161
162         %% /* In case of shutdown, delete this task */
163         %% vTaskDelete(NULL);
164     }
165
166     %if extMode == 1
167       void ext_mode_comm_task(void* p)
168       {
169         drv_sci_set_crlf_conv_en(FALSE); /* Disable CR->CRLF conversion */
170
171         %<SLibGenERTExtModeInit()>
172         xSemaphoreGive(ext_mode_ready);
173
174         while (rtmGetErrorStatus(%<modelName>_M) == NULL && !rtmGetStopRequested(%<modelName>_M)) {
175           rtExtModeOneStep(rtmGetRTWExtModeInfo(%<modelName>_M), %<numSampleTimes>, (boolean_T *)&rtmGetStopRequested(%<modelName>_M));
176         }
177         rtExtModeShutdown(%<numSampleTimes>);
178         /* In case of shutdown, delete this task */
179         vTaskDelete(NULL);
180       }
181     %endif
182
183     /**
184      * Hardware initialization, task spawning and OS scheduler start.
185      */
186     void main(void)
187     {
188         /* Initialize RPP board */
189         %if EXISTS(::rpp_ain_present)
190             rpp_adc_init();
191         %endif
192         %if EXISTS(::rpp_gio_in_present) || EXISTS(::rpp_gio_out_present)
193             rpp_gio_init(RPP_GIO_PORT_ALL);
194         %endif
195         rpp_sci_init();
196
197         // Speed up the SCI
198         rpp_sci_setup(115200);
199
200         %if rppPrintMeta
201         %assign model_info = SPRINTF("'%s' - %s (TLC %s)\\r\\n", LibGetMdlPubHdrBaseName(), TLC_TIME, TLC_VERSION)
202         rpp_sci_printk("%<model_info>");
203         %endif
204
205         /* Create and lock semaphore */
206         vSemaphoreCreateBinary(step_signal);
207         xSemaphoreTake(step_signal, 0);
208         vSemaphoreCreateBinary(initialized_signal);
209         xSemaphoreTake(initialized_signal, 0);
210         %if extMode == 1
211           vSemaphoreCreateBinary(ext_mode_ready);
212           xSemaphoreTake(ext_mode_ready, 0);
213         %endif
214
215         /* Create tasks to step model and model task */
216         if (xTaskCreate(control_task, "control_task",
217             configMINIMAL_STACK_SIZE, NULL, CONTROL_PRIORITY, NULL) != pdPASS) {
218             rpp_sci_printk("ERROR: Cannot spawn control task.\r\n");
219             return;
220         }
221         if (xTaskCreate(working_task, "working_task",
222             %<rppModelTaskStack>, NULL, WORKING_PRIORITY, NULL) != pdPASS) {
223             rpp_sci_printk("ERROR: Cannot spawn model task.\r\n"
224             );
225             return;
226         }
227         %if extMode == 1
228           /* External mode */
229           rtParseArgsForExtMode(0, NULL);
230
231           if (xTaskCreate(ext_mode_comm_task, "ext_mode_comm_task", 1024, NULL, EXTMODE_PRIORITY, NULL) != pdPASS) {
232             rpp_sci_printk("ERROR: Cannot spawn model task.\r\n");
233             return;
234           }
235         %endif
236
237         /* Start FreeRTOS Scheduler */
238         vTaskStartScheduler();
239
240         /* We should never get here */
241         %<LibCallModelTerminate()>
242         rpp_sci_printk("ERROR: Problem allocating memory for idle task.\r\n");
243     }
244
245
246     #if configUSE_MALLOC_FAILED_HOOK == 1
247     /**
248      * FreeRTOS malloc() failed hook.
249      */
250      void vApplicationMallocFailedHook(void) {
251        rpp_sci_printk("ERROR: Memory allocation failed.\r\n");
252      }
253     #endif
254
255
256     #if configCHECK_FOR_STACK_OVERFLOW > 0
257     /**
258      * FreeRTOS stack overflow hook.
259      */
260     void vApplicationStackOverflowHook(xTaskHandle xTask, signed portCHAR *pcTaskName)
261     {
262       rpp_sci_printk("ERROR: Stack overflow : \"%s\".\r\n", pcTaskName);
263     }
264     #endif
265
266     %closefile tmpBuf
267     %<LibSetSourceFileSection(cFile, "Functions", tmpBuf)>
268     %%%%%%%%
269
270 %endfunction