]> rtime.felk.cvut.cz Git - jenkicar/rpp-simulink.git/blobdiff - rpp/rpp/rpp_mrmain.tlc
Change license to MIT
[jenkicar/rpp-simulink.git] / rpp / rpp / rpp_mrmain.tlc
index 36edd2797c4be80ead8ae32af3e47654d26b52ad..8e2fb58d04bd87bce0116c52c05123601ccf0eb3 100644 (file)
@@ -5,10 +5,26 @@
 %%     - Michal Sojka <sojkam1@fel.cvut.cz>
 %%     - Michal Horn <hornmich@fel.cvut.cz>
 %%
-%% This document contains proprietary information belonging to Czech
-%% Technical University in Prague. Passing on and copying of this
-%% document, and communication of its contents is not permitted
-%% without prior written authorization.
+%% Permission is hereby granted, free of charge, to any person
+%% obtaining a copy of this software and associated documentation
+%% files (the "Software"), to deal in the Software without
+%% restriction, including without limitation the rights to use,
+%% copy, modify, merge, publish, distribute, sublicense, and/or sell
+%% copies of the Software, and to permit persons to whom the
+%% Software is furnished to do so, subject to the following
+%% conditions:
+
+%% The above copyright notice and this permission notice shall be
+%% included in all copies or substantial portions of the Software.
+
+%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+%% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+%% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+%% NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+%% HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+%% WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+%% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+%% OTHER DEALINGS IN THE SOFTWARE.
 %%
 %% File : rpp_mrmain.tlc
 %% Abstract:
         %assign CompiledModel.GenerateSampleERTMain = TLC_FALSE
     %endif
 
-
     %assign cFile = LibCreateSourceFile("Source", "Custom", "ert_main")
 
+    %if LibIsSingleTasking()
+      %assign taskCount = 1
+      %assign firstTask = 0
+    %else
+      %assign taskCount = numSampleTimes - tid01Eq
+      %assign firstTask = tid01Eq
+    %endif
+
 
     %%%%%%%%
     %openfile tmpBuf
@@ -49,6 +72,7 @@
       /* External mode header file */
       #include "ext_work.h"
       #include <drv/sci.h>
+      #include <drv/emac.h>
     %endif
 
     %closefile tmpBuf
 
     /* Definitions */
     #define STEP_SIZE_MILLIS (%<CompiledModel.FundamentalStepSize>*1000.0)
-    #define NUM_SAMPLE_TIMES    %<numSampleTimes>
+    #define NUM_TASKS    %<taskCount>
     #define CONTROL_PRIORITY (configMAX_PRIORITIES - 1)
 
     %% Worker task priority assignment - rate transition block
     %% requires rate monotonic priority assignment
-    %foreach i = numSampleTimes - tid01Eq
-        #define WORKING%<i + tid01Eq>_PRIORITY    (configMAX_PRIORITIES - %<2 + i>)
+    %foreach i = taskCount
+        #define WORKING%<i + firstTask>_PRIORITY    (configMAX_PRIORITIES - %<2 + i>)
     %endforeach
 
     %if extMode == 1
       #define EXTMODE_PRIORITY IDLE_PRIORITY /* Extmode not used */
     %endif
 
-    %foreach i = numSampleTimes - tid01Eq
-        %assign j = i + tid01Eq
+    %foreach i = taskCount
+        %assign j = i + firstTask
         #if (WORKING%<j>_PRIORITY <= EXTMODE_PRIORITY) || (WORKING%<j>_PRIORITY >= CONTROL_PRIORITY)
         #error Too many tasks. Increase configMAX_PRIORITIES.
         #endif
       static xSemaphoreHandle ext_mode_ready = NULL;
     %endif
     static uint32_t steps_control = 0;
-    static uint32_t steps_working[NUM_SAMPLE_TIMES];
+    static uint32_t steps_working[NUM_TASKS];
     boolean_t overrun_flag = FALSE;
-    static sub_rate_t sub_rate[NUM_SAMPLE_TIMES];
+    static sub_rate_t sub_rate[NUM_TASKS];
     static boolean_t simulationFinished = 0;
 
     %closefile tmpBuf
      */
     void control_task(void* p)
     {
-        uint32_t i;
 
-        %% Variables used by LibCallSetEventForThisBaseStep (static => zero initialized)
-        static uint32_t taskCounter[NUM_SAMPLE_TIMES];
-        static boolean_t eventFlags[NUM_SAMPLE_TIMES];
-        static boolean_t OverrunFlags[NUM_SAMPLE_TIMES];
+        %if !LibIsSingleTasking()
+          uint32_t i = 0;
 
-        (void)OverrunFlags; /* Not used in multitasking mode, but required by TLC macro */
+          %% Variables used by LibCallSetEventForThisBaseStep (static => zero initialized)
+          static uint32_t taskCounter[NUM_TASKS];
+          static boolean_t eventFlags[NUM_TASKS];
+          static boolean_t OverrunFlags[NUM_TASKS];
+
+          (void)OverrunFlags; /* Not used in multitasking mode, but required by TLC macro */
+        %endif
 
         steps_control = 0;
       %if extMode == 1
         xSemaphoreTake(ext_mode_ready, portMAX_DELAY);
       %endif
 
+      /* Initialize model */
+      %<LibCallModelInitialize()>\
+
+      /* Start periodic execution */
       static const portTickType freq_ticks = STEP_SIZE_MILLIS / portTICK_RATE_MS;
       portTickType last_wake_time = xTaskGetTickCount();
 
             /* Wait until next step */
             vTaskDelayUntil(&last_wake_time, freq_ticks);
 
-            /* Check subrate overrun, set rates that need to run this time step*/
-            %<LibCallSetEventForThisBaseStep("eventFlags")>\
+            %if !LibIsSingleTasking()
+              /* Mark rates that need to run this time step */
+              %<LibCallSetEventForThisBaseStep("eventFlags")>\
+            %endif
 
-            /* Trigger sub-rate threads */
-            %foreach j = numSampleTimes - tid01Eq
-                %assign i = j + tid01Eq
+            /* Trigger working threads */
+            %foreach j = taskCount
+                %assign i = j + firstTask
                 %assign s = CompiledModel.SampleTime[i].PeriodAndOffset[0]
                 %assign o = CompiledModel.SampleTime[i].PeriodAndOffset[1]
                 /* Sampling rate %<i>, sample time = %<s>, offset = %<o> */
             %endforeach
 
-              for (i = %<tid01Eq>; i < NUM_SAMPLE_TIMES; i++) {
-                if (i == 0 || eventFlags[i]) {
-                    eventFlags[i] = FALSE;
-                    uint32_t step_sem_value = uxQueueMessagesWaiting(sub_rate[i].sem);
+            %if LibIsSingleTasking()
+              %assign i = "0"
+            %else
+              %assign i = "i"
+              for (%<i> = %<firstTask>; %<i> < NUM_TASKS; %<i>++) {
+                  if (%<i> == 0 || eventFlags[%<i>]) {
+                    eventFlags[%<i>] = FALSE;
+                %endif
+                    uint32_t step_sem_value = uxQueueMessagesWaiting(sub_rate[%<i>].sem);
                     if (step_sem_value) {
                         %% Commented out so that overrun does stop the whole execution
                         %% rtmSetErrorStatus(%<modelName>_M, "Overrun");
                         overrun_flag = TRUE;
-                        break;
-                    }
-                    if (xSemaphoreGive(sub_rate[i].sem) == pdFALSE) {
-                        rpp_sci_printk("ERROR: Task %d semaphore 1 give.\n", i);
-                        while (1) ;
-                    }
-                    if (xSemaphoreGive(sub_rate[i].sem) == pdFALSE) {
-                        rpp_sci_printk("ERROR: Task %d semaphore 2 give.\n", i);
-                        while (1) ;
+                        continue;
                     }
+                    xSemaphoreGive(sub_rate[%<i>].sem);
+                    xSemaphoreGive(sub_rate[%<i>].sem);
+                %if !LibIsSingleTasking()
                 }
               }
+            %endif
 
             steps_control++;
 
         simulationFinished = 1;
 
         /* Final step */
-        for (i = %<tid01Eq>; i < NUM_SAMPLE_TIMES; i++) {
-            xSemaphoreGive(sub_rate[i].sem);
-            xSemaphoreGive(sub_rate[i].sem);
+        %if !LibIsSingleTasking()
+        for (%<i> = %<firstTask>; %<i> < NUM_TASKS; %<i>++) {
+        %endif
+            xSemaphoreGive(sub_rate[%<i>].sem);
+            xSemaphoreGive(sub_rate[%<i>].sem);
+        %if !LibIsSingleTasking()
         }
+        %endif
 
         /* In case of shutdown, delete this task */
         vTaskDelete(NULL);
     }
 
-    %foreach j = numSampleTimes - tid01Eq
-        %assign i = j + tid01Eq
+    %foreach j = taskCount
+        %assign i = j + firstTask
         /**
          * Model step logic execution task for sample time %<CompiledModel.SampleTime[i].ClockTickStepSize>.
          */
         void ext_mode_comm_task(void* p)
         {
             drv_sci_set_crlf_conv_en(FALSE); /* Disable CR->CRLF conversion */
+            rtParseArgsForExtMode(0, NULL);
 
             %<SLibGenERTExtModeInit()>
             xSemaphoreGive(ext_mode_ready);
         %endif
         rpp_sci_init();
 
+        %if extMode == 1
+            rpp_eth_init();
+        %endif
+        
         // Speed up the SCI
         rpp_sci_setup(115200);
 
-        /* Initialize model */
-        %<LibCallModelInitialize()>\
-
         %if rppPrintMeta
             %assign model_info = SPRINTF("'%s' - %s (TLC %s)\\r\\n", LibGetMdlPubHdrBaseName(), TLC_TIME, TLC_VERSION)
             rpp_sci_printk("%<model_info>");
         %endif
-
         %if extMode == 1
           vSemaphoreCreateBinary(ext_mode_ready);
           xSemaphoreTake(ext_mode_ready, 0);
         %endif
 
-        %foreach j = numSampleTimes - tid01Eq
-            %assign i = j + tid01Eq
+        %foreach j = taskCount
+            %assign i = j + firstTask
             %assign s = CompiledModel.SampleTime[i].PeriodAndOffset[0]
             %assign o = CompiledModel.SampleTime[i].PeriodAndOffset[1]
 
             }
 
             /* Starting loop %<i> thread for sample time = %<s>s, offset = %<o>s. */
-            if (xTaskCreate(working_task%<i>,
-                            "working_task%<i>",
-                            %<rppModelTaskStack>,
-                            NULL,
-                            WORKING%<i>_PRIORITY,
+            if (xTaskCreate(working_task%<i>, "working_task%<i>",
+                            %<rppModelTaskStack>, NULL, WORKING%<i>_PRIORITY,
                             &sub_rate[%<i>].thread ) != pdPASS) {
                 rpp_sci_printk("ERROR: Cannot spawn working task %<i>.\r\n");
                 while (1);
 
         /* Create tasks to step model and model task */
 
-        if (xTaskCreate(control_task,
-                        "control_task",
-                        %<rppModelTaskStack>,
-                        NULL,
-                        CONTROL_PRIORITY,
+        if (xTaskCreate(control_task, "control_task",
+                        %<rppModelTaskStack>, NULL, CONTROL_PRIORITY,
                         NULL) != pdPASS) {
             rpp_sci_printk("ERROR: Cannot spawn control task.\r\n");
             while (1);
 
         %if extMode == 1
           /* External mode */
-          rtParseArgsForExtMode(0, NULL);
 
           if (xTaskCreate(ext_mode_comm_task, "ext_mode_comm_task", 1024, NULL, EXTMODE_PRIORITY, NULL) != pdPASS) {
             rpp_sci_printk("ERROR: Cannot spawn model task.\r\n");