1 %% Copyright (C) 2013-2014 Czech Technical University in Prague
4 %% - Carlos Jenkins <carlos@jenkins.co.cr>
5 %% - Michal Sojka <sojkam1@fel.cvut.cz>
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.
12 %% File : rpp_srmain.tlc
14 %% Custom TLC file to generate an RPP "main" file.
16 %% This file generates the "main" file for the RPP target on top of the RPP
17 %% library and the FreeRTOS operating system.
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.
23 %% Example in <matlabroot>/rtw/c/tlc/mw/bareboard_srmain.tlc
28 %function FcnSingleTaskingMain() void
30 %if GenerateSampleERTMain
31 %assign CompiledModel.GenerateSampleERTMain = TLC_FALSE
35 %assign cFile = LibCreateSourceFile("Source", "Custom", "ert_main")
42 #include "%<LibGetMdlPubHdrBaseName()>.h"
44 /* RPP runtime includes */
45 #include "rpp_simulink_runtime.h"
48 /* External mode header file */
54 %<LibSetSourceFileSection(cFile, "Includes", tmpBuf)>
62 #define STEP_SIZE_MILLIS %<CompiledModel.FundamentalStepSize>*1000.0
63 #define CONTROL_PRIORITY 3
64 #define WORKING_PRIORITY 2
65 #define EXTMODE_PRIORITY 1
68 %<LibSetSourceFileSection(cFile, "Defines", tmpBuf)>
75 static boolean_t working = FALSE;
76 static xSemaphoreHandle step_signal = NULL;
77 static xSemaphoreHandle initialized_signal = NULL;
79 static xSemaphoreHandle ext_mode_ready = NULL;
81 static uint32_t steps_control = 0;
82 static uint32_t steps_working = 0;
83 boolean_t overrun_flag = FALSE;
86 %<LibSetSourceFileSection(cFile, "Declarations", tmpBuf)>
94 * Model step control and overrun detection task.
96 void control_task(void* p)
99 xSemaphoreTake(initialized_signal, portMAX_DELAY);
101 xSemaphoreTake(ext_mode_ready, portMAX_DELAY);
104 static const portTickType freq_ticks = STEP_SIZE_MILLIS / portTICK_RATE_MS;
105 portTickType last_wake_time = xTaskGetTickCount();
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.
113 %% See <MATLAB_ROOT>/rtw/c/tlc/mw/rtmspecmacs.tlc at line 198.
115 %if !GenerateSampleERTMain
116 while (rtmGetErrorStatus(%<modelName>_M) == NULL) {
118 while (rtmGetErrorStatus(%<modelName>_M) == NULL && !rtmGetStopRequested(%<modelName>_M)) {
120 /* Wait until next step */
121 vTaskDelayUntil(&last_wake_time, freq_ticks);
124 /* Overrun detected */
127 overrun_flag = FALSE;
128 /* Release semaphore */
129 xSemaphoreGive(step_signal);
134 rtExtModeCheckEndTrigger();
139 /* In case of shutdown, delete this task */
144 * Model step logic execution task.
146 void working_task(void* p)
148 /* Initialize model */
149 %<LibCallModelInitialize()>\
150 /* Step the model for any subrate */
151 xSemaphoreGive(initialized_signal);
152 %foreach idx = LibGetNumSyncPeriodicTasks()
153 %assign tid = idx + tid01Eq
154 %assign sampleTime = LibGetSampleTimePeriodAndOffset(tid,0)
155 %assign steps = FEVAL("round", sampleTime / CompiledModel.FundamentalStepSize)
156 #define STEPS_FOR_TID%<tid> ((int)%<steps>)
162 if (xSemaphoreTake(step_signal, portMAX_DELAY)) {
164 %if LibNumSynchronousSampleTimes() > 1
166 for (i = %<tid01Eq>; i < %<LibNumSynchronousSampleTimes()>; i++) {
168 %foreach idx = LibGetNumSyncPeriodicTasks()
169 %assign tid = idx + tid01Eq
171 %assign sampleTime = LibGetSampleTimePeriodAndOffset(tid,0)
172 if ((steps_working % STEPS_FOR_TID%<tid>) == 0) {
173 %<LibCallModelStep(tid)>\
182 %<LibCallModelStep(0)>\
189 %% /* In case of shutdown, delete this task */
190 %% vTaskDelete(NULL);
194 void ext_mode_comm_task(void* p)
196 drv_sci_set_crlf_conv_en(FALSE); /* Disable CR->CRLF conversion */
198 %<SLibGenERTExtModeInit()>
199 xSemaphoreGive(ext_mode_ready);
201 while (rtmGetErrorStatus(%<modelName>_M) == NULL && !rtmGetStopRequested(%<modelName>_M)) {
202 rtExtModeOneStep(rtmGetRTWExtModeInfo(%<modelName>_M), %<numSampleTimes>, (boolean_T *)&rtmGetStopRequested(%<modelName>_M));
204 rtExtModeShutdown(%<numSampleTimes>);
205 /* In case of shutdown, delete this task */
211 * Hardware initialization, task spawning and OS scheduler start.
215 /* Initialize RPP board */
216 %if EXISTS(::rpp_ain_present)
219 %if EXISTS(::rpp_din_present) || EXISTS(::rpp_dout_present)
220 rpp_gio_init(RPP_GIO_PORT_ALL);
225 rpp_sci_setup(115200);
228 %assign model_info = SPRINTF("'%s' - %s (TLC %s)\\r\\n", LibGetMdlPubHdrBaseName(), TLC_TIME, TLC_VERSION)
229 rpp_sci_printk("%<model_info>");
232 /* Create and lock semaphore */
233 vSemaphoreCreateBinary(step_signal);
234 xSemaphoreTake(step_signal, 0);
235 vSemaphoreCreateBinary(initialized_signal);
236 xSemaphoreTake(initialized_signal, 0);
238 vSemaphoreCreateBinary(ext_mode_ready);
239 xSemaphoreTake(ext_mode_ready, 0);
242 /* Create tasks to step model and model task */
243 if (xTaskCreate(control_task, "control_task",
244 configMINIMAL_STACK_SIZE, NULL, CONTROL_PRIORITY, NULL) != pdPASS) {
245 rpp_sci_printk("ERROR: Cannot spawn control task.\r\n");
248 if (xTaskCreate(working_task, "working_task",
249 %<rppModelTaskStack>, NULL, WORKING_PRIORITY, NULL) != pdPASS) {
250 rpp_sci_printk("ERROR: Cannot spawn model task.\r\n"
256 rtParseArgsForExtMode(0, NULL);
258 if (xTaskCreate(ext_mode_comm_task, "ext_mode_comm_task", 1024, NULL, EXTMODE_PRIORITY, NULL) != pdPASS) {
259 rpp_sci_printk("ERROR: Cannot spawn model task.\r\n");
264 /* Start FreeRTOS Scheduler */
265 vTaskStartScheduler();
267 /* We should never get here */
268 %<LibCallModelTerminate()>
269 rpp_sci_printk("ERROR: Problem allocating memory for idle task.\r\n");
273 #if configUSE_MALLOC_FAILED_HOOK == 1
275 * FreeRTOS malloc() failed hook.
277 void vApplicationMallocFailedHook(void) {
278 rpp_sci_printk("ERROR: Memory allocation failed.\r\n");
283 #if configCHECK_FOR_STACK_OVERFLOW > 0
285 * FreeRTOS stack overflow hook.
287 void vApplicationStackOverflowHook(xTaskHandle xTask, signed portCHAR *pcTaskName)
289 rpp_sci_printk("ERROR: Stack overflow : \"%s\".\r\n", pcTaskName);
294 %<LibSetSourceFileSection(cFile, "Functions", tmpBuf)>