From: Michal Sojka Date: Wed, 10 Jul 2013 12:07:21 +0000 (+0200) Subject: Add main file generator from Hamacek's target X-Git-Url: http://rtime.felk.cvut.cz/gitweb/ert_linux.git/commitdiff_plain/a8d66b1d495efed5fc346bdcc83d299b74fb8ab6 Add main file generator from Hamacek's target --- diff --git a/ert_linux/ert_linux_multitasking_main.tlc b/ert_linux/ert_linux_multitasking_main.tlc new file mode 100644 index 0000000..82e161e --- /dev/null +++ b/ert_linux/ert_linux_multitasking_main.tlc @@ -0,0 +1,244 @@ +%% +%% 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