]> rtime.felk.cvut.cz Git - ert_linux.git/blob - ert_linux/ert_linux_multitasking_main.tlc
Intentation fixes
[ert_linux.git] / ert_linux / ert_linux_multitasking_main.tlc
1 %%\r
2 %% linux_ert_target_multitasking_main.tlc\r
3 %%\r
4 %% description:\r
5 %%  This TLC script generates ert_main for multi-rate / multi-tasking\r
6 %%  case.\r
7 %%\r
8 %% date: 3nd Feb 2009\r
9 %%\r
10 %% author: Lukas Hamacek\r
11 %% e-mail: hamacl1@fel.cvut.cz\r
12 %% Department of Control Engineering\r
13 %% Faculty of Electrical Engineering\r
14 %% Czech Technical University in Prague\r
15 %%\r
16 %% modifications:\r
17 %%  2009/2/3 - Lukas Hamacek\r
18 %%      creation of the file\r
19 %%\r
20 \r
21 %% GENERATEDECLARATIONS\r
22 %%  This function generates main function declarations.\r
23 %%\r
24 %function generateDeclarations() Output\r
25 \r
26   /* Multirate - Multitasking case main file */\r
27 \r
28   #include <stdio.h>                     /* This ert_main.c example uses printf/fflush */\r
29   #include <pthread.h>                   /* Thread library header file */\r
30   #include <sched.h>                     /* OS scheduler header file */\r
31   #include <semaphore.h>                 /* Semaphores library header file */\r
32   #include "pthread_periodic.h"          /* Periodic threads library header file*/\r
33   #include "%<modelName>.h"              /* Model's header file */\r
34   #include "rtwtypes.h"                  /* MathWorks types */\r
35   %if extMode == 1\r
36     #include "ext_work.h"                  /* External mode header file */\r
37   %endif\r
38 \r
39   /**\r
40    * Maximal priority used by main loop thread.\r
41    */\r
42   #define MAX_PRIO sched_get_priority_max(SCHED_FIFO) - 4\r
43 \r
44   /**\r
45    * Thread handler of the main loop thread.\r
46    * Fundamental sample time = %<fundamentalStepSize>s\r
47    */\r
48   pthread_t main_loop_thread;\r
49 \r
50   %foreach i = numSampleTimes\r
51     %assign s = sampleTime%<i>\r
52     %assign o = offset%<i>\r
53 \r
54     /**\r
55      * Thread handler of the sample time %<i> loop thread.\r
56      * Sample time = %<s>s, offset = %<o>s\r
57      */\r
58     pthread_t rt_OneStep%<i>_thread;\r
59 \r
60     /**\r
61      * Semaphore used to suspend rt_OneStep%<i> loop until next simulation step.\r
62      */\r
63     sem_t step%<i>_semaphore;\r
64   %endforeach\r
65 \r
66   /**\r
67    * Flag if the simulation has been terminated.\r
68    */\r
69   int simulationFinished = 0;\r
70 \r
71 %endfunction\r
72 \r
73 \r
74 %% GENERATERTONESTEP\r
75 %%  This function generates code of rt_OneStep function.\r
76 %%\r
77 %function generateRtOneStep() Output\r
78 \r
79   %foreach i = numSampleTimes\r
80     %assign s = sampleTime%<i>\r
81     %assign o = offset%<i>\r
82 \r
83     /**\r
84      * This is thread function of the simulation one step cycle.\r
85      * Sample time = %<s>s, offset = %<o>s\r
86      */\r
87     void * rt_OneStep%<i>()\r
88     {\r
89         /* Setting up the pririty of the sample time loop */\r
90         struct sched_param scheduling_parameters;\r
91         scheduling_parameters.sched_priority = MAX_PRIO - 1 - %<i>;\r
92         if (0 != pthread_setschedparam(pthread_self(), SCHED_FIFO, &scheduling_parameters))\r
93         {\r
94             %%log_message("[ERROR] Failed to set sample time thread priority, Login as root and start again.", VERBOSEL);\r
95             printf("[ERROR] Failed to set the loop %<i> thread priority. Login as root and start again.\n");\r
96         }\r
97 \r
98         while(!simulationFinished) {\r
99             sem_wait(&step%<i>_semaphore);    /* sem_val = 1 */\r
100             %<modelName>_step%<i>();\r
101             sem_wait(&step%<i>_semaphore);    /* sem_val = 0 */\r
102         }\r
103     }\r
104   %endforeach\r
105 %endfunction\r
106 \r
107 \r
108 %% GENERATEMAIN\r
109 %%  This function generates code of the main function function.\r
110 %%\r
111 %function generateMain() Output\r
112 \r
113   /**\r
114    * This is the thread function of the main loop.\r
115    * Fundamental sample time = %<fundamentalStepSize>s\r
116    */\r
117   void * main_loop()\r
118   {\r
119     struct timespec start;\r
120     struct timespec period;\r
121     boolean_T eventFlags[%<numSampleTimes>];             /* Model has %<numSampleTimes> rates */\r
122     int_T i;\r
123 \r
124     /* Setting up the pririty of the main loop */\r
125        struct sched_param scheduling_parameters;\r
126        scheduling_parameters.sched_priority = sched_get_priority_max(SCHED_FIFO) - 4;\r
127     if (0 != pthread_setschedparam(pthread_self(), SCHED_FIFO, &scheduling_parameters))\r
128     {\r
129       %%log_message("[ERROR] Failed to set main thread priority, Login as root and start again", VERBOSEL);\r
130       printf("[ERROR] Failed to set main thread priority. Login as root and start again.\n");\r
131     }\r
132 \r
133     period.tv_sec = (unsigned long long)%<fundamentalStepSize>;\r
134     period.tv_nsec = (unsigned long long)((%<fundamentalStepSize>-period.tv_sec)*1000000000);\r
135 \r
136     clock_gettime(CLOCK_REALTIME, &start);\r
137     pthread_make_periodic_np(pthread_self(), &start, &period);\r
138 \r
139     int step_sem_value;\r
140 \r
141     /* Main loop, running until all the threads are terminated */\r
142     while(rtmGetErrorStatus(%<modelName>_M) == NULL && !rtmGetStopRequested(%<modelName>_M)) {\r
143       pthread_wait_np();\r
144       %<modelName>_SetEventsForThisBaseStep(eventFlags);\r
145 \r
146       /* Base sampling rate */\r
147       sem_getvalue(&step0_semaphore, &step_sem_value);\r
148       if(step_sem_value) {\r
149         rtmSetErrorStatus(%<modelName>_M, "Overrun");\r
150         printf("Loop 0 overrun, sample time=%<sampleTime0>s, offset=%<offset0>s is too fast\n");\r
151         break;\r
152       }\r
153       sem_post(&step0_semaphore);\r
154       sem_post(&step0_semaphore);\r
155 \r
156       %foreach i = numSampleTimes-1\r
157         %assign s = sampleTime%<i+1>\r
158         %assign o = offset%<i+1>\r
159         /* Sampling rate %<i+1>, sample time = %<s>, offset = %<o> */\r
160         if (eventFlags[%<i+1>]) {\r
161           sem_getvalue(&step%<i+1>_semaphore, &step_sem_value);\r
162           if(step_sem_value) {\r
163             rtmSetErrorStatus(%<modelName>_M, "Overrun");\r
164             printf("Loop %<i+1> overrun, sample time=%<s>s, offset=%<o>s is too fast\n");\r
165             break;\r
166           }\r
167           sem_post(&step%<i+1>_semaphore);\r
168           sem_post(&step%<i+1>_semaphore);\r
169         }\r
170       %endforeach\r
171 \r
172       %if extMode == 1\r
173         rtExtModeCheckEndTrigger();\r
174       %endif\r
175     }\r
176 \r
177     simulationFinished = 1;\r
178     /* Final step */\r
179     %foreach i = numSampleTimes\r
180       sem_post(&step%<i>_semaphore);\r
181       sem_post(&step%<i>_semaphore);\r
182     %endforeach\r
183   }\r
184 \r
185   /**\r
186    * This is the main function of the model.\r
187    * Multirate - Multitasking case main file\r
188    */\r
189   int_T main(int_T argc, const char_T *argv[])\r
190   {\r
191     %if extMode == 1\r
192       /* External mode */\r
193       rtERTExtModeParseArgs(argc, argv);\r
194     %else\r
195       (void)(argc);\r
196       (void *)(argv);\r
197     %endif\r
198 \r
199     /* Initialize periodic thread library */\r
200     pthread_periodic_init_np();\r
201 \r
202     /* Initialize model */\r
203     %<modelName>_initialize(1);\r
204     simulationFinished = 0;\r
205 \r
206     %foreach i = numSampleTimes\r
207       %assign s = sampleTime%<i>\r
208       %assign o = offset%<i>\r
209 \r
210       /* Initializing the step semaphore of the loop %<i>*/\r
211       if(sem_init(&step%<i>_semaphore, 0, 0) < 0) {\r
212         printf("[ERROR] Step semaphore %<i> initialization failed!\n");\r
213         %%log_message("[ERROR] Step semaphore %<i> initialization failed", VERBOSEL);\r
214         return(1);\r
215       }\r
216 \r
217       /* Starting loop %<i> thread for sample time = %<s>s, offset = %<o>s. */\r
218       pthread_create(&rt_OneStep%<i>_thread, NULL, rt_OneStep%<i>, NULL);\r
219     %endforeach\r
220 \r
221     /* Starting the main loop */\r
222     pthread_create(&main_loop_thread, NULL, main_loop, NULL);\r
223     pthread_join(main_loop_thread, NULL);\r
224     %foreach i = numSampleTimes\r
225       pthread_join(rt_OneStep%<i>_thread, NULL);\r
226     %endforeach\r
227 \r
228     /* Terminate model */\r
229     %<modelName>_terminate();\r
230 \r
231     const char_T *errStatus = rtmGetErrorStatus(%<modelName>_M);\r
232     int_T i;\r
233     if(errStatus != NULL && strcmp(errStatus, "Simulation finished")) {\r
234       %%printf("%s\n", rtmGetErrorStatus(%<modelName>_M));\r
235       if(!strcmp(errStatus, "Overrun")) {\r
236         printf("ISR overrun - sampling rate too fast\n");\r
237       }\r
238       return(1);\r
239     }\r
240     return 0;\r
241   }\r
242 %endfunction\r
243 \r
244 %% [EOF] linux_ert_target_miltitasking_main.tlc\r