]> rtime.felk.cvut.cz Git - jenkicar/rpp-simulink.git/commitdiff
Fix unified single/multi-tasking main template
authorMichal Sojka <sojkam1@fel.cvut.cz>
Sat, 29 Aug 2015 20:01:22 +0000 (22:01 +0200)
committerMichal Sojka <sojkam1@fel.cvut.cz>
Thu, 3 Sep 2015 10:57:50 +0000 (12:57 +0200)
- create only one task in single tasking mode
- replace break with continue in overrun handling block
- initialize model from control thread (i.e. after starting scheduler).
  Some parts of the library may require this.

rpp/rpp/rpp_mrmain.tlc

index 36edd2797c4be80ead8ae32af3e47654d26b52ad..38281e2a72c813625836bd1c3587d6158b90e659 100644 (file)
         %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
 
     /* 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
@@ -77,8 +84,8 @@
       #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>.
          */
         // 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>");
           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);