]> rtime.felk.cvut.cz Git - jenkicar/rpp-simulink.git/blob - rpp/rpp/rpp_srmain.tlc
Added overrun flag notification. Removed includes, because will be generated by each...
[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 file processing to generate a "main" file.
22 %%
23 %% References:
24 %%     Example in <matlabroot>/rtw/c/tlc/mw/bareboard_srmain.tlc
25
26
27 %selectfile NULL_FILE
28
29 %function FcnSingleTaskingMain() void
30
31     %if GenerateSampleERTMain
32         %assign CompiledModel.GenerateSampleERTMain = TLC_FALSE
33     %endif
34
35
36     %assign cFile = LibCreateSourceFile("Source", "Custom", "ert_main")
37
38
39     %%%%%%%%
40     %openfile tmpBuf
41
42     /* Standard includes */
43     #include <stdbool.h>
44
45     /* Kernel includes */
46     #include "FreeRTOS.h"
47     #include "os_task.h"
48     #include "os_semphr.h"
49     %% FIXME: Return to original file names
50     %%#include "task.h"
51     %%#include "semphr.h"
52
53     /* Model includes */
54     #include "%<LibGetMdlPubHdrBaseName()>.h"
55
56     %closefile tmpBuf
57     %<LibSetSourceFileSection(cFile, "Includes", tmpBuf)>
58     %%%%%%%%
59
60
61     %%%%%%%%
62     %openfile tmpBuf
63
64     #define STEP_SIZE_MILLIS (%<CompiledModel.FundamentalStepSize>*1000.0)
65     #define CONTROL_PRIORITY 2
66     #define WORKING_PRIORITY 1
67
68     %closefile tmpBuf
69     %<LibSetSourceFileSection(cFile, "Defines", tmpBuf)>
70     %%%%%%%%
71
72
73     %%%%%%%%
74     %openfile tmpBuf
75
76     bool WORKING = false;
77     bool SHUTDOWN = false;
78     xSemaphoreHandle step_signal = NULL;
79
80     %closefile tmpBuf
81     %<LibSetSourceFileSection(cFile, "Declarations", tmpBuf)>
82     %%%%%%%%
83
84
85     %%%%%%%%
86     %openfile tmpBuf
87
88     /**
89      * Model step control and overrun detection task.
90      */
91     void control_task(void *p) {
92
93         const portTickType freq_ticks = STEP_SIZE_MILLIS / portTICK_RATE_MS;
94         portTickType last_wake_time = xTaskGetTickCount();
95
96         while(!SHUTDOWN) {
97
98             // Wait until next step
99             vTaskDelayUntil(&last_wake_time, freq_ticks);
100
101             if(WORKING) {
102                 // Overrun detected
103                 %<LibSetRTModelErrorStatus("\"Overrun\"")>;
104                 // FIXME: Call overrun routine
105             } else {
106                 // Release semaphore
107                 xSemaphoreGive(step_signal);
108             }
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                 WORKING = false;
128             }
129         }
130
131         /* In case of shutdown, delete this task */
132         vTaskDelete(NULL);
133     }
134
135
136     /**
137      * Hardware initialization, task spawning and OS scheduler start.
138      */
139     void main(void)
140     {
141
142         /* Initialize peripherals */
143         // FIXME: Implement conditional init()'s
144         _enable_IRQ();
145
146         /* Initialize model */
147         %<LibCallModelInitialize()>\
148
149         /* Create and lock semaphore */
150         vSemaphoreCreateBinary(step_signal);
151         xSemaphoreTake(step_signal, 0);
152
153         /* Create tasks to step model and start scheduler */
154         // FIXME: How to calculate / policy about model stack size
155         xTaskCreate(control_task, (signed char*) "control_task", 128,  NULL,
156             CONTROL_PRIORITY, NULL);
157         xTaskCreate(working_task, (signed char*) "working_task", 4096, NULL,
158             WORKING_PRIORITY, NULL);
159         vTaskStartScheduler();
160
161         // We should never get here
162         %<LibCallModelTerminate()>\
163         while(true) {
164         }
165     }
166
167     %closefile tmpBuf
168     %<LibSetSourceFileSection(cFile, "Functions", tmpBuf)>
169     %%%%%%%%
170
171 %endfunction