2 %% linux_ert_target_multitasking_main.tlc
\r
5 %% This TLC script generates ert_main for multi-rate / multi-tasking
\r
8 %% date: 3nd Feb 2009
\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
17 %% 2009/2/3 - Lukas Hamacek
\r
18 %% creation of the file
\r
21 %% GENERATEDECLARATIONS
\r
22 %% This function generates main function declarations.
\r
24 %function generateDeclarations() Output
\r
26 /* Multirate - Multitasking case main file */
\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
36 #include "ext_work.h" /* External mode header file */
\r
40 * Maximal priority used by main loop thread.
\r
42 #define MAX_PRIO sched_get_priority_max(SCHED_FIFO) - 4
\r
45 * Thread handler of the main loop thread.
\r
46 * Fundamental sample time = %<fundamentalStepSize>s
\r
48 pthread_t main_loop_thread;
\r
50 %foreach i = numSampleTimes
\r
51 %assign s = sampleTime%<i>
\r
52 %assign o = offset%<i>
\r
55 * Thread handler of the sample time %<i> loop thread.
\r
56 * Sample time = %<s>s, offset = %<o>s
\r
58 pthread_t rt_OneStep%<i>_thread;
\r
61 * Semaphore used to suspend rt_OneStep%<i> loop until next simulation step.
\r
63 sem_t step%<i>_semaphore;
\r
67 * Flag if the simulation has been terminated.
\r
69 int simulationFinished = 0;
\r
74 %% GENERATERTONESTEP
\r
75 %% This function generates code of rt_OneStep function.
\r
77 %function generateRtOneStep() Output
\r
79 %foreach i = numSampleTimes
\r
80 %assign s = sampleTime%<i>
\r
81 %assign o = offset%<i>
\r
84 * This is thread function of the simulation one step cycle.
\r
85 * Sample time = %<s>s, offset = %<o>s
\r
87 void * rt_OneStep%<i>()
\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
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
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
109 %% This function generates code of the main function function.
\r
111 %function generateMain() Output
\r
114 * This is the thread function of the main loop.
\r
115 * Fundamental sample time = %<fundamentalStepSize>s
\r
119 struct timespec start;
\r
120 struct timespec period;
\r
121 boolean_T eventFlags[%<numSampleTimes>]; /* Model has %<numSampleTimes> rates */
\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
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
133 period.tv_sec = (unsigned long long)%<fundamentalStepSize>;
\r
134 period.tv_nsec = (unsigned long long)((%<fundamentalStepSize>-period.tv_sec)*1000000000);
\r
136 clock_gettime(CLOCK_REALTIME, &start);
\r
137 pthread_make_periodic_np(pthread_self(), &start, &period);
\r
139 int step_sem_value;
\r
141 /* Main loop, running until all the threads are terminated */
\r
142 while(rtmGetErrorStatus(%<modelName>_M) == NULL && !rtmGetStopRequested(%<modelName>_M)) {
\r
144 %<modelName>_SetEventsForThisBaseStep(eventFlags);
\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
153 sem_post(&step0_semaphore);
\r
154 sem_post(&step0_semaphore);
\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
167 sem_post(&step%<i+1>_semaphore);
\r
168 sem_post(&step%<i+1>_semaphore);
\r
173 rtExtModeCheckEndTrigger();
\r
177 simulationFinished = 1;
\r
179 %foreach i = numSampleTimes
\r
180 sem_post(&step%<i>_semaphore);
\r
181 sem_post(&step%<i>_semaphore);
\r
186 * This is the main function of the model.
\r
187 * Multirate - Multitasking case main file
\r
189 int_T main(int_T argc, const char_T *argv[])
\r
192 /* External mode */
\r
193 rtERTExtModeParseArgs(argc, argv);
\r
199 /* Initialize periodic thread library */
\r
200 pthread_periodic_init_np();
\r
202 /* Initialize model */
\r
203 %<modelName>_initialize(1);
\r
204 simulationFinished = 0;
\r
206 %foreach i = numSampleTimes
\r
207 %assign s = sampleTime%<i>
\r
208 %assign o = offset%<i>
\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
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
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
228 /* Terminate model */
\r
229 %<modelName>_terminate();
\r
231 const char_T *errStatus = rtmGetErrorStatus(%<modelName>_M);
\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
244 %% [EOF] linux_ert_target_miltitasking_main.tlc
\r