📄 sf_rx.c
字号:
/* * * Filename: dspSFunction.c * * Module: * * Description: Discrete-time S-function template. This is a simple * S-function using typical options for a DSP (discrete-time) * algorithm implementation. All it does is to multiply * each element of the input vector by 2. * * Most of the housekeeping is done using standard macros * defined in the Mathworks header files. These act on the * Block's SimStruct data structure S, which holds the block's * parameters and other option settings. * * The standard format for macros is along the lines of - * * ssSetInputPortWidth(S,0,1); * * - which sets input port 0 to a width of 1. Input and * output ports are always referenced using 0-based indexes. * * Compilation * notes: Compile using the command: mex <filename> at the MATLAB * command line. The mex utility will produce an executable * .dll file (for PC platforms), which must be located in a * directory on the MATLAB path at simulation runtime. Note * that mex will place the .dll into the current MATLAB working * directory at compile time, which may not be the directory * containing the original source file! You may first need to * configure the mex utility using mex -setup at the MATLAB * command line. * * Design ref: * * Author: Chris Thorpe, Cambridge Control Ltd * * Version: 1.1 * * Date: * * *//* The name of the S-function must be #defined the same as the filename */#define S_FUNCTION_NAME sf_rx/* This sets the format of the S-function: always use S_FUNCTION_LEVEL_2 */#define S_FUNCTION_LEVEL 2/* The simstruc.h header file is always required */#include "simstruc.h"/* -----DIRECTIVES----------------------------------------------- *//* -----OPTIONAL FUNCTIONS--------------------------------------- */#define MDL_START#if defined MDL_STARTstatic void mdlStart(SimStruct *S) { int_T i, width; real_T *buf; /* Get buffer width required */ width = mxGetPr(ssGetSFcnParam(S,0))[0]; /* Allocate memory for buffer. */ if ( (buf = (real_T *)calloc(width,sizeof(real_T))) == NULL) { ssSetErrorStatus(S,"Error allocating memory"); return; } ssGetPWork(S)[0] = buf; /* Initialise array index for storing inputs*/ ssGetIWork(S)[0] = 0;}#endif /* MDL_START *//* -----MANDATORY FUNCTIONS-------------------------------------- *//* mdlInitializeSizes() is called at simulation startup and whenever the block diagram is updated. It contains general initialisation settings. */static void mdlInitializeSizes(SimStruct *S){ int_T bufsize; ssSetNumSFcnParams(S,1); bufsize = (int_T)mxGetPr(ssGetSFcnParam(S,0))[0]; /* Set number of input ports (one) */ ssSetNumInputPorts (S,2); /* Set input port width (DYNAMICALLY_SIZED adjusts it to match input signal) */ ssSetInputPortWidth (S,0,1); ssSetInputPortWidth (S,1,1); /* Set Direct Feedthrough option (used if outputs are computed directly from inputs - as opposed to being computed via a state-space algorithm.) */ ssSetInputPortDirectFeedThrough (S,0,1); ssSetInputPortDirectFeedThrough (S,1,1); /* Set number of output ports (one) */ ssSetNumOutputPorts (S,1); /* Set output port width (DYNAMICALLY_SIZED adjusts it to match input width) */ ssSetOutputPortWidth (S,0,bufsize); ssSetNumIWork(S,1); ssSetNumPWork(S,1); /* Set number of sample rates the block operates at (single-rate) */ ssSetNumSampleTimes (S,1); /* Set 'exception-free code' option - most efficient. Do not set if the s-function calls any potentially exception-throwing mx functions. */ ssSetOptions (S,SS_OPTION_EXCEPTION_FREE_CODE);}/* mdlInitializeSampleTimes() sets block and port sample times at initialisation. */static void mdlInitializeSampleTimes(SimStruct *S){ /* Set block sample rate (INHERITED_SAMPLE_TIME inherits from driving block) */ ssSetSampleTime (S,0,INHERITED_SAMPLE_TIME); /* Set offset for sample time (usually 0.0) */ ssSetOffsetTime (S,0,0.0);}/* mdlOutputs() is called at each simulation step to do the actual work. */static void mdlOutputs(SimStruct *S, int_T tid){ /* The input signals are not guaranteed to be contiguous arrays - their elements are accessed using arrays of pointers */ InputRealPtrsType uPtr = ssGetInputPortSignalPtrs(S,0); InputRealPtrsType ctrl = ssGetInputPortSignalPtrs(S,1); /* The output signals are contiguous arrays */ real_T *y = ssGetOutputPortRealSignal(S,0); int_T width = ssGetOutputPortWidth(S,0); int_T *idx = &(ssGetIWork(S)[0]); real_T *buf = ssGetPWork(S)[0]; int_T i = 0; if (**ctrl == 0.0) { /* In idle state: just reset pointer to start of buffer */ *idx = 0; } else { /* In active state: first check for pointer at start of buffer. If so then reinitialise buffer to zeros... */ if (*idx == 0) { for (i=0;i<width;i++) { buf[i] = 0.0; } } /* ... put the new input into the buffer and increment the index... */ buf[(*idx)] = **uPtr; (*idx)++; /* ... and wrap the index if we're at the end of the buffer. */ if (*idx >= width) { *idx = 0; } } /* Read out the buffer into the output array. */ for (i=0;i<width;i++) { y[i] = buf[i]; }}/* mdlTerminate() is called at the end of the simulation run to clean up. A stub function must be provided even if it is not actually used. */static void mdlTerminate(SimStruct *S){ /* Free the memory allocated for the buffer. */ free((real_T *)ssGetPWork(S)[0]);}/*----FINAL DIRECTIVES------------------------------------------ *//* These preprocessor directives are always required at the end of the file. */#ifdef MATLAB_MEX_FILE#include "simulink.c"#else#include "cg_sfun.h"#endif/* [EOF] */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -