├── ert_linux ├── ert_linux_genfiles.tlc ├── ert_linux_setup.m ├── sl_customization.m ├── ert_linux_build.m ├── ert_linux_run_model.m ├── ert_linux_deploy_and_connect.m ├── ert_linux.tlc ├── ert_linux_file_process.tlc ├── ert_nuttx.tlc ├── ert_linux_select_callback_handler.m ├── ert_linux_main.tlc ├── ert_linux.tmf └── ert_nuttx.tmf ├── model_samples ├── model_sample.slx ├── model_sample_nuttx.slx ├── README.md └── dummy_sfunction.c ├── LICENSE └── README.md /ert_linux/ert_linux_genfiles.tlc: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /model_samples/model_sample.slx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aa4cc/ert_linux/HEAD/model_samples/model_sample.slx -------------------------------------------------------------------------------- /model_samples/model_sample_nuttx.slx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aa4cc/ert_linux/HEAD/model_samples/model_sample_nuttx.slx -------------------------------------------------------------------------------- /ert_linux/ert_linux_setup.m: -------------------------------------------------------------------------------- 1 | function ert_linux_setup() 2 | curpath = pwd; 3 | tgtpath = curpath(1:end-length('/ert_linux')); 4 | addpath(fullfile(tgtpath, 'ert_linux')); 5 | savepath; 6 | disp('ERT_LINUX Target Path Setup Complete.'); 7 | -------------------------------------------------------------------------------- /ert_linux/sl_customization.m: -------------------------------------------------------------------------------- 1 | function sl_customization(cm) 2 | cm.ExtModeTransports.add('ert_linux.tlc', 'tcpip', 'ext_comm', 'Level1'); 3 | cm.ExtModeTransports.add('ert_nuttx.tlc', 'tcpip', 'ext_comm', 'Level1'); 4 | end 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2009-2017 Department of Control Engineering 2 | Faculty of Electrical Engineering 3 | Czech Technical University in Prague 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | -------------------------------------------------------------------------------- /ert_linux/ert_linux_build.m: -------------------------------------------------------------------------------- 1 | function ert_linux_build(modelName, buildParamsBlockName) 2 | % ************************************************************************* 3 | % Authors: Martin Gurtner 4 | % Date: 2020/02/28 5 | % 6 | % Copyright: 7 | % (c) 2020 Dept. of Control Engineering, FEE, CTU Prague 8 | % 9 | % ************************************************************************* 10 | 11 | % Change dir to the folder where the simulink model is located 12 | cd(fileparts(which(bdroot(modelName)))); 13 | 14 | configSet = getActiveConfigSet(modelName); 15 | % Set the make command params 16 | set_param( configSet, 'MakeCommand', eval(get_param(strcat(modelName, ['/', buildParamsBlockName]), 'make_command'))) 17 | 18 | % Build the model 19 | rtwbuild(modelName); 20 | end 21 | 22 | -------------------------------------------------------------------------------- /model_samples/README.md: -------------------------------------------------------------------------------- 1 | # Sample Models for Linux Simulink Coder Target 2 | 3 | Currently, there is one sample model which can run either on the local machine or can be deployed to a remote architecture target (aarch64 or armhf). 4 | 5 | ## RT priority 6 | For both samples, the user starting up the application on the target hase to be able to set RT priorities. This capabilty can be added to a user called `username` by adding the following lines to /etc/security/limits.conf 7 | ``` 8 | username - rtprio 95 9 | username - memlock unlimited 10 | ``` 11 | Alternatively, one can replace `username` by `@sudo` which would add the same capability to all user in sudo group. 12 | 13 | ## Connection to the remote host 14 | To run the application on the remote target, the host PC connects to the remote target via SSH. To do so, target SSH key has to be either stored in the Simulink model folder under the name `target-ssh-key` or in folder visible by the ssh command. 15 | 16 | -------------------------------------------------------------------------------- /ert_linux/ert_linux_run_model.m: -------------------------------------------------------------------------------- 1 | function ert_linux_run_model(model_app, target_ip_addr, target_user) 2 | % ************************************************************************* 3 | % Authors: Martin Gurtner 4 | % Date: 2020/02/28 5 | % 6 | % Copyright: 7 | % (c) 2020 Dept. of Control Engineering, FEE, CTU Prague 8 | % 9 | % ************************************************************************* 10 | 11 | if nargin == 1 12 | % Run locally 13 | system(sprintf('xterm -e "echo running model %s on the local machine ; ./%s -tf inf -w ; sleep 2" &', model_app, model_app)); 14 | elseif nargin == 3 15 | % Run on the remote target 16 | system('unset LD_LIBRARY_PATH'); 17 | 18 | if isfile('target-ssh-key') 19 | ssh_key_opt = '-i target-ssh-key'; 20 | else 21 | ssh_key_opt = ''; 22 | end 23 | 24 | system(sprintf('xterm -e "scp %s ./%s %s@%s:/tmp ; echo model %s copied to target is run ; ssh %s %s@%s /tmp/%s -tf inf -w ; sleep 2" &', ssh_key_opt, model_app, target_user, target_ip_addr, model_app, ssh_key_opt, target_user, target_ip_addr, model_app)); 25 | else 26 | error('Wrong number of arguments.'); 27 | end 28 | 29 | end 30 | 31 | -------------------------------------------------------------------------------- /ert_linux/ert_linux_deploy_and_connect.m: -------------------------------------------------------------------------------- 1 | function ert_linux_deploy_and_connect(modelName, targetLoginParamsBlockName) 2 | % ************************************************************************* 3 | % Authors: Martin Gurtner 4 | % Date: 2020/02/28 5 | % 6 | % Copyright: 7 | % (c) 2020 Dept. of Control Engineering, FEE, CTU Prague 8 | % 9 | % ************************************************************************* 10 | 11 | % Change dir to the folder where the simulink model is located 12 | cd(fileparts(which(bdroot(modelName)))); 13 | 14 | if nargin == 2 15 | % Run the model on the remote target 16 | 17 | % get the login credentials from the TargetLoginParams block 18 | trgt_ip = get_param(strcat(modelName, strcat('/', targetLoginParamsBlockName)), 'trgt_ip_addr'); 19 | trgt_user = get_param(strcat(modelName, strcat('/', targetLoginParamsBlockName)), 'trgt_username'); 20 | 21 | % Set the IP address of the target 22 | set_param(getActiveConfigSet(modelName), 'ExtModeMexArgs', trgt_ip); 23 | 24 | ert_linux_run_model(get_param(modelName,'name'), trgt_ip, trgt_user); 25 | else 26 | % Run the model locally 27 | 28 | % Set the IP address of the target to the localhost 29 | set_param(getActiveConfigSet(gcs), 'ExtModeMexArgs', '''127.0.0.1''') 30 | 31 | ert_linux_run_model(get_param(modelName,'name')); 32 | end 33 | 34 | pause(3); 35 | 36 | set_param(modelName, 'SimulationCommand', 'connect'); 37 | 38 | 39 | end 40 | 41 | -------------------------------------------------------------------------------- /ert_linux/ert_linux.tlc: -------------------------------------------------------------------------------- 1 | %% SYSTLC: Linux Embedded Coder TMF: ert_linux.tmf MAKE: make_rtw \ 2 | %% EXTMODE: ext_comm 3 | %% 4 | %% Copyright 1994-2011 The MathWorks, Inc. 5 | %% Copyright 2013 Michal Sojka 6 | %% Abstract: Embedded real-time system target file for Linux OS. 7 | %% 8 | %selectfile NULL_FILE 9 | 10 | %assign CodeFormat = "Embedded-C" 11 | 12 | %assign TargetType = "RT" 13 | %assign Language = "C" 14 | %if !EXISTS("AutoBuildProcedure") 15 | %assign AutoBuildProcedure = !GenerateSampleERTMain 16 | %endif 17 | 18 | %assign RateBasedStepFcn = 1 /% Generate only rate-based step functions %/ 19 | 20 | %% The model_SetEventsForThisBaseRate function is not required for the 21 | %% VxWorks environment, i.e., when using an operating system. 22 | %assign SuppressSetEventsForThisBaseRateFcn = (TargetOS == "VxWorksExample") 23 | %if !EXISTS("InlineSetEventsForThisBaseRateFcn") 24 | %assign InlineSetEventsForThisBaseRateFcn = TLC_TRUE 25 | %endif 26 | %if !EXISTS("SuppressMultiTaskScheduler") 27 | %assign SuppressMultiTaskScheduler = TLC_TRUE 28 | %endif 29 | 30 | %assign TargetRegistMutexOp = 1 31 | %assign TargetRegistSynchroOp = 1 32 | 33 | %if FEVAL("verLessThan", "matlab", "9.2") 34 | %include "commontargetlib.tlc" 35 | %endif 36 | 37 | %include "codegenentry.tlc" 38 | %include "ert_linux_genfiles.tlc" 39 | 40 | /% 41 | BEGIN_RTW_OPTIONS 42 | 43 | rtwgensettings.DerivedFrom = 'ert.tlc'; 44 | 45 | %----------------------------------------% 46 | % Configure code generation settings % 47 | %----------------------------------------% 48 | 49 | rtwgensettings.BuildDirSuffix = '_ert_linux'; 50 | rtwgensettings.Version = '1'; 51 | rtwgensettings.SelectCallback = 'ert_linux_select_callback_handler(hDlg, hSrc)'; 52 | 53 | END_RTW_OPTIONS 54 | %/ 55 | -------------------------------------------------------------------------------- /ert_linux/ert_linux_file_process.tlc: -------------------------------------------------------------------------------- 1 | %% 2 | %% linux_ert_target_generate_main.tlc 3 | %% 4 | %% description: 5 | %% TLC script which generates ert_main function according 6 | %% to the number of model tasks and bitrates. 7 | %% 8 | %% date: 2nd Feb 2009 9 | %% 10 | %% author: Lukas Hamacek 11 | %% e-mail: hamacl1@fel.cvut.cz 12 | %% Department of Control Engineering 13 | %% Faculty of Electrical Engineering 14 | %% Czech Technical University in Prague 15 | %% 16 | %% modifications: 17 | %% 2009/2/2 - Lukas Hamacek 18 | %% creation of the file 19 | %% 20 | %% 2009/4/18 - Lukas Hamacek 21 | %% asynchronous sample times checked and removed from generation 22 | %% 23 | 24 | %assign ert_mainC = LibCreateSourceFile("Source", "Custom", "ert_main") 25 | 26 | %assign ::modelName = CompiledModel.Name 27 | %assign ::solverMode = CompiledModel.FixedStepOpts.SolverMode 28 | %assign ::fundamentalStepSize = CompiledModel.FundamentalStepSize 29 | %assign ::numSampleTimes = CompiledModel.NumSynchronousSampleTimes 30 | %assign ::extMode = CompiledModel.ConfigSet.ExtMode 31 | 32 | %% parse sample times and offsets 33 | %assign j = 0 34 | %foreach i = CompiledModel.NumSampleTimes 35 | %if CompiledModel.SampleTime[i].Asynchronous == "no" 36 | %assign ::sampleTime% = CompiledModel.SampleTime[i].PeriodAndOffset[0] 37 | %assign ::offset% = CompiledModel.SampleTime[i].PeriodAndOffset[1] 38 | %assign j = j+1 39 | %endif 40 | %endforeach 41 | 42 | %% Generate ert_main.c 43 | %include "ert_linux_main.tlc" 44 | 45 | %openfile buff 46 | % 47 | %closefile buff 48 | % 49 | 50 | %openfile buff 51 | % 52 | % 53 | %closefile buff 54 | % 55 | -------------------------------------------------------------------------------- /ert_linux/ert_nuttx.tlc: -------------------------------------------------------------------------------- 1 | %% SYSTLC: NuttX Embedded Coder TMF: ert_nuttx.tmf MAKE: make_rtw \ 2 | %% EXTMODE: ext_comm 3 | %% 4 | %% Copyright 1994-2011 The MathWorks, Inc. 5 | %% Copyright 2013 Michal Sojka 6 | %% Copyright 2014-2020 Pavel Pisa 7 | %% Abstract: Embedded real-time system target file for NuttX OS. 8 | %% 9 | %selectfile NULL_FILE 10 | 11 | %assign CodeFormat = "Embedded-C" 12 | 13 | %assign TargetType = "RT" 14 | %assign Language = "C" 15 | %if !EXISTS("AutoBuildProcedure") 16 | %assign AutoBuildProcedure = !GenerateSampleERTMain 17 | %endif 18 | 19 | %assign RateBasedStepFcn = 1 /% Generate only rate-based step functions %/ 20 | 21 | %% The model_SetEventsForThisBaseRate function is not required for the 22 | %% VxWorks environment, i.e., when using an operating system. 23 | %assign SuppressSetEventsForThisBaseRateFcn = (TargetOS == "VxWorksExample") 24 | %if !EXISTS("InlineSetEventsForThisBaseRateFcn") 25 | %assign InlineSetEventsForThisBaseRateFcn = TLC_TRUE 26 | %endif 27 | %if !EXISTS("SuppressMultiTaskScheduler") 28 | %assign SuppressMultiTaskScheduler = TLC_TRUE 29 | %endif 30 | 31 | %assign TargetRegistMutexOp = 1 32 | %assign TargetRegistSynchroOp = 1 33 | 34 | %if FEVAL("verLessThan", "matlab", "9.2") 35 | %include "commontargetlib.tlc" 36 | %endif 37 | 38 | %include "codegenentry.tlc" 39 | %include "ert_linux_genfiles.tlc" 40 | 41 | /% 42 | BEGIN_RTW_OPTIONS 43 | 44 | rtwgensettings.DerivedFrom = 'ert.tlc'; 45 | 46 | %----------------------------------------% 47 | % Configure code generation settings % 48 | %----------------------------------------% 49 | 50 | rtwgensettings.BuildDirSuffix = '_ert_nuttx'; 51 | rtwgensettings.Version = '1'; 52 | rtwgensettings.SelectCallback = 'ert_linux_select_callback_handler(hDlg, hSrc)'; 53 | 54 | END_RTW_OPTIONS 55 | %/ 56 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Minimalist Simulink Coder Target for Linux 2 | ============================================ 3 | 4 | Authors: Martin Gurtner 5 | Lukas Hamacek 6 | Pavel Pisa 7 | Michal Sojka 8 | 9 | The project has been initiated and is maintained by: 10 | Czech Technical University in Prague 11 | Faculty of Electrical Engineering 12 | Department of Control Engineering 13 | https://control.fel.cvut.cz/ 14 | 15 | The aim of this target is to allow Simulink to generate code that 16 | runs in real-time on Linux, preferably with fully preemptive kernel. 17 | This target tries to be minimalist in the sense that it reuses 18 | as much as possible from Simulink built-in targets. 19 | 20 | Installation 21 | ------------ 22 | 23 | In Matlab prompt execute: 24 | 25 | cd /ert_linux/ert_linux 26 | ert_linux_setup 27 | 28 | From now on, Code Generation pane of Simulink Model Configuration 29 | Parameters should offer `ert_linux.tlc` as System Target File (after 30 | pressing "Browse...." button). 31 | 32 | Documentation 33 | ------------- 34 | 35 | In order to cross-compile the generated source, modify the "Make 36 | command" in Code Generation pane to set the CC variable (and/or CPP 37 | for C++ compiler). For example: 38 | 39 | make_rtw CC=arm-linux-gnueabi-gcc 40 | 41 | Pointers to more ERT Linux target documentation can be found at the 42 | project SourceForge page 43 | 44 | http://lintarget.sourceforge.net/ 45 | 46 | In addition to the target documentation, there are documented 47 | applications (PMSM control, CAN etc.) and related packages 48 | for SocketCAN, Humusoft MF624 data acquisition boards 49 | and more at related Lintarget site 50 | 51 | Michal Sojka's blogpost about the actual version can be found at 52 | http://rtime.felk.cvut.cz/~sojka/blog/on-generating-linux-applications-from-simulink/. 53 | 54 | Development Sources Repository 55 | ------------------------------ 56 | 57 | Newest version of this project can be found at 58 | 59 | https://github.com/aa4cc/ert_linux/ 60 | 61 | Tested Hardware Platforms and Systems 62 | ------------------------------------- 63 | 64 | This target has been tested with Matlab R2019b 65 | and Humusoft MF624 cards with Linux kernels up to 4.19 RT 66 | on 64-bit x86 Debian GNU/Linux system, ARM based Xilinx Zynq 67 | systems and AArch64 Nvidia based systems. Experimental support 68 | for NuttX RTOS for small MCUs is included as well. 69 | 70 | Big thanks for help with update to R2019b and other advices 71 | to Jan Houska . 72 | -------------------------------------------------------------------------------- /ert_linux/ert_linux_select_callback_handler.m: -------------------------------------------------------------------------------- 1 | function ert_linux_select_callback_handler(varargin) 2 | 3 | % ************************************************************************* 4 | % Authors: Lukáš Hamáček, Michal Sojka 5 | % Date: 2007/01/18 6 | % 7 | % Copyright: 8 | % (c) 2009 Dept. of Control Engineering, FEE, CTU Prague 9 | % 10 | % ************************************************************************* 11 | 12 | hDlg = varargin{1}; 13 | hSrc = varargin{2}; 14 | 15 | % ----- solver pane ------------------------------------------------------- 16 | % fixed-step required by the rtw 17 | slConfigUISetVal(hDlg, hSrc, 'Solver', 'FixedStepDiscrete'); 18 | slConfigUISetEnabled(hDlg, hSrc, 'Solver', true); 19 | slConfigUISetVal(hDlg, hSrc, 'SolverType', 'Fixed-step'); 20 | slConfigUISetEnabled(hDlg, hSrc, 'SolverType', false); 21 | slConfigUISetVal(hDlg, hSrc, 'SampleTimeConstraint', 'Unconstrained'); 22 | slConfigUISetVal(hDlg, hSrc, 'SolverMode', 'Auto'); 23 | slConfigUISetVal(hDlg, hSrc, 'AutoInsertRateTranBlk', 'off'); 24 | 25 | % ----- data import/export pane ------------------------------------------- 26 | 27 | % ----- optimization pane ------------------------------------------------- 28 | 29 | % ----- diagnostics pane -------------------------------------------------- 30 | 31 | % ----- hardware implementation pane -------------------------------------- 32 | 33 | % ----- model referencing pane -------------------------------------------- 34 | 35 | % ----- real time workshop pane ------------------------------------------- 36 | % general (default settings) 37 | % slConfigUISetVal(hDlg, hSrc, 'GenerateReport', 'off'); 38 | % slConfigUISetVal(hDlg, hSrc, 'IncludeHyperlinkInReport', 'off'); 39 | % slConfigUISetVal(hDlg, hSrc, 'LaunchReport', 'off'); % 40 | % slConfigUISetVal(hDlg, hSrc, 'IgnoreCustomStorageClasses', 'off'); 41 | % slConfigUISetVal(hDlg, hSrc, 'MakeCommand', 'make_rtw CC=powerpc-603e-linux-gnu-gcc.exe'); 42 | % slConfigUISetVal(hDlg, hSrc, 'GenCodeOnly', 'on'); 43 | % slConfigUISetEnabled(hDlg, hSrc, 'GenCodeOnly', false); 44 | % 45 | % debug 46 | % slConfigUISetVal(hDlg, hSrc, 'RTWVerbose', 'on'); 47 | % slConfigUISetVal(hDlg, hSrc, 'RetainRTWFile', 'on'); 48 | 49 | % interface 50 | % slConfigUISetVal(hDlg, hSrc, 'GenFloatMathFcnCalls', 'ANSI_C'); 51 | % slConfigUISetEnabled(hDlg, hSrc, 'GenFloatMathFcnCalls', false); 52 | % slConfigUISetVal(hDlg, hSrc, 'MultiInstanceERTCode', 'off'); 53 | % slConfigUISetEnabled(hDlg, hSrc, 'MultiInstanceERTCode', false); 54 | % slConfigUISetVal(hDlg, hSrc, 'GRTInterface', 'off'); 55 | % slConfigUISetEnabled(hDlg, hSrc, 'GRTInterface', false); 56 | % slConfigUISetVal(hDlg, hSrc, 'ExtModeMexArgs', '''192.168.123.199'' 1 17725'); 57 | 58 | % slConfigUISetVal(hDlg, hSrc, 'CombineOutputUpdateFcns', 'on'); 59 | % slConfigUISetEnabled(hDlg, hSrc, 'CombineOutputUpdateFcns', false); 60 | % slConfigUISetVal(hDlg, hSrc, 'GRTInterface', 'off'); 61 | % slConfigUISetEnabled(hDlg, hSrc, 'GRTInterface', false); 62 | 63 | % slConfigUISetVal(hDlg, hSrc, 'GenerateErtSFunction', 'off'); 64 | % slConfigUISetEnabled(hDlg, hSrc, 'GenerateErtSFunction', false); 65 | % slConfigUISetVal(hDlg, hSrc, 'MatFileLogging', 'off'); 66 | 67 | % templates 68 | % slConfigUISetVal(hDlg, hSrc, 'ERTSrcFileBannerTemplate', 'linux_ert_target_code_template.cgt'); 69 | % slConfigUISetEnabled(hDlg, hSrc, 'ERTSrcFileBannerTemplate',false); 70 | % slConfigUISetVal(hDlg, hSrc, 'ERTHdrFileBannerTemplate', 'linux_ert_target_code_template.cgt'); 71 | % slConfigUISetEnabled(hDlg, hSrc, 'ERTHdrFileBannerTemplate',false); 72 | % slConfigUISetVal(hDlg, hSrc, 'ERTDataSrcFileTemplate', 'linux_ert_target_code_template.cgt'); 73 | % slConfigUISetEnabled(hDlg, hSrc, 'ERTDataSrcFileTemplate',false); 74 | % slConfigUISetVal(hDlg, hSrc, 'ERTDataHdrFileTemplate', 'linux_ert_target_code_template.cgt'); 75 | % slConfigUISetEnabled(hDlg, hSrc, 'ERTDataHdrFileTemplate',false); 76 | slConfigUISetVal(hDlg, hSrc, 'ERTCustomFileTemplate', 'ert_linux_file_process.tlc'); 77 | slConfigUISetEnabled(hDlg, hSrc, 'ERTCustomFileTemplate',false); 78 | slConfigUISetVal(hDlg, hSrc, 'GenerateSampleERTMain', 'off'); 79 | slConfigUISetEnabled(hDlg, hSrc, 'GenerateSampleERTMain',false); 80 | 81 | % ----- other ------------------------------------------------------------- 82 | -------------------------------------------------------------------------------- /model_samples/dummy_sfunction.c: -------------------------------------------------------------------------------- 1 | /* 2 | * S-function - dummy_sfunction to trigger S-function enabled build mode 3 | * 4 | * Copyright (C) 2020 Lukas Cerny 5 | * Copyright (C) 2014-2020 Pavel Pisa 6 | * 7 | * Department of Control Engineering 8 | * Faculty of Electrical Engineering 9 | * Czech Technical University in Prague (CTU) 10 | * 11 | * The S-Function for ERT Linux can be distributed in compliance 12 | * with GNU General Public License (GPL) version 2 or later. 13 | * Other licence can negotiated with CTU. 14 | * 15 | * Next exception is granted in addition to GPL. 16 | * Instantiating or linking compiled version of this code 17 | * to produce an application image/executable, does not 18 | * by itself cause the resulting application image/executable 19 | * to be covered by the GNU General Public License. 20 | * This exception does not however invalidate any other reasons 21 | * why the executable file might be covered by the GNU Public License. 22 | * Publication of enhanced or derived S-function files is required 23 | * although. 24 | * 25 | * Linux ERT code is available from 26 | * https://github.com/aa4cc/ert_linux 27 | * More CTU Linux target for Simulink components are available at 28 | * http://lintarget.sourceforge.net/ 29 | * 30 | * sfuntmpl_basic.c by The MathWorks, Inc. has been used to accomplish 31 | * required S-function structure. 32 | */ 33 | 34 | 35 | #define S_FUNCTION_NAME dummy_sfunction 36 | #define S_FUNCTION_LEVEL 2 37 | 38 | /* 39 | * The S-function has next parameters 40 | * 41 | * Sample time - sample time value or -1 for inherited 42 | */ 43 | 44 | #define PRM_TS(S) (mxGetScalar(ssGetSFcnParam(S, 0))) 45 | 46 | #define PRM_COUNT 1 47 | 48 | /* 49 | * Need to include simstruc.h for the definition of the SimStruct and 50 | * its associated macro definitions. 51 | */ 52 | #include 53 | #include "simstruc.h" 54 | 55 | /* Error handling 56 | * -------------- 57 | * 58 | * You should use the following technique to report errors encountered within 59 | * an S-function: 60 | * 61 | * ssSetErrorStatus(S,"Error encountered due to ..."); 62 | * return; 63 | * 64 | * Note that the 2nd argument to ssSetErrorStatus must be persistent memory. 65 | * It cannot be a local variable. For example the following will cause 66 | * unpredictable errors: 67 | * 68 | * mdlOutputs() 69 | * { 70 | * char msg[256]; {ILLEGAL: to fix use "static char msg[256];"} 71 | * sprintf(msg,"Error due to %s", string); 72 | * ssSetErrorStatus(S,msg); 73 | * return; 74 | * } 75 | * 76 | * See matlabroot/simulink/src/sfuntmpl_doc.c for more details. 77 | */ 78 | 79 | /*====================* 80 | * S-function methods * 81 | *====================*/ 82 | 83 | #define MDL_CHECK_PARAMETERS /* Change to #undef to remove function */ 84 | #if defined(MDL_CHECK_PARAMETERS) && defined(MATLAB_MEX_FILE) 85 | /* Function: mdlCheckParameters ============================================= 86 | * Abstract: 87 | * mdlCheckParameters verifies new parameter settings whenever parameter 88 | * change or are re-evaluated during a simulation. When a simulation is 89 | * running, changes to S-function parameters can occur at any time during 90 | * the simulation loop. 91 | */ 92 | static void mdlCheckParameters(SimStruct *S) 93 | { 94 | if ((PRM_TS(S) < 0) && (PRM_TS(S) != -1)) 95 | ssSetErrorStatus(S, "Ts has to be positive or -1 for automatic step"); 96 | } 97 | #endif /* MDL_CHECK_PARAMETERS */ 98 | 99 | 100 | /* Function: mdlInitializeSizes =============================================== 101 | * Abstract: 102 | * The sizes information is used by Simulink to determine the S-function 103 | * block's characteristics (number of inputs, outputs, states, etc.). 104 | */ 105 | static void mdlInitializeSizes(SimStruct *S) 106 | { 107 | int_T nInputPorts = 0; 108 | int_T i; 109 | 110 | ssSetNumSFcnParams(S, PRM_COUNT); /* Number of expected parameters */ 111 | if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) { 112 | /* Return if number of expected != number of actual parameters */ 113 | ssSetErrorStatus(S, "1-parameters requited: Ts"); 114 | return; 115 | } 116 | 117 | #if defined(MDL_CHECK_PARAMETERS) && defined(MATLAB_MEX_FILE) 118 | mdlCheckParameters(S); 119 | if (ssGetErrorStatus(S) != NULL) return; 120 | #endif 121 | 122 | ssSetNumContStates(S, 0); 123 | ssSetNumDiscStates(S, 0); 124 | 125 | if (!ssSetNumInputPorts(S, nInputPorts)) return; 126 | 127 | if (!ssSetNumOutputPorts(S, 1)) return; 128 | ssSetOutputPortWidth(S, 0, 1); 129 | ssSetOutputPortDataType(S, 0, SS_INT32); 130 | 131 | ssSetNumSampleTimes(S, 1); 132 | ssSetNumRWork(S, 0); 133 | ssSetNumIWork(S, 0); 134 | ssSetNumPWork(S, 0); 135 | ssSetNumModes(S, 0); 136 | ssSetNumNonsampledZCs(S, 0); 137 | 138 | /* Specify the sim state compliance to be same as a built-in block */ 139 | ssSetSimStateCompliance(S, USE_DEFAULT_SIM_STATE); 140 | 141 | ssSetOptions(S, 0); 142 | } 143 | 144 | 145 | 146 | /* Function: mdlInitializeSampleTimes ========================================= 147 | * Abstract: 148 | * This function is used to specify the sample time(s) for your 149 | * S-function. You must register the same number of sample times as 150 | * specified in ssSetNumSampleTimes. 151 | */ 152 | static void mdlInitializeSampleTimes(SimStruct *S) 153 | { 154 | if (PRM_TS(S) == -1) { 155 | ssSetSampleTime(S, 0, CONTINUOUS_SAMPLE_TIME); 156 | ssSetOffsetTime(S, 0, FIXED_IN_MINOR_STEP_OFFSET); 157 | } else { 158 | ssSetSampleTime(S, 0, PRM_TS(S)); 159 | ssSetOffsetTime(S, 0, 0.0); 160 | } 161 | } 162 | 163 | 164 | 165 | #define MDL_INITIALIZE_CONDITIONS /* Change to #undef to remove function */ 166 | #if defined(MDL_INITIALIZE_CONDITIONS) 167 | /* Function: mdlInitializeConditions ======================================== 168 | * Abstract: 169 | * In this function, you should initialize the continuous and discrete 170 | * states for your S-function block. The initial states are placed 171 | * in the state vector, ssGetContStates(S) or ssGetRealDiscStates(S). 172 | * You can also perform any other initialization activities that your 173 | * S-function may require. Note, this routine will be called at the 174 | * start of simulation and if it is present in an enabled subsystem 175 | * configured to reset states, it will be call when the enabled subsystem 176 | * restarts execution to reset the states. 177 | */ 178 | static void mdlInitializeConditions(SimStruct *S) 179 | { 180 | 181 | } 182 | #endif /* MDL_INITIALIZE_CONDITIONS */ 183 | 184 | 185 | 186 | #define MDL_START /* Change to #undef to remove function */ 187 | #if defined(MDL_START) 188 | /* Function: mdlStart ======================================================= 189 | * Abstract: 190 | * This function is called once at start of model execution. If you 191 | * have states that should be initialized once, this is the place 192 | * to do it. 193 | */ 194 | static void mdlStart(SimStruct *S) 195 | { 196 | mdlInitializeConditions(S); 197 | } 198 | #endif /* MDL_START */ 199 | 200 | 201 | 202 | /* Function: mdlOutputs ======================================================= 203 | * Abstract: 204 | * In this function, you compute the outputs of your S-function 205 | * block. 206 | */ 207 | static void mdlOutputs(SimStruct *S, int_T tid) 208 | { 209 | int32_T *y = ssGetOutputPortSignal(S,0); 210 | 211 | y[0] = 0; 212 | } 213 | 214 | 215 | 216 | #define MDL_UPDATE /* Change to #undef to remove function */ 217 | #if defined(MDL_UPDATE) 218 | /* Function: mdlUpdate ====================================================== 219 | * Abstract: 220 | * This function is called once for every major integration time step. 221 | * Discrete states are typically updated here, but this function is useful 222 | * for performing any tasks that should only take place once per 223 | * integration step. 224 | */ 225 | static void mdlUpdate(SimStruct *S, int_T tid) 226 | { 227 | 228 | } 229 | #endif /* MDL_UPDATE */ 230 | 231 | 232 | 233 | #undef MDL_DERIVATIVES /* Change to #undef to remove function */ 234 | #if defined(MDL_DERIVATIVES) 235 | /* Function: mdlDerivatives ================================================= 236 | * Abstract: 237 | * In this function, you compute the S-function block's derivatives. 238 | * The derivatives are placed in the derivative vector, ssGetdX(S). 239 | */ 240 | static void mdlDerivatives(SimStruct *S) 241 | { 242 | } 243 | #endif /* MDL_DERIVATIVES */ 244 | 245 | 246 | 247 | /* Function: mdlTerminate ===================================================== 248 | * Abstract: 249 | * In this function, you should perform any actions that are necessary 250 | * at the termination of a simulation. For example, if memory was 251 | * allocated in mdlStart, this is the place to free it. 252 | */ 253 | static void mdlTerminate(SimStruct *S) 254 | { 255 | 256 | } 257 | 258 | 259 | /*======================================================* 260 | * See sfuntmpl_doc.c for the optional S-function methods * 261 | *======================================================*/ 262 | 263 | /*=============================* 264 | * Required S-function trailer * 265 | *=============================*/ 266 | 267 | #ifdef MATLAB_MEX_FILE /* Is this file being compiled as a MEX-file? */ 268 | #include "simulink.c" /* MEX-file interface mechanism */ 269 | #else 270 | #include "cg_sfun.h" /* Code generation registration function */ 271 | #endif 272 | -------------------------------------------------------------------------------- /ert_linux/ert_linux_main.tlc: -------------------------------------------------------------------------------- 1 | %% 2 | %% 3 | %% description: 4 | %% This TLC script generates ert_main.c 5 | %% case. 6 | %% 7 | %% authors: Michal Sojka 8 | %% Lukas Hamacek 9 | %% 10 | %% Department of Control Engineering 11 | %% Faculty of Electrical Engineering 12 | %% Czech Technical University in Prague 13 | %% 14 | 15 | %% GENERATEDECLARATIONS 16 | %% This function generates main function declarations. 17 | %% 18 | 19 | %assign ::tid01Eq = LibGetTID01EQ() 20 | 21 | %function generateDeclarations() Output 22 | 23 | /* Multirate - Multitasking case main file */ 24 | #define _BSD_SOURCE /* For usleep() */ 25 | #define _POSIX_C_SOURCE 200112L /* For clock_gettime() & clock_nanosleep() */ 26 | #include /* This ert_main.c example uses printf/fflush */ 27 | #include /* Thread library header file */ 28 | #include /* OS scheduler header file */ 29 | #include /* Semaphores library header file */ 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include /* For mlockall() */ 35 | #include 36 | #include "%.h" /* Model's header file */ 37 | #include "rtwtypes.h" /* MathWorks types */ 38 | %if extMode == 1 39 | #include "ext_work.h" /* External mode header file */ 40 | %endif 41 | 42 | #ifndef TRUE 43 | #define TRUE true 44 | #define FALSE false 45 | #endif 46 | 47 | /*==================* 48 | * Required defines * 49 | *==================*/ 50 | 51 | #ifndef MODEL 52 | # error Must specify a model name. Define MODEL=name. 53 | #else 54 | /* create generic macros that work with any model */ 55 | # define EXPAND_CONCAT(name1,name2) name1 ## name2 56 | # define CONCAT(name1,name2) EXPAND_CONCAT(name1,name2) 57 | # define MODEL_INITIALIZE CONCAT(MODEL,_initialize) 58 | # define MODEL_STEP CONCAT(MODEL,_step) 59 | # define MODEL_TERMINATE CONCAT(MODEL,_terminate) 60 | # define RT_MDL CONCAT(MODEL,_M) 61 | #endif 62 | 63 | /* Error checking */ 64 | #define STRINGIZE(num) #num 65 | #define POS(line) __FILE__ ":" STRINGIZE(line) 66 | #define CHECK0(expr) do { int __err = (expr); if (__err) { fprintf(stderr, "Error: %s returned '%s' at " POS(__LINE__) "\n", #expr, strerror(__err)); exit(1); } } while (0); 67 | #define CHECKE(expr) do { if ((expr) == -1) { perror(#expr " at " POS(__LINE__)); exit(1); } } while (0); 68 | 69 | /** 70 | * Maximal priority used by base rate thread. 71 | */ 72 | #define MAX_PRIO (sched_get_priority_min(SCHED_FIFO) + %) 73 | 74 | /** 75 | * Thread handle of the base rate thread. 76 | * Fundamental sample time = %s 77 | */ 78 | pthread_t base_rate_thread; 79 | 80 | /** 81 | * Thread handles of and semaphores for sub rate threads. The array 82 | * is indexed by TID, i.e. the first one or two elements are unused. 83 | %foreach i = numSampleTimes 84 | %if i == 0 || i == 1 && tid01Eq 85 | %continue 86 | %endif 87 | %assign s = sampleTime% 88 | %assign o = offset% 89 | * TID%: sample time = %s, offset = %s 90 | %endforeach 91 | */ 92 | struct sub_rate { 93 | pthread_t thread; 94 | sem_t sem; 95 | } sub_rate[%]; 96 | 97 | /** 98 | * Flag if the simulation has been terminated. 99 | */ 100 | int simulationFinished = 0; 101 | 102 | %if extMode == 1 103 | /* Indication that the base rate thread has started */ 104 | sem_t ext_mode_ready; 105 | %endif 106 | %endfunction 107 | 108 | %function printfunc() Output 109 | /% printf("%s\n", __func__); %/ 110 | %endfunction 111 | 112 | %function generateRtOneStep() Output 113 | %foreach j = numSampleTimes - 1 114 | %assign i = j + 1 115 | %if i == 1 && tid01Eq 116 | %continue 117 | %endif 118 | void *sub_rate%(void *arg) 119 | { 120 | while(!simulationFinished) { 121 | sem_wait(&sub_rate[%].sem); /* sem_val = 1 */ 122 | % 123 | %_step%(); 124 | sem_wait(&sub_rate[%].sem); /* sem_val = 0 */ 125 | } 126 | return NULL; 127 | } 128 | %endforeach 129 | %endfunction 130 | 131 | 132 | %% GENERATEMAIN 133 | %% This function generates code of the main function function. 134 | %% 135 | %function generateMain() Output 136 | /** 137 | * This is the thread function of the base rate loop. 138 | * Fundamental sample time = %s 139 | */ 140 | void * base_rate(void *param_unused) 141 | { 142 | %assign sec = FEVAL("uint32", fundamentalStepSize) 143 | %assign nsec = FEVAL("uint32", (fundamentalStepSize - FEVAL("floor", fundamentalStepSize))*1000000000) 144 | struct timespec now, next; 145 | struct timespec period = { %, % }; /* % seconds */ 146 | boolean_T eventFlags[%]; /* Model has % rates */ 147 | int_T taskCounter[%] = %; 148 | int_T OverrunFlags[%]; 149 | int step_sem_value; 150 | int_T i; 151 | 152 | (void)param_unused; 153 | 154 | %if extMode == 1 155 | % 156 | CHECKE(sem_post(&ext_mode_ready)); 157 | %endif 158 | 159 | clock_gettime(CLOCK_MONOTONIC, &next); 160 | 161 | /* Main loop, running until all the threads are terminated */ 162 | while(rtmGetErrorStatus(%_M) == NULL && !rtmGetStopRequested(%_M)) { 163 | % 164 | /* Check subrate overrun, set rates that need to run this time step*/ 165 | %\ 166 | 167 | /* Trigger sub-rate threads */ 168 | %foreach i = numSampleTimes 169 | %if i == 0 || i == 1 && tid01Eq 170 | %continue 171 | %endif 172 | %assign s = sampleTime% 173 | %assign o = offset% 174 | /* Sampling rate %, sample time = %, offset = % */ 175 | if (eventFlags[%]) { 176 | eventFlags[%] = FALSE; 177 | sem_getvalue(&sub_rate[%].sem, &step_sem_value); 178 | if (step_sem_value) { 179 | rtmSetErrorStatus(%_M, "Overrun"); 180 | printf("Sub rate % overrun, sample time=%s, offset=%s is too fast\n"); 181 | break; 182 | } 183 | sem_post(&sub_rate[%].sem); 184 | sem_post(&sub_rate[%].sem); 185 | } 186 | %endforeach 187 | 188 | /* Execute base rate step */ 189 | %if solverMode == "SingleTasking" 190 | %_step(); 191 | %else 192 | %_step0(); 193 | %endif 194 | 195 | %if extMode == 1 196 | rtExtModeCheckEndTrigger(); 197 | %endif 198 | 199 | do { 200 | next.tv_sec += period.tv_sec; 201 | next.tv_nsec += period.tv_nsec; 202 | if (next.tv_nsec >= 1000000000) { 203 | next.tv_sec++; 204 | next.tv_nsec -= 1000000000; 205 | } 206 | clock_gettime(CLOCK_MONOTONIC, &now); 207 | if (now.tv_sec > next.tv_sec || 208 | (now.tv_sec == next.tv_sec && now.tv_nsec > next.tv_nsec)) { 209 | uint32_T usec = (now.tv_sec - next.tv_sec) * 1000000 + (now.tv_nsec - next.tv_nsec)/1000; 210 | fprintf(stderr, "Base rate (%s) overrun by %d us\n", usec); 211 | next = now; 212 | continue; 213 | } 214 | } while (0); 215 | clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &next, NULL); 216 | 217 | } 218 | 219 | simulationFinished = 1; 220 | /* Final step */ 221 | for (i = %<1 + tid01Eq>; i < %; i++) { 222 | sem_post(&sub_rate[i].sem); 223 | sem_post(&sub_rate[i].sem); 224 | } 225 | return NULL; 226 | } 227 | 228 | /** 229 | * Signal handler for ABORT during simulation 230 | */ 231 | void abort_signal_handler(int sig) { 232 | fprintf(stderr, "Simulation aborted by pressing CTRL+C\n"); 233 | rtmSetStopRequested(%_M, 1); 234 | } 235 | 236 | /** 237 | * This is the main function of the model. 238 | * Multirate - Multitasking case main file 239 | */ 240 | int_T main(int_T argc, const char_T *argv[]) 241 | { 242 | const char_T *errStatus; 243 | int_T i; 244 | pthread_attr_t attr; 245 | struct sched_param sched_param; 246 | 247 | %if extMode == 1 248 | /* External mode */ 249 | /* rtERTExtModeParseArgs(argc, argv); */ 250 | rtExtModeParseArgs(argc, argv, NULL); 251 | CHECKE(sem_init(&ext_mode_ready, 0, 0)); 252 | %else 253 | (void)(argc); 254 | (void *)(argv); 255 | %endif 256 | 257 | #ifndef WITHOUT_MLOCK 258 | CHECKE(mlockall(MCL_CURRENT | MCL_FUTURE)); 259 | #endif 260 | 261 | /* Initialize model */ 262 | %_initialize(); 263 | simulationFinished = 0; 264 | 265 | /* Prepare task attributes */ 266 | CHECK0(pthread_attr_init(&attr)); 267 | CHECK0(pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED)); 268 | CHECK0(pthread_attr_setschedpolicy(&attr, SCHED_FIFO)); 269 | 270 | %foreach i = numSampleTimes 271 | %if i == 0 || i == 1 && tid01Eq 272 | %continue 273 | %endif 274 | %assign s = sampleTime% 275 | %assign o = offset% 276 | 277 | /* Initializing the step semaphore of the loop % */ 278 | CHECKE(sem_init(&sub_rate[%].sem, 0, 0)); 279 | 280 | /* Starting loop % thread for sample time = %s, offset = %s. */ 281 | sched_param.sched_priority = MAX_PRIO - %; 282 | CHECK0(pthread_attr_setschedparam(&attr, &sched_param)); 283 | CHECK0(pthread_create(&sub_rate[%].thread, &attr, sub_rate%, (void*)%)); 284 | 285 | %endforeach 286 | 287 | /* Starting the base rate thread */ 288 | sched_param.sched_priority = MAX_PRIO; 289 | CHECK0(pthread_attr_setschedparam(&attr, &sched_param)); 290 | CHECK0(pthread_create(&base_rate_thread, &attr, base_rate, NULL)); 291 | CHECK0(pthread_attr_destroy(&attr)); 292 | 293 | %if extMode == 1 294 | /* External mode */ 295 | CHECKE(sem_wait(&ext_mode_ready)); 296 | 297 | signal(SIGINT, abort_signal_handler); /* important for letting the destructor be called. */ 298 | 299 | while(rtmGetErrorStatus(%_M) == NULL && !rtmGetStopRequested(%_M)) { 300 | rtExtModeOneStep(rtmGetRTWExtModeInfo(RT_MDL), NUMST, (boolean_T *)&rtmGetStopRequested(RT_MDL)); 301 | usleep(%); 302 | } 303 | %endif 304 | 305 | /* Wait for threads to finish */ 306 | pthread_join(base_rate_thread, NULL); 307 | %foreach i = numSampleTimes 308 | %if i == 0 || i == 1 && tid01Eq 309 | %continue 310 | %endif 311 | pthread_join(sub_rate[%].thread, NULL); 312 | %endforeach 313 | 314 | %if extMode == 1 315 | rtExtModeShutdown(%); 316 | %endif 317 | 318 | /* Terminate model */ 319 | %_terminate(); 320 | 321 | errStatus = rtmGetErrorStatus(%_M); 322 | if(errStatus != NULL && strcmp(errStatus, "Simulation finished")) { 323 | %%printf("%s\n", rtmGetErrorStatus(%_M)); 324 | if(!strcmp(errStatus, "Overrun")) { 325 | printf("ISR overrun - sampling rate too fast\n"); 326 | } 327 | return(1); 328 | } 329 | return 0; 330 | } 331 | 332 | /* Local Variables: */ 333 | /* compile-command: "make -f %.mk" */ 334 | /* End: */ 335 | 336 | %endfunction 337 | -------------------------------------------------------------------------------- /ert_linux/ert_linux.tmf: -------------------------------------------------------------------------------- 1 | # Copyright 1994-2018 The MathWorks, Inc. 2 | # 3 | # File : ert_unix.tmf 4 | # 5 | # Abstract: 6 | # Template makefile for building a UNIX-based stand-alone embedded 7 | # real-time version of Simulink model using generated C code. 8 | # 9 | # This makefile attempts to conform to the guidelines specified in the 10 | # IEEE Std 1003.2-1992 (POSIX) standard. It is designed to be used 11 | # with GNU Make which is located in matlabroot/rtw/bin. 12 | # 13 | # Note that this template is automatically customized by the build 14 | # procedure to create ".mk" 15 | # 16 | # The following defines can be used to modify the behavior of the 17 | # build: 18 | # OPT_OPTS - Optimization options. Default is -O. 19 | # CPP_OPTS - C++ compiler options. 20 | # OPTS - User specific compile options. 21 | # USER_SRCS - Additional user sources, such as files needed by 22 | # S-functions. 23 | # USER_INCLUDES - Additional include paths 24 | # (i.e. USER_INCLUDES="-Iwhere-ever -Iwhere-ever2") 25 | # 26 | # To enable debugging: 27 | # set DEBUG_BUILD = 1 below, which will trigger OPTS=-g and 28 | # LDFLAGS += -g (may vary with compiler version, see compiler doc) 29 | # 30 | # This template makefile is designed to be used with a system target 31 | # file that contains 'rtwgensettings.BuildDirSuffix' see ert.tlc 32 | 33 | 34 | #------------------------ Macros read by make_rtw ------------------------------ 35 | # 36 | # The following macros are read by the build procedure: 37 | # 38 | # MAKECMD - This is the command used to invoke the make utility 39 | # HOST - What platform this template makefile is targeted for 40 | # (i.e. PC or UNIX) 41 | # BUILD - Invoke make from the build procedure (yes/no)? 42 | # SYS_TARGET_FILE - Name of system target file. 43 | 44 | MAKECMD = |>MATLAB_BIN<|/|>ARCH<|/gmake 45 | HOST = UNIX 46 | BUILD = yes 47 | SYS_TARGET_FILE = any 48 | 49 | # Opt in to simplified format by specifying compatible Toolchain 50 | TOOLCHAIN_NAME = ["Clang v3.1 | gmake (64-bit Mac)", \ 51 | "GNU gcc/g++ | gmake (64-bit Linux)"] 52 | 53 | #---------------------- Tokens expanded by make_rtw ---------------------------- 54 | # 55 | # The following tokens, when wrapped with "|>" and "<|" are expanded by the 56 | # build procedure. 57 | # 58 | # MODEL_NAME - Name of the Simulink block diagram 59 | # MODEL_MODULES - Any additional generated source modules 60 | # MAKEFILE_NAME - Name of makefile created from template makefile .mk 61 | # MATLAB_ROOT - Path to where MATLAB is installed. 62 | # S_FUNCTIONS_LIB - List of S-functions libraries to link. 63 | # NUMST - Number of sample times 64 | # NCSTATES - Number of continuous states 65 | # COMPUTER - Computer type. See the MATLAB computer command. 66 | # BUILDARGS - Options passed in at the command line. 67 | # MULTITASKING - yes (1) or no (0): Is solver mode multitasking 68 | # INTEGER_CODE - yes (1) or no (0): Is generated code purely integer 69 | # MAT_FILE - yes (1) or no (0): Should mat file logging be done, 70 | # if 0, the generated code runs indefinitely 71 | # MULTI_INSTANCE_CODE - Is the generated code multi instantiable (1/0)? 72 | # MODELREFS - List of referenced models 73 | # TGT_FCN_LIB - Target function (code replacement) library to use 74 | # SHRLIBTARGET - Is this build intended for generation of a shared library instead 75 | # of executable (1/0)? 76 | # MAKEFILEBUILDER_TGT - Is this build performed by the MakefileBuilder class 77 | # e.g. to create a PIL executable? 78 | # STANDALONE_SUPPRESS_EXE - Build the standalone target but only create object code modules 79 | # and do not build an executable 80 | 81 | MODEL = |>MODEL_NAME<| 82 | MODULES = |>MODEL_MODULES<| 83 | PRODUCT = |>PRODUCT<| 84 | MAKEFILE = |>MAKEFILE_NAME<| 85 | MATLAB_ROOT = |>MATLAB_ROOT<| 86 | ALT_MATLAB_ROOT = |>ALT_MATLAB_ROOT<| 87 | MASTER_ANCHOR_DIR = |>MASTER_ANCHOR_DIR<| 88 | START_DIR = |>START_DIR<| 89 | S_FUNCTIONS_LIB = |>S_FUNCTIONS_LIB<| 90 | NUMST = |>NUMST<| 91 | NCSTATES = |>NCSTATES<| 92 | COMPUTER = |>COMPUTER<| 93 | BUILDARGS = |>BUILDARGS<| 94 | MULTITASKING = |>MULTITASKING<| 95 | INTEGER_CODE = |>INTEGER_CODE<| 96 | MAT_FILE = |>MAT_FILE<| 97 | ALLOCATIONFCN = |>GENERATE_ALLOC_FCN<| 98 | ONESTEPFCN = |>COMBINE_OUTPUT_UPDATE_FCNS<| 99 | TERMFCN = |>INCLUDE_MDL_TERMINATE_FCN<| 100 | ENABLE_SLEXEC_SSBRIDGE = |>ENABLE_SLEXEC_SSBRIDGE<| 101 | MULTI_INSTANCE_CODE = |>MULTI_INSTANCE_CODE<| 102 | CLASSIC_INTERFACE = |>CLASSIC_INTERFACE<| 103 | TGT_FCN_LIB = |>TGT_FCN_LIB<| 104 | MODELREFS = |>MODELREFS<| 105 | GEN_SAMPLE_MAIN = |>GEN_SAMPLE_MAIN<| 106 | TARGET_LANG_EXT = |>TARGET_LANG_EXT<| 107 | SHRLIBTARGET = |>SHRLIBTARGET<| 108 | MAKEFILEBUILDER_TGT = |>MAKEFILEBUILDER_TGT<| 109 | STANDALONE_SUPPRESS_EXE = |>STANDALONE_SUPPRESS_EXE<| 110 | OPTIMIZATION_FLAGS = |>OPTIMIZATION_FLAGS<| 111 | ADDITIONAL_LDFLAGS = |>ADDITIONAL_LDFLAGS<| 112 | INTERLEAVED_COMPLEX_FLAGS = |>INTERLEAVED_COMPLEX_FLAGS<| 113 | DEFINES_CUSTOM = |>DEFINES_CUSTOM<| 114 | SYSTEM_LIBS = |>SYSTEM_LIBS<| 115 | MODEL_HAS_DYNAMICALLY_LOADED_SFCNS = |>MODEL_HAS_DYNAMICALLY_LOADED_SFCNS<| 116 | 117 | # To enable debugging: 118 | # set DEBUG_BUILD = 1 119 | DEBUG_BUILD = 0 120 | 121 | MODULES := $(filter-out rt_main.c, $(MODULES)) 122 | 123 | #--------------------------- Model and reference models ----------------------- 124 | MODELLIB = |>MODELLIB<| 125 | MODELREF_LINK_LIBS = |>MODELREF_LINK_LIBS<| 126 | RELATIVE_PATH_TO_ANCHOR = |>RELATIVE_PATH_TO_ANCHOR<| 127 | # NONE: standalone, SIM: modelref sim, RTW: modelref coder target 128 | MODELREF_TARGET_TYPE = |>MODELREF_TARGET_TYPE<| 129 | ISPROTECTINGMODEL = |>ISPROTECTINGMODEL<| 130 | PROT_CAPIC_SUFFIX = _capi.c 131 | PROT_CAPIO_SUFFIX = _capi_host.o 132 | 133 | 134 | #-- For gcc, link model reference libraries as a group to resolve circular references --- 135 | # (NOTE: Clang does not recognize these switches but it already resolves circular references) 136 | MODELREF_LINK_LIBS_GROUP = |>MODELREF_LINK_LIBS<| 137 | ifeq ($(COMPUTER),GLNXA64) 138 | MODELREF_LINK_LIBS_GROUP = -Wl,--start-group |>MODELREF_LINK_LIBS<| -Wl,--end-group 139 | endif 140 | 141 | #-- In the case when directory name contains space --- 142 | ifneq ($(MATLAB_ROOT),$(ALT_MATLAB_ROOT)) 143 | MATLAB_ROOT := $(ALT_MATLAB_ROOT) 144 | endif 145 | 146 | #--------------------------- Tool Specifications ------------------------------- 147 | 148 | include $(MATLAB_ROOT)/rtw/c/tools/unixtools.mk 149 | 150 | #------------------------------ Include Path ----------------------------------- 151 | 152 | # Additional includes 153 | ADD_INCLUDES = \ 154 | |>START_EXPAND_INCLUDES<| -I|>EXPAND_DIR_NAME<| \ 155 | |>END_EXPAND_INCLUDES<| 156 | 157 | INCLUDES = -I. -I$(RELATIVE_PATH_TO_ANCHOR) $(USER_INCLUDES) \ 158 | $(INSTRUMENT_INCLUDES) $(ADD_INCLUDES) 159 | 160 | #-------------------------------- C Flags -------------------------------------- 161 | 162 | # Optimization Options 163 | ifndef OPT_OPTS 164 | OPT_OPTS = $(DEFAULT_OPT_OPTS) 165 | endif 166 | 167 | # General User Options 168 | ifeq ($(DEBUG_BUILD),0) 169 | DBG_FLAG = 170 | else 171 | # Set OPTS=-g and any additional flags for debugging 172 | DBG_FLAG = -g 173 | LDFLAGS += -g 174 | endif 175 | 176 | LDFLAGS += -Wl,-rpath,"$(MATLAB_ROOT)/bin/$(ARCH)" -L"$(MATLAB_ROOT)/bin/$(ARCH)" 177 | 178 | # Compiler options, etc: 179 | CPP_REQ_DEFINES1 = -DMODEL=$(MODEL) -DNUMST=$(NUMST) -DNCSTATES=$(NCSTATES) \ 180 | -DUNIX -DMAT_FILE=$(MAT_FILE) -DINTEGER_CODE=$(INTEGER_CODE) \ 181 | -DONESTEPFCN=$(ONESTEPFCN) -DTERMFCN=$(TERMFCN) \ 182 | -DHAVESTDIO -DMULTI_INSTANCE_CODE=$(MULTI_INSTANCE_CODE) \ 183 | -DCLASSIC_INTERFACE=$(CLASSIC_INTERFACE) \ 184 | -DALLOCATIONFCN=$(ALLOCATIONFCN) 185 | 186 | ifneq ($(ENABLE_SLEXEC_SSBRIDGE), 0) 187 | ifeq ($(MODELREF_TARGET_TYPE),SIM) 188 | CPP_REQ_DEFINES1 += -DENABLE_SLEXEC_SSBRIDGE=$(ENABLE_SLEXEC_SSBRIDGE) 189 | endif 190 | endif 191 | 192 | CPP_REQ_DEFINES = $(CPP_REQ_DEFINES1) 193 | ifeq ($(MODELREF_TARGET_TYPE),SIM) 194 | CPP_REQ_DEFINES += -DMDL_REF_SIM_TGT=1 195 | else 196 | CPP_REQ_DEFINES += -DMT=$(MULTITASKING) 197 | endif 198 | 199 | 200 | CPP_REQ_DEFINES += -DMODEL_HAS_DYNAMICALLY_LOADED_SFCNS=$(MODEL_HAS_DYNAMICALLY_LOADED_SFCNS) 201 | 202 | ifneq ($(OPTIMIZATION_FLAGS),) 203 | CC_OPTS = $(OPTS) $(OPTIMIZATION_FLAGS) 204 | else 205 | CC_OPTS = $(OPT_OPTS) $(OPTS) 206 | endif 207 | 208 | CFLAGS = $(ANSI_OPTS) $(DBG_FLAG) $(CC_OPTS) $(DEFINES_CUSTOM) $(CPP_REQ_DEFINES) $(INCLUDES) 209 | CPPFLAGS = $(CPP_ANSI_OPTS) $(DBG_FLAG) $(CPP_OPTS) $(CC_OPTS) $(CPP_REQ_DEFINES) $(INCLUDES) 210 | 211 | #-------------------------- Additional Libraries ------------------------------ 212 | 213 | SYSTEM_LIBS += -lm -lrt -lpthread 214 | 215 | LIBS = 216 | |>START_PRECOMP_LIBRARIES<| 217 | ifeq ($(OPT_OPTS),$(DEFAULT_OPT_OPTS)) 218 | ifeq ($(INTEGER_CODE),0) 219 | ifeq ($(MODELREF_TARGET_TYPE),SIM) 220 | LIBS += |>EXPAND_LIBRARY_LOCATION<|/|>EXPAND_LIBRARY_NAME<|_rtwsfcn.a 221 | else 222 | LIBS += |>EXPAND_LIBRARY_LOCATION<|/|>EXPAND_LIBRARY_NAME<|_ert.a 223 | endif 224 | else 225 | LIBS += |>EXPAND_LIBRARY_LOCATION<|/|>EXPAND_LIBRARY_NAME<|_int_ert.a 226 | endif 227 | else 228 | LIBS += |>EXPAND_LIBRARY_NAME<|.a 229 | endif 230 | |>END_PRECOMP_LIBRARIES<| |>START_EXPAND_LIBRARIES<| 231 | LIBS += |>EXPAND_LIBRARY_NAME<|.a |>END_EXPAND_LIBRARIES<| 232 | LIBS += $(S_FUNCTIONS_LIB) $(INSTRUMENT_LIBS) 233 | 234 | #----------------------------- Source Files ------------------------------------ 235 | ADD_SRCS = 236 | 237 | SRCS = $(ADD_SRCS) $(MODULES) 238 | 239 | USER_SRCS = 240 | 241 | USER_OBJS = $(addsuffix .o, $(basename $(USER_SRCS))) 242 | LOCAL_USER_OBJS = $(notdir $(USER_OBJS)) 243 | 244 | OBJS = $(addsuffix .o, $(basename $(SRCS))) $(USER_OBJS) 245 | PROT_CAPIC = $(addsuffix $(PROT_CAPIC_SUFFIX), $(MODEL)) 246 | PROT_CAPIO = $(addsuffix $(PROT_CAPIO_SUFFIX), $(MODEL)) 247 | LINK_OBJS = $(addsuffix .o, $(basename $(SRCS))) $(LOCAL_USER_OBJS) 248 | 249 | ADDITIONAL_LDFLAGS += $(ARCH_SPECIFIC_LDFLAGS) 250 | 251 | #--------------------------------- Rules --------------------------------------- 252 | BIN_SETTING = $(LD) $(LDFLAGS) $(ADDITIONAL_LDFLAGS) -o $(PRODUCT) 253 | BUILD_PRODUCT_TYPE = "executable" 254 | ifeq ($(MODELREF_TARGET_TYPE),NONE) 255 | ifeq ($(SHRLIBTARGET), 1) 256 | BIN_SETTING = $(LD) $(SHRLIBLDFLAGS)$(MODEL).def -o $(PRODUCT) 257 | BUILD_PRODUCT_TYPE = "shared object" 258 | ifeq ($(GEN_SAMPLE_MAIN), 1) 259 | PRODUCT := $(notdir $(PRODUCT)) 260 | $(MODEL) : $(PRODUCT) ert_main.o 261 | $(LD) $(LDFLAGS) $(ADDITIONAL_LDFLAGS) -o $(MODEL) ert_main.o $(PRODUCT) $(SYSTEM_LIBS) 262 | @mv $(PRODUCT) $(RELATIVE_PATH_TO_ANCHOR)/ 263 | @mv $(MODEL) $(RELATIVE_PATH_TO_ANCHOR)/ 264 | @echo "### Created executable: $@" 265 | endif 266 | endif 267 | ifeq ($(MAKEFILEBUILDER_TGT), 1) 268 | $(PRODUCT) : $(OBJS) $(LIBS) $(MODELLIB) $(MODELREF_LINK_LIBS) 269 | $(BIN_SETTING) $(LINK_OBJS) $(MODELLIB) $(MODELREF_LINK_LIBS_GROUP) $(LIBS) $(SYSTEM_LIBS) 270 | @echo "### Created executable: $@" 271 | else 272 | ifeq ($(STANDALONE_SUPPRESS_EXE), 1) 273 | .PHONY: $(PRODUCT) 274 | $(PRODUCT) : $(OBJS) $(LIBS) 275 | @echo "### Created object modules: $@" 276 | else 277 | $(PRODUCT) : $(OBJS) $(LIBS) $(MODELREF_LINK_LIBS) 278 | $(BIN_SETTING) $(LINK_OBJS) $(MODELREF_LINK_LIBS_GROUP) $(LIBS) $(SYSTEM_LIBS) 279 | @echo "### Created $(BUILD_PRODUCT_TYPE): $@" 280 | endif 281 | endif 282 | else 283 | # Protected model simulation target 284 | ifeq ($(MODELREF_TARGET_TYPE),SIM) 285 | ifeq ($(ISPROTECTINGMODEL),PROTECTING) 286 | all : $(PRODUCT) $(PROT_CAPIO) 287 | $(PROT_CAPIO) : $(PROT_CAPIC) 288 | $(CC) -c -o $(PROT_CAPIO) $(CFLAGS) $(GCC_WALL_FLAG) -DHOST_CAPI_BUILD $(PROT_CAPIC) 289 | endif 290 | endif 291 | $(PRODUCT) : $(OBJS) 292 | @rm -f $(MODELLIB) 293 | $(AR) ruvs $(MODELLIB) $(LINK_OBJS) 294 | @echo "### Created $(MODELLIB)" 295 | @echo "### Created library: $@" 296 | endif 297 | 298 | #-------------------------- Support for building modules ---------------------- 299 | 300 | %.o : %.c 301 | $(CC) -c $(CFLAGS) $(GCC_WALL_FLAG) "$<" 302 | 303 | %.o : %.cpp 304 | $(CPP) -c $(CPPFLAGS) $(GCC_WALL_FLAG) "$<" 305 | 306 | %.o : $(RELATIVE_PATH_TO_ANCHOR)/%.c 307 | $(CC) -c $(CFLAGS) $(GCC_WALL_FLAG) "$<" 308 | 309 | %.o : $(RELATIVE_PATH_TO_ANCHOR)/%.cpp 310 | $(CPP) -c $(CPPFLAGS) $(GCC_WALL_FLAG) "$<" 311 | 312 | |>START_EXPAND_RULES<|%.o : |>EXPAND_DIR_NAME<|/%.c 313 | $(CC) -c $(CFLAGS) $(GCC_WALL_FLAG_MAX) "$<" 314 | 315 | |>END_EXPAND_RULES<| 316 | 317 | |>START_EXPAND_RULES<|%.o : |>EXPAND_DIR_NAME<|/%.cpp 318 | $(CPP) -c $(CPPFLAGS) $(GCC_WALL_FLAG_MAX) "$<" 319 | 320 | |>END_EXPAND_RULES<| 321 | 322 | #------------------------------- Libraries ------------------------------------- 323 | 324 | |>START_EXPAND_LIBRARIES<|MODULES_|>EXPAND_LIBRARY_NAME<| = \ 325 | |>START_EXPAND_MODULES<| |>EXPAND_MODULE_NAME<|.o \ 326 | |>END_EXPAND_MODULES<| 327 | 328 | |>EXPAND_LIBRARY_NAME<|.a : $(MAKEFILE) rtw_proj.tmw $(MODULES_|>EXPAND_LIBRARY_NAME<|) 329 | @echo "### Creating $@ " 330 | $(AR) rs $@ $(MODULES_|>EXPAND_LIBRARY_NAME<|) 331 | @echo "### $@ Created " 332 | 333 | |>END_EXPAND_LIBRARIES<| 334 | 335 | |>START_PRECOMP_LIBRARIES<|MODULES_|>EXPAND_LIBRARY_NAME<| = \ 336 | |>START_EXPAND_MODULES<| |>EXPAND_MODULE_NAME<|.o \ 337 | |>END_EXPAND_MODULES<| 338 | 339 | |>EXPAND_LIBRARY_NAME<|.a : $(MAKEFILE) rtw_proj.tmw $(MODULES_|>EXPAND_LIBRARY_NAME<|) 340 | @echo "### Creating $@ " 341 | $(AR) rs $@ $(MODULES_|>EXPAND_LIBRARY_NAME<|) 342 | @echo "### $@ Created " 343 | 344 | |>END_PRECOMP_LIBRARIES<| 345 | 346 | #----------------------------- Dependencies ------------------------------------ 347 | 348 | $(OBJS) : $(MAKEFILE) rtw_proj.tmw 349 | 350 | -------------------------------------------------------------------------------- /ert_linux/ert_nuttx.tmf: -------------------------------------------------------------------------------- 1 | # Copyright 1994-2018 The MathWorks, Inc. 2 | # Copyright 2020 Pavel Pisa 3 | # 4 | # File : ert_nuttx.tmf 5 | # 6 | # Abstract: 7 | # Template makefile for building a UNIX-based stand-alone embedded 8 | # real-time version of Simulink model using generated C code. 9 | # 10 | # This makefile attempts to conform to the guidelines specified in the 11 | # IEEE Std 1003.2-1992 (POSIX) standard. It is designed to be used 12 | # with GNU Make which is located in matlabroot/rtw/bin. 13 | # 14 | # Note that this template is automatically customized by the build 15 | # procedure to create ".mk" 16 | # 17 | # The following defines can be used to modify the behavior of the 18 | # build: 19 | # NUTTX_EXPORT - NuttX OS build export directory. 20 | # OPT_OPTS - Optimization options. Default is -O. 21 | # CPP_OPTS - C++ compiler options. 22 | # OPTS - User specific compile options. 23 | # USER_SRCS - Additional user sources, such as files needed by 24 | # S-functions. 25 | # USER_INCLUDES - Additional include paths 26 | # (i.e. USER_INCLUDES="-Iwhere-ever -Iwhere-ever2") 27 | # 28 | # To enable debugging: 29 | # set DEBUG_BUILD = 1 below, which will trigger OPTS=-g and 30 | # LDFLAGS += -g (may vary with compiler version, see compiler doc) 31 | # 32 | # This template makefile is designed to be used with a system target 33 | # file that contains 'rtwgensettings.BuildDirSuffix' see ert.tlc 34 | 35 | 36 | #------------------------ Macros read by make_rtw ------------------------------ 37 | # 38 | # The following macros are read by the build procedure: 39 | # 40 | # MAKECMD - This is the command used to invoke the make utility 41 | # HOST - What platform this template makefile is targeted for 42 | # (i.e. PC or UNIX) 43 | # BUILD - Invoke make from the build procedure (yes/no)? 44 | # SYS_TARGET_FILE - Name of system target file. 45 | 46 | MAKECMD = |>MATLAB_BIN<|/|>ARCH<|/gmake 47 | HOST = UNIX 48 | BUILD = yes 49 | SYS_TARGET_FILE = any 50 | 51 | # Opt in to simplified format by specifying compatible Toolchain 52 | TOOLCHAIN_NAME = ["Clang v3.1 | gmake (64-bit Mac)", \ 53 | "GNU gcc/g++ | gmake (64-bit Linux)"] 54 | 55 | #---------------------- Tokens expanded by make_rtw ---------------------------- 56 | # 57 | # The following tokens, when wrapped with "|>" and "<|" are expanded by the 58 | # build procedure. 59 | # 60 | # MODEL_NAME - Name of the Simulink block diagram 61 | # MODEL_MODULES - Any additional generated source modules 62 | # MAKEFILE_NAME - Name of makefile created from template makefile .mk 63 | # MATLAB_ROOT - Path to where MATLAB is installed. 64 | # S_FUNCTIONS_LIB - List of S-functions libraries to link. 65 | # NUMST - Number of sample times 66 | # NCSTATES - Number of continuous states 67 | # COMPUTER - Computer type. See the MATLAB computer command. 68 | # BUILDARGS - Options passed in at the command line. 69 | # MULTITASKING - yes (1) or no (0): Is solver mode multitasking 70 | # INTEGER_CODE - yes (1) or no (0): Is generated code purely integer 71 | # MAT_FILE - yes (1) or no (0): Should mat file logging be done, 72 | # if 0, the generated code runs indefinitely 73 | # MULTI_INSTANCE_CODE - Is the generated code multi instantiable (1/0)? 74 | # MODELREFS - List of referenced models 75 | # TGT_FCN_LIB - Target function (code replacement) library to use 76 | # SHRLIBTARGET - Is this build intended for generation of a shared library instead 77 | # of executable (1/0)? 78 | # MAKEFILEBUILDER_TGT - Is this build performed by the MakefileBuilder class 79 | # e.g. to create a PIL executable? 80 | # STANDALONE_SUPPRESS_EXE - Build the standalone target but only create object code modules 81 | # and do not build an executable 82 | 83 | MODEL = |>MODEL_NAME<| 84 | MODULES = |>MODEL_MODULES<| 85 | PRODUCT = |>PRODUCT<| 86 | MAKEFILE = |>MAKEFILE_NAME<| 87 | MATLAB_ROOT = |>MATLAB_ROOT<| 88 | ALT_MATLAB_ROOT = |>ALT_MATLAB_ROOT<| 89 | MASTER_ANCHOR_DIR = |>MASTER_ANCHOR_DIR<| 90 | START_DIR = |>START_DIR<| 91 | S_FUNCTIONS_LIB = |>S_FUNCTIONS_LIB<| 92 | NUMST = |>NUMST<| 93 | NCSTATES = |>NCSTATES<| 94 | COMPUTER = |>COMPUTER<| 95 | BUILDARGS = |>BUILDARGS<| 96 | MULTITASKING = |>MULTITASKING<| 97 | INTEGER_CODE = |>INTEGER_CODE<| 98 | MAT_FILE = |>MAT_FILE<| 99 | ALLOCATIONFCN = |>GENERATE_ALLOC_FCN<| 100 | ONESTEPFCN = |>COMBINE_OUTPUT_UPDATE_FCNS<| 101 | TERMFCN = |>INCLUDE_MDL_TERMINATE_FCN<| 102 | ENABLE_SLEXEC_SSBRIDGE = |>ENABLE_SLEXEC_SSBRIDGE<| 103 | MULTI_INSTANCE_CODE = |>MULTI_INSTANCE_CODE<| 104 | CLASSIC_INTERFACE = |>CLASSIC_INTERFACE<| 105 | TGT_FCN_LIB = |>TGT_FCN_LIB<| 106 | MODELREFS = |>MODELREFS<| 107 | GEN_SAMPLE_MAIN = |>GEN_SAMPLE_MAIN<| 108 | TARGET_LANG_EXT = |>TARGET_LANG_EXT<| 109 | SHRLIBTARGET = |>SHRLIBTARGET<| 110 | MAKEFILEBUILDER_TGT = |>MAKEFILEBUILDER_TGT<| 111 | STANDALONE_SUPPRESS_EXE = |>STANDALONE_SUPPRESS_EXE<| 112 | #OPTIMIZATION_FLAGS = |>OPTIMIZATION_FLAGS<| 113 | ADDITIONAL_LDFLAGS = |>ADDITIONAL_LDFLAGS<| 114 | INTERLEAVED_COMPLEX_FLAGS = |>INTERLEAVED_COMPLEX_FLAGS<| 115 | DEFINES_CUSTOM = |>DEFINES_CUSTOM<| 116 | SYSTEM_LIBS = |>SYSTEM_LIBS<| 117 | MODEL_HAS_DYNAMICALLY_LOADED_SFCNS = |>MODEL_HAS_DYNAMICALLY_LOADED_SFCNS<| 118 | 119 | # To enable debugging: 120 | # set DEBUG_BUILD = 1 121 | DEBUG_BUILD = 0 122 | 123 | MODULES := $(filter-out rt_main.c, $(MODULES)) 124 | 125 | #--------------------------- Model and reference models ----------------------- 126 | MODELLIB = |>MODELLIB<| 127 | MODELREF_LINK_LIBS = |>MODELREF_LINK_LIBS<| 128 | RELATIVE_PATH_TO_ANCHOR = |>RELATIVE_PATH_TO_ANCHOR<| 129 | # NONE: standalone, SIM: modelref sim, RTW: modelref coder target 130 | MODELREF_TARGET_TYPE = |>MODELREF_TARGET_TYPE<| 131 | ISPROTECTINGMODEL = |>ISPROTECTINGMODEL<| 132 | PROT_CAPIC_SUFFIX = _capi.c 133 | PROT_CAPIO_SUFFIX = _capi_host.o 134 | 135 | #-- In the case when directory name contains space --- 136 | ifneq ($(MATLAB_ROOT),$(ALT_MATLAB_ROOT)) 137 | MATLAB_ROOT := $(ALT_MATLAB_ROOT) 138 | endif 139 | 140 | #--------------------------- Tool Specifications ------------------------------- 141 | 142 | #include $(MATLAB_ROOT)/rtw/c/tools/unixtools.mk 143 | 144 | #------------------------------ NuttX build specific --------------------------- 145 | 146 | ifndef NUTTX_EXPORT 147 | $(warning Specify NUTTX_EXPORT) 148 | $(warning make_rtw NUTTX_EXPORT=/path/to/nuttx-export) 149 | $(error NUTTX_EXPORT not defined, cannot continue) 150 | endif 151 | 152 | include $(NUTTX_EXPORT)/scripts/Make.defs 153 | 154 | NUTTX_INCLUDES = -isystem $(NUTTX_EXPORT)/include 155 | 156 | ifneq ($(filter -Wl%, $(NXFLATLDFLAGS1)$(NXFLATLDFLAGS2)$(LDSTARTGROUP)$(LDFLAGS)),) 157 | GCC_LD_OPTION = -Wl, 158 | endif 159 | 160 | ifeq ($(LDSTARTGROUP),) 161 | LDSTARTGROUP = $(GCC_LD_OPTION)--start-group 162 | LDENDGROUP = $(GCC_LD_OPTION)--end-group 163 | endif 164 | 165 | SYSTEM_LIBS += $(LDSTARTGROUP) $(LDLIBS) $(EXTRA_LIBS) $(LDENDGROUP) 166 | ELF_MODULE_LIBS = $(LDSTARTGROUP) $(EXTRA_LIBS) $(LDENDGROUP) 167 | 168 | LDFLAGS += -L $(NUTTX_EXPORT)/libs 169 | 170 | ifneq ($(shell $(CC) --target-help | grep -e '-mlong-calls\b'),) 171 | TARGET_ARCH_LONG_CALLS = -mlong-calls 172 | endif 173 | 174 | TARGET_ARCH_FLAGS ?= $(ARCHCFLAGS) $(ARCHCPUFLAGS) \ 175 | $(TARGET_ARCH_LONG_CALLS) -fno-common -DWITHOUT_MLOCK 176 | 177 | DEFAULT_OPT_OPTS ?= $(ARCHOPTIMIZATION) 178 | 179 | LD_SCRIPTS = $(LDNAME:%=$(NUTTX_EXPORT)/scripts/%) 180 | 181 | LDFLAGS_LD_SCRIPTS += $(LD_SCRIPTS:%=-T %) 182 | 183 | LDFLAGS_LD_SCRIPTS += --entry=__start 184 | 185 | ELF_FILE_LDSCRIPT ?= $(wildcard $(NUTTX_EXPORT)/scripts/gnu-elf.ld) 186 | 187 | #--------------------------- Model and reference models - continue ------------ 188 | 189 | #-- For gcc, link model reference libraries as a group to resolve circular references --- 190 | # (NOTE: Clang does not recognize these switches but it already resolves circular references) 191 | MODELREF_LINK_LIBS_GROUP = |>MODELREF_LINK_LIBS<| 192 | ifeq ($(COMPUTER),GLNXA64) 193 | MODELREF_LINK_LIBS_GROUP = $(LDSTARTGROUP) |>MODELREF_LINK_LIBS<| $(LDENDGROUP) 194 | endif 195 | 196 | #------------------------------ Include Path ----------------------------------- 197 | 198 | # Additional includes 199 | ADD_INCLUDES = \ 200 | |>START_EXPAND_INCLUDES<| -I|>EXPAND_DIR_NAME<| \ 201 | |>END_EXPAND_INCLUDES<| 202 | 203 | INCLUDES = -I. -I$(RELATIVE_PATH_TO_ANCHOR) $(USER_INCLUDES) \ 204 | $(INSTRUMENT_INCLUDES) $(ADD_INCLUDES) \ 205 | $(NUTTX_INCLUDES) 206 | 207 | #-------------------------------- C Flags -------------------------------------- 208 | 209 | # Optimization Options 210 | ifndef OPT_OPTS 211 | OPT_OPTS = $(DEFAULT_OPT_OPTS) 212 | endif 213 | 214 | # General User Options 215 | ifeq ($(DEBUG_BUILD),0) 216 | DBG_FLAG = 217 | else 218 | # Set OPTS=-g and any additional flags for debugging 219 | DBG_FLAG = -g 220 | LDFLAGS += -g 221 | endif 222 | 223 | LDFLAGS += 224 | 225 | # Compiler options, etc: 226 | CPP_REQ_DEFINES1 = -DMODEL=$(MODEL) -DNUMST=$(NUMST) -DNCSTATES=$(NCSTATES) \ 227 | -DUNIX -DMAT_FILE=$(MAT_FILE) -DINTEGER_CODE=$(INTEGER_CODE) \ 228 | -DONESTEPFCN=$(ONESTEPFCN) -DTERMFCN=$(TERMFCN) \ 229 | -DHAVESTDIO -DMULTI_INSTANCE_CODE=$(MULTI_INSTANCE_CODE) \ 230 | -DCLASSIC_INTERFACE=$(CLASSIC_INTERFACE) \ 231 | -DALLOCATIONFCN=$(ALLOCATIONFCN) 232 | 233 | ifneq ($(ENABLE_SLEXEC_SSBRIDGE), 0) 234 | ifeq ($(MODELREF_TARGET_TYPE),SIM) 235 | CPP_REQ_DEFINES1 += -DENABLE_SLEXEC_SSBRIDGE=$(ENABLE_SLEXEC_SSBRIDGE) 236 | endif 237 | endif 238 | 239 | CPP_REQ_DEFINES = $(CPP_REQ_DEFINES1) 240 | ifeq ($(MODELREF_TARGET_TYPE),SIM) 241 | CPP_REQ_DEFINES += -DMDL_REF_SIM_TGT=1 242 | else 243 | CPP_REQ_DEFINES += -DMT=$(MULTITASKING) 244 | endif 245 | 246 | 247 | CPP_REQ_DEFINES += -DMODEL_HAS_DYNAMICALLY_LOADED_SFCNS=$(MODEL_HAS_DYNAMICALLY_LOADED_SFCNS) 248 | 249 | ifneq ($(OPTIMIZATION_FLAGS),) 250 | CC_OPTS = $(OPTS) $(OPTIMIZATION_FLAGS) 251 | else 252 | CC_OPTS = $(OPT_OPTS) $(OPTS) 253 | endif 254 | 255 | CFLAGS = $(TARGET_ARCH_FLAGS) $(ARCHWARNINGS) $(ANSI_OPTS) $(DBG_FLAG) $(CC_OPTS) $(DEFINES_CUSTOM) $(CPP_REQ_DEFINES) $(INCLUDES) 256 | 257 | CPPFLAGS = $(TARGET_ARCH_FLAGS) $(ARCHCXXFLAGS) $(ARCHWARNINGSXX) $(CPP_ANSI_OPTS) $(DBG_FLAG) $(CPP_OPTS) $(CC_OPTS) $(CPP_REQ_DEFINES) $(INCLUDES) 258 | 259 | #-------------------------- Additional Libraries ------------------------------ 260 | 261 | LIBS = 262 | |>START_PRECOMP_LIBRARIES<| 263 | ifeq ($(OPT_OPTS),$(DEFAULT_OPT_OPTS)) 264 | ifeq ($(INTEGER_CODE),0) 265 | ifeq ($(MODELREF_TARGET_TYPE),SIM) 266 | LIBS += |>EXPAND_LIBRARY_LOCATION<|/|>EXPAND_LIBRARY_NAME<|_rtwsfcn.a 267 | else 268 | LIBS += |>EXPAND_LIBRARY_LOCATION<|/|>EXPAND_LIBRARY_NAME<|_ert.a 269 | endif 270 | else 271 | LIBS += |>EXPAND_LIBRARY_LOCATION<|/|>EXPAND_LIBRARY_NAME<|_int_ert.a 272 | endif 273 | else 274 | LIBS += |>EXPAND_LIBRARY_NAME<|.a 275 | endif 276 | |>END_PRECOMP_LIBRARIES<| |>START_EXPAND_LIBRARIES<| 277 | LIBS += |>EXPAND_LIBRARY_NAME<|.a |>END_EXPAND_LIBRARIES<| 278 | LIBS += $(S_FUNCTIONS_LIB) $(INSTRUMENT_LIBS) 279 | 280 | #----------------------------- Source Files ------------------------------------ 281 | ADD_SRCS = 282 | 283 | SRCS = $(ADD_SRCS) $(MODULES) 284 | 285 | USER_SRCS = 286 | 287 | USER_OBJS = $(addsuffix .o, $(basename $(USER_SRCS))) 288 | LOCAL_USER_OBJS = $(notdir $(USER_OBJS)) 289 | 290 | OBJS = $(addsuffix .o, $(basename $(SRCS))) $(USER_OBJS) 291 | PROT_CAPIC = $(addsuffix $(PROT_CAPIC_SUFFIX), $(MODEL)) 292 | PROT_CAPIO = $(addsuffix $(PROT_CAPIO_SUFFIX), $(MODEL)) 293 | LINK_OBJS = $(addsuffix .o, $(basename $(SRCS))) $(LOCAL_USER_OBJS) 294 | 295 | ADDITIONAL_LDFLAGS += $(ARCH_SPECIFIC_LDFLAGS) 296 | 297 | #--------------------------------- Rules --------------------------------------- 298 | BIN_SETTING = $(LD) $(LDFLAGS) $(LDFLAGS_LD_SCRIPTS) \ 299 | $(ADDITIONAL_LDFLAGS) -o $(PRODUCT) $(HEAD_OBJ:%=$(NUTTX_EXPORT)/startup/%) 300 | BUILD_PRODUCT_TYPE = "executable" 301 | ifeq ($(MODELREF_TARGET_TYPE),NONE) 302 | ifeq ($(SHRLIBTARGET), 1) 303 | BIN_SETTING = $(LD) $(SHRLIBLDFLAGS)$(MODEL).def -o $(PRODUCT) 304 | BUILD_PRODUCT_TYPE = "shared object" 305 | ifeq ($(GEN_SAMPLE_MAIN), 1) 306 | PRODUCT := $(notdir $(PRODUCT)) 307 | $(MODEL) : $(PRODUCT) ert_main.o 308 | $(LD) $(LDFLAGS) $(ADDITIONAL_LDFLAGS) -o $(MODEL) ert_main.o $(PRODUCT) $(SYSTEM_LIBS) 309 | @mv $(PRODUCT) $(RELATIVE_PATH_TO_ANCHOR)/ 310 | @mv $(MODEL) $(RELATIVE_PATH_TO_ANCHOR)/ 311 | @echo "### Created SHRLIBTARGET executable: $@" 312 | endif 313 | endif 314 | ifeq ($(MAKEFILEBUILDER_TGT), 1) 315 | $(PRODUCT) : $(OBJS) $(LIBS) $(MODELLIB) $(MODELREF_LINK_LIBS) 316 | $(BIN_SETTING) $(LINK_OBJS) $(MODELLIB) $(MODELREF_LINK_LIBS_GROUP) $(LIBS) $(SYSTEM_LIBS) 317 | @echo "### Created MAKEFILEBUILDER_TGT executable: $@" 318 | else 319 | ifeq ($(STANDALONE_SUPPRESS_EXE), 1) 320 | .PHONY: $(PRODUCT) $(PRODUCT).elf 321 | $(PRODUCT) : $(OBJS) $(LIBS) 322 | @echo "### Created object modules: $@" 323 | else 324 | $(PRODUCT) : $(OBJS) $(LIBS) $(MODELREF_LINK_LIBS) 325 | [ ! -e $(ELF_FILE_LDSCRIPT) ] || \ 326 | $(LD) $(LDFLAGS) $(ADDITIONAL_LDFLAGS) -o $(PRODUCT).elf \ 327 | -r -e main -T $(ELF_FILE_LDSCRIPT) \ 328 | $(GCC_LD_OPTION)-Map $(GCC_LD_OPTION)$(PRODUCT).elf.map \ 329 | $(LINK_OBJS) $(MODELREF_LINK_LIBS_GROUP) $(LIBS) $(ELF_MODULE_LIBS) 330 | $(BIN_SETTING) $(LINK_OBJS) $(MODELREF_LINK_LIBS_GROUP) $(LIBS) $(SYSTEM_LIBS) 331 | @echo "### Created $(BUILD_PRODUCT_TYPE): $@" 332 | endif 333 | endif 334 | else 335 | # Protected model simulation target 336 | ifeq ($(MODELREF_TARGET_TYPE),SIM) 337 | ifeq ($(ISPROTECTINGMODEL),PROTECTING) 338 | all : $(PRODUCT) $(PROT_CAPIO) 339 | $(PROT_CAPIO) : $(PROT_CAPIC) 340 | $(CC) -c -o $(PROT_CAPIO) $(CFLAGS) $(GCC_WALL_FLAG) -DHOST_CAPI_BUILD $(PROT_CAPIC) 341 | endif 342 | endif 343 | $(PRODUCT) : $(OBJS) 344 | @rm -f $(MODELLIB) 345 | $(AR) ruvs $(MODELLIB) $(LINK_OBJS) 346 | @echo "### Created $(MODELLIB)" 347 | @echo "### Created library: $@" 348 | endif 349 | 350 | #-------------------------- Support for building modules ---------------------- 351 | 352 | %.o : %.c 353 | $(CC) -c $(CFLAGS) $(GCC_WALL_FLAG) "$<" 354 | 355 | %.o : %.cpp 356 | $(CPP) -c $(CPPFLAGS) $(GCC_WALL_FLAG) "$<" 357 | 358 | %.o : $(RELATIVE_PATH_TO_ANCHOR)/%.c 359 | $(CC) -c $(CFLAGS) $(GCC_WALL_FLAG) "$<" 360 | 361 | %.o : $(RELATIVE_PATH_TO_ANCHOR)/%.cpp 362 | $(CPP) -c $(CPPFLAGS) $(GCC_WALL_FLAG) "$<" 363 | 364 | |>START_EXPAND_RULES<|%.o : |>EXPAND_DIR_NAME<|/%.c 365 | $(CC) -c $(CFLAGS) $(GCC_WALL_FLAG_MAX) "$<" 366 | 367 | |>END_EXPAND_RULES<| 368 | 369 | |>START_EXPAND_RULES<|%.o : |>EXPAND_DIR_NAME<|/%.cpp 370 | $(CPP) -c $(CPPFLAGS) $(GCC_WALL_FLAG_MAX) "$<" 371 | 372 | |>END_EXPAND_RULES<| 373 | 374 | #------------------------------- Libraries ------------------------------------- 375 | 376 | |>START_EXPAND_LIBRARIES<|MODULES_|>EXPAND_LIBRARY_NAME<| = \ 377 | |>START_EXPAND_MODULES<| |>EXPAND_MODULE_NAME<|.o \ 378 | |>END_EXPAND_MODULES<| 379 | 380 | |>EXPAND_LIBRARY_NAME<|.a : $(MAKEFILE) rtw_proj.tmw $(MODULES_|>EXPAND_LIBRARY_NAME<|) 381 | @echo "### Creating $@ " 382 | $(AR) rs $@ $(MODULES_|>EXPAND_LIBRARY_NAME<|) 383 | @echo "### $@ Created " 384 | 385 | |>END_EXPAND_LIBRARIES<| 386 | 387 | |>START_PRECOMP_LIBRARIES<|MODULES_|>EXPAND_LIBRARY_NAME<| = \ 388 | |>START_EXPAND_MODULES<| |>EXPAND_MODULE_NAME<|.o \ 389 | |>END_EXPAND_MODULES<| 390 | 391 | |>EXPAND_LIBRARY_NAME<|.a : $(MAKEFILE) rtw_proj.tmw $(MODULES_|>EXPAND_LIBRARY_NAME<|) 392 | @echo "### Creating $@ " 393 | $(AR) rs $@ $(MODULES_|>EXPAND_LIBRARY_NAME<|) 394 | @echo "### $@ Created " 395 | 396 | |>END_PRECOMP_LIBRARIES<| 397 | 398 | #----------------------------- Dependencies ------------------------------------ 399 | 400 | $(OBJS) : $(MAKEFILE) rtw_proj.tmw 401 | --------------------------------------------------------------------------------