1 %% Copyright (C) 2013-2015 Czech Technical University in Prague
4 %% - Carlos Jenkins <carlos@jenkins.co.cr>
5 %% - Michal Sojka <sojkam1@fel.cvut.cz>
6 %% - Michal Horn <hornmich@fel.cvut.cz>
8 %% This document contains proprietary information belonging to Czech
9 %% Technical University in Prague. Passing on and copying of this
10 %% document, and communication of its contents is not permitted
11 %% without prior written authorization.
13 %% File : rpp_mrmain.tlc
15 %% Custom TLC file to generate an RPP "main" file.
17 %% This file generates the "main" file for the RPP target on top of the RPP
18 %% library and the FreeRTOS operating system.
20 %% The mr prefix is standard to mark Multi Tasking main, which is the case. See
21 %% rpp_file_process.m description above for more information about this.
24 %% Example in <matlabroot>/rtw/c/tlc/mw/bareboard_mrmain.tlc
29 %function FcnMultiTaskingMain() void
31 %if GenerateSampleERTMain
32 %assign CompiledModel.GenerateSampleERTMain = TLC_FALSE
35 %assign cFile = LibCreateSourceFile("Source", "Custom", "ert_main")
37 %if LibIsSingleTasking()
41 %assign taskCount = numSampleTimes - tid01Eq
42 %assign firstTask = tid01Eq
50 #include "%<LibGetMdlPubHdrBaseName()>.h"
52 /* RPP runtime includes */
53 #include "rpp_simulink_runtime.h"
56 /* External mode header file */
63 %<LibSetSourceFileSection(cFile, "Includes", tmpBuf)>
71 #define STEP_SIZE_MILLIS (%<CompiledModel.FundamentalStepSize>*1000.0)
72 #define NUM_TASKS %<taskCount>
73 #define CONTROL_PRIORITY (configMAX_PRIORITIES - 1)
75 %% Worker task priority assignment - rate transition block
76 %% requires rate monotonic priority assignment
77 %foreach i = taskCount
78 #define WORKING%<i + firstTask>_PRIORITY (configMAX_PRIORITIES - %<2 + i>)
82 #define EXTMODE_PRIORITY 1
84 #define IDLE_PRIORITY 0
85 #define EXTMODE_PRIORITY IDLE_PRIORITY /* Extmode not used */
88 %foreach i = taskCount
89 %assign j = i + firstTask
90 #if (WORKING%<j>_PRIORITY <= EXTMODE_PRIORITY) || (WORKING%<j>_PRIORITY >= CONTROL_PRIORITY)
91 #error Too many tasks. Increase configMAX_PRIORITIES.
96 %<LibSetSourceFileSection(cFile, "Defines", tmpBuf)>
102 typedef struct sub_rate_st {
104 xSemaphoreHandle sem;
108 static xSemaphoreHandle ext_mode_ready = NULL;
110 static uint32_t steps_control = 0;
111 static uint32_t steps_working[NUM_TASKS];
112 boolean_t overrun_flag = FALSE;
113 static sub_rate_t sub_rate[NUM_TASKS];
114 static boolean_t simulationFinished = 0;
117 %<LibSetSourceFileSection(cFile, "Declarations", tmpBuf)>
125 * Model step control and overrun detection task.
127 void control_task(void* p)
130 %if !LibIsSingleTasking()
133 %% Variables used by LibCallSetEventForThisBaseStep (static => zero initialized)
134 static uint32_t taskCounter[NUM_TASKS];
135 static boolean_t eventFlags[NUM_TASKS];
136 static boolean_t OverrunFlags[NUM_TASKS];
138 (void)OverrunFlags; /* Not used in multitasking mode, but required by TLC macro */
143 xSemaphoreTake(ext_mode_ready, portMAX_DELAY);
146 /* Initialize model */
147 %<LibCallModelInitialize()>\
149 /* Start periodic execution */
150 static const portTickType freq_ticks = STEP_SIZE_MILLIS / portTICK_RATE_MS;
151 portTickType last_wake_time = xTaskGetTickCount();
153 %% This condition has been added because of the warning:
154 %% "ert_main.c", line 46: warning #238-D: controlling expression is constant
155 %% caused by the expression (void*) 0 passed to the while statement. The rtmGetStopRequested
156 %% macro is defined to this constant if and only if the GenerateSampleERTMain is not set. So
157 %% The condition is not needed in this case as well.
159 %% See <MATLAB_ROOT>/rtw/c/tlc/mw/rtmspecmacs.tlc at line 198.
161 %if !GenerateSampleERTMain
162 while (rtmGetErrorStatus(%<modelName>_M) == NULL) {
164 while (rtmGetErrorStatus(%<modelName>_M) == NULL && !rtmGetStopRequested(%<modelName>_M)) {
166 /* Wait until next step */
167 vTaskDelayUntil(&last_wake_time, freq_ticks);
169 %if !LibIsSingleTasking()
170 /* Mark rates that need to run this time step */
171 %<LibCallSetEventForThisBaseStep("eventFlags")>\
174 /* Trigger working threads */
175 %foreach j = taskCount
176 %assign i = j + firstTask
177 %assign s = CompiledModel.SampleTime[i].PeriodAndOffset[0]
178 %assign o = CompiledModel.SampleTime[i].PeriodAndOffset[1]
179 /* Sampling rate %<i>, sample time = %<s>, offset = %<o> */
182 %if LibIsSingleTasking()
186 for (%<i> = %<firstTask>; %<i> < NUM_TASKS; %<i>++) {
187 if (%<i> == 0 || eventFlags[%<i>]) {
188 eventFlags[%<i>] = FALSE;
190 uint32_t step_sem_value = uxQueueMessagesWaiting(sub_rate[%<i>].sem);
191 if (step_sem_value) {
192 %% Commented out so that overrun does stop the whole execution
193 %% rtmSetErrorStatus(%<modelName>_M, "Overrun");
197 xSemaphoreGive(sub_rate[%<i>].sem);
198 xSemaphoreGive(sub_rate[%<i>].sem);
199 %if !LibIsSingleTasking()
207 rtExtModeCheckEndTrigger();
211 simulationFinished = 1;
214 %if !LibIsSingleTasking()
215 for (%<i> = %<firstTask>; %<i> < NUM_TASKS; %<i>++) {
217 xSemaphoreGive(sub_rate[%<i>].sem);
218 xSemaphoreGive(sub_rate[%<i>].sem);
219 %if !LibIsSingleTasking()
223 /* In case of shutdown, delete this task */
227 %foreach j = taskCount
228 %assign i = j + firstTask
230 * Model step logic execution task for sample time %<CompiledModel.SampleTime[i].ClockTickStepSize>.
232 void working_task%<i>(void *p)
234 steps_working[%<i>] = 0;
236 while(!simulationFinished) {
237 xSemaphoreTake(sub_rate[%<i>].sem, portMAX_DELAY); /* Sem_val = 1 */
238 %<LibCallModelStep(i)>\
239 steps_working[%<i>]++;
240 xSemaphoreTake(sub_rate[%<i>].sem, portMAX_DELAY); /* Sem_val = 0 */
243 %% /* In case of shutdown, delete this task */
249 void ext_mode_comm_task(void* p)
251 drv_sci_set_crlf_conv_en(FALSE); /* Disable CR->CRLF conversion */
253 %<SLibGenERTExtModeInit()>
254 xSemaphoreGive(ext_mode_ready);
256 while (rtmGetErrorStatus(%<modelName>_M) == NULL && !rtmGetStopRequested(%<modelName>_M)) {
257 rtExtModeOneStep(rtmGetRTWExtModeInfo(%<modelName>_M), %<numSampleTimes>, (boolean_T *)&rtmGetStopRequested(%<modelName>_M));
259 rtExtModeShutdown(%<numSampleTimes>);
260 /* In case of shutdown, delete this task */
266 * Hardware initialization, task spawning and OS scheduler start.
270 /* Initialize RPP board */
271 /* Initialize RPP board */
272 %if EXISTS(::rpp_ain_present)
275 %if EXISTS(::rpp_aout_present)
278 %if EXISTS(::rpp_din_present)
281 %if EXISTS(::rpp_hbr_present)
284 %if EXISTS(::rpp_irc_present)
287 %if EXISTS(::rpp_lout_present)
290 %if EXISTS(::rpp_mout_present)
293 %if EXISTS(::rpp_sdr_present)
296 %if EXISTS(::rpp_gio_in_present) || EXISTS(::rpp_gio_out_present)
297 rpp_gio_init(RPP_GIO_PORT_ALL);
306 rpp_sci_setup(115200);
309 %assign model_info = SPRINTF("'%s' - %s (TLC %s)\\r\\n", LibGetMdlPubHdrBaseName(), TLC_TIME, TLC_VERSION)
310 rpp_sci_printk("%<model_info>");
314 vSemaphoreCreateBinary(ext_mode_ready);
315 xSemaphoreTake(ext_mode_ready, 0);
318 %foreach j = taskCount
319 %assign i = j + firstTask
320 %assign s = CompiledModel.SampleTime[i].PeriodAndOffset[0]
321 %assign o = CompiledModel.SampleTime[i].PeriodAndOffset[1]
323 /* Initializing the step semaphore of the loop %<i> */
324 sub_rate[%<i>].sem = xSemaphoreCreateCounting(2, 0);
325 if (sub_rate[%<i>].sem == NULL) {
326 rpp_sci_printk("ERROR: Can not create semaphore for task %<i>.\r\n");
330 /* Starting loop %<i> thread for sample time = %<s>s, offset = %<o>s. */
331 if (xTaskCreate(working_task%<i>, "working_task%<i>",
332 %<rppModelTaskStack>, NULL, WORKING%<i>_PRIORITY,
333 &sub_rate[%<i>].thread ) != pdPASS) {
334 rpp_sci_printk("ERROR: Cannot spawn working task %<i>.\r\n");
339 /* Create tasks to step model and model task */
341 if (xTaskCreate(control_task, "control_task",
342 %<rppModelTaskStack>, NULL, CONTROL_PRIORITY,
344 rpp_sci_printk("ERROR: Cannot spawn control task.\r\n");
350 rtParseArgsForExtMode(0, NULL);
352 if (xTaskCreate(ext_mode_comm_task, "ext_mode_comm_task", 1024, NULL, EXTMODE_PRIORITY, NULL) != pdPASS) {
353 rpp_sci_printk("ERROR: Cannot spawn model task.\r\n");
358 /* Start FreeRTOS Scheduler */
359 vTaskStartScheduler();
361 /* We should never get here */
362 %<LibCallModelTerminate()>\
363 rpp_sci_printk("ERROR: Problem allocating memory for idle task.\r\n");
368 #if configUSE_MALLOC_FAILED_HOOK == 1
370 * FreeRTOS malloc() failed hook.
372 void vApplicationMallocFailedHook(void) {
373 rpp_sci_printk("ERROR: Memory allocation failed.\r\n");
379 #if configCHECK_FOR_STACK_OVERFLOW > 0
381 * FreeRTOS stack overflow hook.
383 void vApplicationStackOverflowHook(xTaskHandle xTask, signed portCHAR *pcTaskName)
385 rpp_sci_printk("ERROR: Stack overflow : \"%s\".\r\n", pcTaskName);
391 %<LibSetSourceFileSection(cFile, "Functions", tmpBuf)>