Port Legacy Code
Find the States
If a variable-step solver is being used, it is critical that all continuous states
are identified in the code and put into the C S-function state vector for
integration instead of being integrated by the Fortran® code. Likewise, all derivative calculations must be made available
separately to be called from the mdlDerivatives
method in the C
S-function. Without these steps, any Fortran code with continuous states will not be compatible with variable-step
solvers if the S-function is registered as a continuous block with continuous
states.
Telltale signs of implicit advancement are incremented variables such as
M=M+1
or X=X+0.05
. If the code has many of
these constructs and you determine that it is impractical to recode the source so as
not to “ratchet forward,” you might need to try another approach using
fixed-step solvers.
If it is impractical to find all the implicit states and to separate out the
derivative calculations for the Simulink® engine, another approach can be used, but you are limited to using
fixed-step solvers. The technique here is to call the Fortran code from the mdlUpdate
method so the Fortran code is only executed once per major simulation integration step. Any
block outputs must be cached in a work vector so that mdlOutputs
can be called as often as needed and output the values from the work vector instead
of calling the Fortran routine again (causing it to inadvertently advance time). See
sfuntmpl_gate_fortran.c
for an example that uses DWork
vectors. See How to Use DWork Vectors for details on
allocating data-typed work vectors.
Sample Times
If the Fortran code has an implicit step size in its algorithm, coefficients, etc.,
ensure that you register the proper discrete sample time in the C S-function
mdlInitializeSampleTimes
method and only change the block's
output values from the mdlUpdate
method.
Store Data
If you plan to have multiple copies of this S-function used in one Simulink model, you need to allocate storage for each copy of the S-function in the model. The recommended approach is to use DWork vectors (see DWork Vector Basics).
If you plan to have only one copy of the S-function in the model, DWork vectors
still provide the most advanced method for storing data. However, another
alternative is to allocate a block of memory using the malloc
command and store the pointer to that memory in a PWork vector (see Elementary Work Vectors). In this case, you must remember to deallocate
the memory using the free
command in the S-function
mdlTerminate
method.
Use Flints if Needed
Use flints (floating-point ints
) to keep track of time. Flints
(for IEEE-754 floating-point numerics) have the useful property of not accumulating
roundoff error when adding and subtracting flints. Using flint variables in
DOUBLE PRECISION
storage (with integer values) avoids
roundoff error accumulation that would accumulate when floating-point numbers are
added together thousands of times.
DOUBLE PRECISION F : : F = F + 1.0 TIME = 0.003 * F
This technique avoids a common pitfall in simulations.
Considerations for Real Time
Since very few Fortran applications are used in a real-time environment, it is common to come across simulation code that is incompatible with a real-time environment. Common failures include unbounded (or large) iterations and sporadic but time-intensive side calculations. You must deal with these directly if you expect to run in real time.
Conversely, it is still perfectly good practice to have iterative or sporadic calculations if the generated code is not being used for a real-time application.