%%\r
-%% linux_ert_target_multitasking_main.tlc\r
%%\r
%% description:\r
-%% This TLC script generates ert_main for multi-rate / multi-tasking\r
+%% This TLC script generates ert_main.c\r
%% case.\r
%%\r
-%% date: 3nd Feb 2009\r
+%% authors: Michal Sojka <sojkam1@fel.cvut.cz>\r
+%% Lukas Hamacek <hamacl1@fel.cvut.cz>\r
%%\r
-%% author: Lukas Hamacek, Michal Sojka\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
%function generateDeclarations() Output\r
\r
/* Multirate - Multitasking case main file */\r
- #define _POSIX_C_SOURCE 199309L /* For clock_gettime() */\r
+ #define _BSD_SOURCE /* For usleep() */\r
+ #define _POSIX_C_SOURCE 200112L /* For clock_gettime() & clock_nanosleep() */\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 <time.h>\r
#include <stdlib.h>\r
+ #include <unistd.h>\r
#include "%<modelName>.h" /* Model's header file */\r
#include "rtwtypes.h" /* MathWorks types */\r
%if extMode == 1\r
\r
%endfunction\r
\r
+%function printfunc() Output\r
+ /% printf("%s\n", __func__); %/\r
+%endfunction\r
+\r
%function generateRtOneStep() Output\r
%foreach j = numSampleTimes - 1\r
%assign i = j + 1\r
{\r
while(!simulationFinished) {\r
sem_wait(&sub_rate[%<i>].sem); /* sem_val = 1 */\r
- printf("%s\n", __func__);\r
+ %<printfunc()>\r
%<modelName>_step%<i>();\r
- %if extMode == 1\r
- rtExtModeUpload(%<i>, %<RTMGetTaskTimeForTID(i)>);\r
- %endif\r
sem_wait(&sub_rate[%<i>].sem); /* sem_val = 0 */\r
}\r
}\r
%%\r
%function generateMain() Output\r
/**\r
- * This is the thread function of the main loop.\r
+ * This is the thread function of the base rate loop.\r
* Fundamental sample time = %<fundamentalStepSize>s\r
*/\r
void * base_rate()\r
\r
/* Main loop, running until all the threads are terminated */\r
while(rtmGetErrorStatus(%<modelName>_M) == NULL && !rtmGetStopRequested(%<modelName>_M)) {\r
- printf("%s\n", __func__);\r
+ %<printfunc()>\r
/* Check subrate overrun, set rates that need to run this time step*/\r
%<LibCallSetEventForThisBaseStep("eventFlags")>\\r
\r
+ /* Trigger sub-rate threads */\r
%foreach i = numSampleTimes\r
%if i == 0 || i == 1 && tid01Eq\r
%continue\r
}\r
%endforeach\r
\r
- %if extMode == 1\r
- /* external mode */\r
- rtExtModeUpload(0, %<RTMGetTaskTimeForTID(0)>);\r
- %if tid01Eq\r
- rtExtModeUpload(1, %<RTMGetTaskTimeForTID(1)>);\r
- %endif\r
+ /* Execute base rate step */\r
+ %if solverMode == "SingleTasking"\r
+ %<modelName>_step();\r
+ %else\r
+ %<modelName>_step0();\r
+ %endif\r
\r
+ %if extMode == 1\r
rtExtModeCheckEndTrigger();\r
- rtExtModePauseIfNeeded(rtmGetRTWExtModeInfo(RT_MDL),\r
- NUMST,\r
- (boolean_T *)&rtmGetStopRequested(RT_MDL));\r
- rtExtModeOneStep(rtmGetRTWExtModeInfo(RT_MDL),\r
- NUMST,\r
- (boolean_T *)&rtmGetStopRequested(RT_MDL));\r
%endif\r
\r
- next.tv_sec += period.tv_sec;\r
- next.tv_nsec += period.tv_nsec;\r
- if (next.tv_nsec >= 1000000000) {\r
- next.tv_sec++;\r
- next.tv_nsec -= 1000000000;\r
- }\r
- clock_gettime(CLOCK_MONOTONIC, &now);\r
- if (now.tv_sec > next.tv_sec ||\r
- (now.tv_sec == next.tv_sec && now.tv_nsec > next.tv_nsec)) {\r
- uint64_T nsec = (now.tv_sec - next.tv_sec) * 1000000000 + now.tv_nsec - next.tv_nsec;\r
- fprintf(stderr, "Base rate (%<s>s) overrun by %d us\n", (int)(nsec/1000));\r
- }\r
+ do {\r
+ next.tv_sec += period.tv_sec;\r
+ next.tv_nsec += period.tv_nsec;\r
+ if (next.tv_nsec >= 1000000000) {\r
+ next.tv_sec++;\r
+ next.tv_nsec -= 1000000000;\r
+ }\r
+ clock_gettime(CLOCK_MONOTONIC, &now);\r
+ if (now.tv_sec > next.tv_sec ||\r
+ (now.tv_sec == next.tv_sec && now.tv_nsec > next.tv_nsec)) {\r
+ uint32_T usec = (now.tv_sec - next.tv_sec) * 1000000 + (now.tv_nsec - next.tv_nsec)/1000;\r
+ fprintf(stderr, "Base rate (%<fundamentalStepSize>s) overrun by %d us\n", usec);\r
+ next = now;\r
+ continue;\r
+ }\r
+ } while (0);\r
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &next, NULL);\r
\r
}\r
%<modelName>_initialize();\r
simulationFinished = 0;\r
\r
+ /* Prepare task attributes */\r
CHECK0(pthread_attr_init(&attr));\r
CHECK0(pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED));\r
CHECK0(pthread_attr_setschedpolicy(&attr, SCHED_FIFO));\r
\r
%endforeach\r
\r
- /* Starting the main loop */\r
+ /* Starting the base rate thread */\r
sched_param.sched_priority = MAX_PRIO;\r
CHECK0(pthread_attr_setschedparam(&attr, &sched_param));\r
CHECK0(pthread_create(&base_rate_thread, &attr, base_rate, NULL));\r
+ CHECK0(pthread_attr_destroy(&attr));\r
+\r
+ %if extMode == 1\r
+ /* External mode */\r
+ while(rtmGetErrorStatus(%<modelName>_M) == NULL && !rtmGetStopRequested(%<modelName>_M)) {\r
+ rtExtModeOneStep(rtmGetRTWExtModeInfo(RT_MDL), NUMST, (boolean_T *)&rtmGetStopRequested(RT_MDL));\r
+ usleep(%<FEVAL("uint32", fundamentalStepSize * 1000000)>);\r
+ }\r
+ %endif\r
\r
/* Wait for threads to finish */\r
- CHECK0(pthread_attr_destroy(&attr));\r
pthread_join(base_rate_thread, NULL);\r
%foreach i = numSampleTimes\r
%if i == 0 || i == 1 && tid01Eq\r