--- /dev/null
+%%\r
+%% linux_ert_target_multitasking_main.tlc\r
+%%\r
+%% description:\r
+%% This TLC script generates ert_main for multi-rate / multi-tasking\r
+%% case.\r
+%%\r
+%% date: 3nd Feb 2009\r
+%%\r
+%% author: Lukas Hamacek\r
+%% e-mail: hamacl1@fel.cvut.cz\r
+%% Department of Control Engineering\r
+%% Faculty of Electrical Engineering\r
+%% Czech Technical University in Prague\r
+%%\r
+%% modifications:\r
+%% 2009/2/3 - Lukas Hamacek\r
+%% creation of the file\r
+%%\r
+\r
+%% GENERATEDECLARATIONS\r
+%% This function generates main function declarations.\r
+%%\r
+%function generateDeclarations() Output\r
+\r
+/* Multirate - Multitasking case main file */\r
+\r
+#include <stdio.h> /* This ert_main.c example uses printf/fflush */\r
+#include <pthread.h> /* Thread library header file */\r
+#include <sched.h> /* OS scheduler header file */\r
+#include <semaphore.h> /* Semaphores library header file */\r
+#include "pthread_periodic.h" /* Periodic threads library header file*/\r
+#include "%<modelName>.h" /* Model's header file */\r
+#include "rtwtypes.h" /* MathWorks types */\r
+%if extMode == 1\r
+#include "ext_work.h" /* External mode header file */\r
+%endif\r
+\r
+/**\r
+ * Maximal priority used by main loop thread.\r
+ */\r
+#define MAX_PRIO sched_get_priority_max(SCHED_FIFO) - 4\r
+\r
+/**\r
+ * Thread handler of the main loop thread.\r
+ * Fundamental sample time = %<fundamentalStepSize>s\r
+ */\r
+pthread_t main_loop_thread;\r
+\r
+%foreach i = numSampleTimes\r
+ %assign s = sampleTime%<i>\r
+ %assign o = offset%<i>\r
+\r
+ /**\r
+ * Thread handler of the sample time %<i> loop thread.\r
+ * Sample time = %<s>s, offset = %<o>s\r
+ */\r
+ pthread_t rt_OneStep%<i>_thread;\r
+\r
+ /**\r
+ * Semaphore used to suspend rt_OneStep%<i> loop until next simulation step.\r
+ */\r
+ sem_t step%<i>_semaphore;\r
+%endforeach\r
+\r
+/**\r
+ * Flag if the simulation has been terminated.\r
+ */\r
+int simulationFinished = 0;\r
+\r
+%endfunction\r
+\r
+\r
+%% GENERATERTONESTEP\r
+%% This function generates code of rt_OneStep function.\r
+%%\r
+%function generateRtOneStep() Output\r
+\r
+%foreach i = numSampleTimes\r
+ %assign s = sampleTime%<i>\r
+ %assign o = offset%<i>\r
+\r
+ /**\r
+ * This is thread function of the simulation one step cycle.\r
+ * Sample time = %<s>s, offset = %<o>s\r
+ */\r
+ void * rt_OneStep%<i>()\r
+ {\r
+ /* Setting up the pririty of the sample time loop */\r
+ struct sched_param scheduling_parameters;\r
+ scheduling_parameters.sched_priority = MAX_PRIO - 1 - %<i>;\r
+ if (0 != pthread_setschedparam(pthread_self(), SCHED_FIFO, &scheduling_parameters))\r
+ {\r
+ %%log_message("[ERROR] Failed to set sample time thread priority, Login as root and start again.", VERBOSEL);\r
+ printf("[ERROR] Failed to set the loop %<i> thread priority. Login as root and start again.\n");\r
+ }\r
+\r
+ while(!simulationFinished) {\r
+ sem_wait(&step%<i>_semaphore); /* sem_val = 1 */\r
+ %<modelName>_step%<i>();\r
+ sem_wait(&step%<i>_semaphore); /* sem_val = 0 */\r
+ }\r
+ }\r
+%endforeach\r
+%endfunction\r
+\r
+\r
+%% GENERATEMAIN\r
+%% This function generates code of the main function function.\r
+%%\r
+%function generateMain() Output\r
+\r
+/**\r
+ * This is the thread function of the main loop.\r
+ * Fundamental sample time = %<fundamentalStepSize>s\r
+ */\r
+void * main_loop()\r
+{\r
+ struct timespec start;\r
+ struct timespec period;\r
+ boolean_T eventFlags[%<numSampleTimes>]; /* Model has %<numSampleTimes> rates */\r
+ int_T i;\r
+\r
+ /* Setting up the pririty of the main loop */\r
+ struct sched_param scheduling_parameters;\r
+ scheduling_parameters.sched_priority = sched_get_priority_max(SCHED_FIFO) - 4;\r
+ if (0 != pthread_setschedparam(pthread_self(), SCHED_FIFO, &scheduling_parameters))\r
+ {\r
+ %%log_message("[ERROR] Failed to set main thread priority, Login as root and start again", VERBOSEL);\r
+ printf("[ERROR] Failed to set main thread priority. Login as root and start again.\n");\r
+ }\r
+\r
+ period.tv_sec = (unsigned long long)%<fundamentalStepSize>;\r
+ period.tv_nsec = (unsigned long long)((%<fundamentalStepSize>-period.tv_sec)*1000000000);\r
+\r
+ clock_gettime(CLOCK_REALTIME, &start);\r
+ pthread_make_periodic_np(pthread_self(), &start, &period);\r
+\r
+ int step_sem_value;\r
+\r
+ /* Main loop, running until all the threads are terminated */\r
+ while(rtmGetErrorStatus(%<modelName>_M) == NULL && !rtmGetStopRequested(%<modelName>_M)) {\r
+ pthread_wait_np();\r
+ %<modelName>_SetEventsForThisBaseStep(eventFlags);\r
+\r
+ /* Base sampling rate */\r
+ sem_getvalue(&step0_semaphore, &step_sem_value);\r
+ if(step_sem_value) {\r
+ rtmSetErrorStatus(%<modelName>_M, "Overrun");\r
+ printf("Loop 0 overrun, sample time=%<sampleTime0>s, offset=%<offset0>s is too fast\n");\r
+ break;\r
+ }\r
+ sem_post(&step0_semaphore);\r
+ sem_post(&step0_semaphore);\r
+\r
+ %foreach i = numSampleTimes-1\r
+ %assign s = sampleTime%<i+1>\r
+ %assign o = offset%<i+1>\r
+ /* Sampling rate %<i+1>, sample time = %<s>, offset = %<o> */\r
+ if (eventFlags[%<i+1>]) {\r
+ sem_getvalue(&step%<i+1>_semaphore, &step_sem_value);\r
+ if(step_sem_value) {\r
+ rtmSetErrorStatus(%<modelName>_M, "Overrun");\r
+ printf("Loop %<i+1> overrun, sample time=%<s>s, offset=%<o>s is too fast\n");\r
+ break;\r
+ }\r
+ sem_post(&step%<i+1>_semaphore);\r
+ sem_post(&step%<i+1>_semaphore);\r
+ }\r
+ %endforeach\r
+\r
+ %if extMode == 1\r
+ rtExtModeCheckEndTrigger();\r
+ %endif\r
+ }\r
+\r
+ simulationFinished = 1;\r
+ /* Final step */\r
+ %foreach i = numSampleTimes\r
+ sem_post(&step%<i>_semaphore);\r
+ sem_post(&step%<i>_semaphore);\r
+ %endforeach\r
+}\r
+\r
+/**\r
+ * This is the main function of the model.\r
+ * Multirate - Multitasking case main file\r
+ */\r
+int_T main(int_T argc, const char_T *argv[])\r
+{\r
+%if extMode == 1\r
+ /* External mode */\r
+ rtERTExtModeParseArgs(argc, argv);\r
+%else\r
+ (void)(argc);\r
+ (void *)(argv);\r
+%endif\r
+\r
+ /* Initialize periodic thread library */\r
+ pthread_periodic_init_np();\r
+\r
+ /* Initialize model */\r
+ %<modelName>_initialize(1);\r
+ simulationFinished = 0;\r
+\r
+%foreach i = numSampleTimes\r
+ %assign s = sampleTime%<i>\r
+ %assign o = offset%<i>\r
+\r
+ /* Initializing the step semaphore of the loop %<i>*/\r
+ if(sem_init(&step%<i>_semaphore, 0, 0) < 0) {\r
+ printf("[ERROR] Step semaphore %<i> initialization failed!\n");\r
+ %%log_message("[ERROR] Step semaphore %<i> initialization failed", VERBOSEL);\r
+ return(1);\r
+ }\r
+\r
+ /* Starting loop %<i> thread for sample time = %<s>s, offset = %<o>s. */\r
+ pthread_create(&rt_OneStep%<i>_thread, NULL, rt_OneStep%<i>, NULL);\r
+%endforeach\r
+\r
+ /* Starting the main loop */\r
+ pthread_create(&main_loop_thread, NULL, main_loop, NULL);\r
+ pthread_join(main_loop_thread, NULL);\r
+%foreach i = numSampleTimes\r
+ pthread_join(rt_OneStep%<i>_thread, NULL);\r
+%endforeach\r
+\r
+ /* Terminate model */\r
+ %<modelName>_terminate();\r
+\r
+ const char_T *errStatus = rtmGetErrorStatus(%<modelName>_M);\r
+ int_T i;\r
+ if(errStatus != NULL && strcmp(errStatus, "Simulation finished")) {\r
+ %%printf("%s\n", rtmGetErrorStatus(%<modelName>_M));\r
+ if(!strcmp(errStatus, "Overrun")) {\r
+ printf("ISR overrun - sampling rate too fast\n");\r
+ }\r
+ return(1);\r
+ }\r
+ return 0;\r
+}\r
+%endfunction\r
+\r
+%% [EOF] linux_ert_target_miltitasking_main.tlc\r