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