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