📄 sreadfil.c
字号:
/*
* SREADFIL A SIMULINK trigged read from a file.
*
* Syntax: [sys, x0] = sreadfil(t,x,u,flag, filename, format, pulnum, threshold, numOutput, recursive)
* The input of this function is a clock pulse signal in triggeling the
* output from a file.
*
* filename: a string for the filename.
* format: the format of the file to read. The choices are:
* "integer", "float", "ascii", "binary".
* pulnum: number of pulses between saved data. If pulnum is a two
* dimentional vector, the second element is the number of
* 'offset' pulse before the first data is saved.
* threshold: trigger signal threshold.
* numOutput: the output width. When this variable is zero or negative
* number, this function will test the file to find the
* column number of the file.
*
* Wes Wang Feb. 7, 1995
* Copyright (c) 1994-96 by The MathWorks, Inc.
* All Rights Reserved
* $Revision: 1.1 $ $Date: 1996/04/01 19:05:39 $
*/
#define S_FUNCTION_NAME sreadfil
#include <stdio.h> /* needed for declaration of sprintf */
#include <string.h> /* needed for string operation */
#ifdef MATLAB_MEX_FILE
#include "mex.h" /* needed for declaration of mexErrMsgTxt */
#endif
/*
* need to include simstruc.h for the definition of the SimStruct and
* its associated macro definitions.
*/
#include "simstruc.h"
/*
* Defines for easy access of the input parameters
*/
#define NUM_ARGS 6
/* file name for the data to be saved */
#define FILENAME ssGetArg(S, 0)
/* data type, which is a string of ASCII, Integer, float, or binary */
#define DATA_TYPE ssGetArg(S, 1)
/* number of pulse count to trigger one saving record */
#define NUM_IN_BT ssGetArg(S, 2)
/* Ouput vector length */
#define NUMOUTPUT ssGetArg(S, 3)
/* recursive index */
#define RECURSIVE ssGetArg(S, 4)
/* threshold in detecting the raising edge. */
#define THRESHOLD ssGetArg(S, 5)
/*
* mdlInitializeSizes - called to initialize the sizes array stored in
* the SimStruct. The sizes array defines the
* characteristics (number of inputs, outputs,
* states, etc.) of the S-Function.
*/
static void mdlInitializeSizes(S)
SimStruct *S;
{
/*
* Set-up size information.
*/
if (ssGetNumArgs(S) == NUM_ARGS) {
int NumOutput = (int)mxGetPr(NUMOUTPUT)[0];
int i;
/* char err_msg[256];
*/
if ((mxGetN(FILENAME) > 1) && (mxGetM(FILENAME) > 1)) {
#ifdef MATLAB_MEX_FILE
char err_msg[256];
sprintf(err_msg, "Filename should be a string vector.");
mexErrMsgTxt(err_msg);
#endif
}
if ((mxGetN(DATA_TYPE) > 1) && (mxGetM(DATA_TYPE) > 1)) {
#ifdef MATLAB_MEX_FILE
char err_msg[256];
sprintf(err_msg, "Data Type should be a string vector.");
mexErrMsgTxt(err_msg);
#endif
}
if ((mxGetN(NUM_IN_BT) * mxGetM(NUM_IN_BT) > 2) || (mxGetN(NUM_IN_BT) * mxGetM(NUM_IN_BT) < 1) ) {
#ifdef MATLAB_MEX_FILE
char err_msg[256];
sprintf(err_msg, "Dimension for trigger pulse number is incorrect.");
mexErrMsgTxt(err_msg);
#endif
}
if ((mxGetN(THRESHOLD) * mxGetM(THRESHOLD)) > 1) {
#ifdef MATLAB_MEX_FILE
char err_msg[256];
sprintf(err_msg, "Threshold must be a scalar.");
mexErrMsgTxt(err_msg);
#endif
}
if ((mxGetN(NUMOUTPUT) * mxGetM(NUMOUTPUT)) > 1) {
#ifdef MATLAB_MEX_FILE
char err_msg[256];
sprintf(err_msg, "Threshold must be a scalar.");
mexErrMsgTxt(err_msg);
#endif
}
/* sprintf(err_msg, "From initialization maxDelay %d, numOutput %d.\n", maxDelay, numOutput);
mexPrintf(err_msg);
*/
ssSetNumContStates( S, 0);
ssSetNumDiscStates( S, 0);
ssSetNumInputs( S, 1);
if (NumOutput <= 0) {
/*If it is ASCII, default to be single output */
char dataType[8];
#ifdef MATLAB_MEX_FILE
if (mxGetString(DATA_TYPE, dataType, sizeof(dataType)) != 0) {
char err_msg[256];
sprintf(err_msg, "'%s' is not a valid data type in file reading", dataType);
mexErrMsgTxt(err_msg);
}
#endif
if ((strcmp(dataType, "ascii") ==0 ) || strcmp(dataType, "ASCII") == 0) {
NumOutput = 1;
} else {
/* Findout the output from the file */
FILE *fp;
char filename[32];
char chrbuffer[512];
int line_length, last_comma;
/* get the file name */
#ifdef MATLAB_MEX_FILE
if (mxGetString(FILENAME, filename, sizeof(filename)) != 0) {
char err_msg[256];
sprintf(err_msg, "Error in opening the data file %s", filename);
mexErrMsgTxt(err_msg);
}
#endif
/* open the file */
fp = fopen(filename, "r");
if (fp == NULL) {
#ifdef MATLAB_MEX_FILE
char err_msg[256];
sprintf(err_msg, "Error in opening the data file %s", filename);
mexErrMsgTxt(err_msg);
#endif
}
/* read the first line */
fgets(chrbuffer, sizeof(chrbuffer), fp);
line_length = strlen(chrbuffer);
if ((line_length <= 0) || (line_length <= 0)) {
#ifdef MATLAB_MEX_FILE
char err_msg[256];
sprintf(err_msg, "Data file is empty.");
mexErrMsgTxt(err_msg);
#endif
}
/* get the counting */
last_comma = 0;
NumOutput = 0;
for (i = 0; i < line_length; i++) {
if ((chrbuffer[i] == ' ') || (chrbuffer[i] == ',')) {
if ((i - last_comma) > 1)
NumOutput += 1;
last_comma = i;
}
}
if ((last_comma + 1) >= line_length)
NumOutput += 1;
/* close the file */
fclose(fp);
}
}
ssSetNumOutputs( S, NumOutput);
ssSetDirectFeedThrough(S, 0);
ssSetNumInputArgs( S, NUM_ARGS);
ssSetNumSampleTimes( S, 1);
ssSetNumRWork( S, 0);
ssSetNumIWork( S, 3);
/* 1st: 0--start, not passed offset; 1--regular calculation
* 2nd: accumulate accounting for the how many pulse passed
* 3rd: 0: last trigger signal was below threshold 1: last trigger signal was above threshold
*/
ssSetNumPWork( S, 1);
/* point for the opened file name */
} else {
#ifdef MATLAB_MEX_FILE
char err_msg[256];
sprintf(err_msg, "Wrong number of input arguments passed to S-function MEX-file.\n"
"%d input arguments were passed in when expecting %d input arguments.\n", ssGetNumArgs(S) + 4, NUM_ARGS + 4);
mexErrMsgTxt(err_msg);
#endif
}
}
/*
* mdlInitializeSampleTimes - initializes the array of sample times stored in
* the SimStruct associated with this S-Function.
*/
static void mdlInitializeSampleTimes(S)
SimStruct *S;
{
/*
* Note, blocks that are continuous in nature should have a single
* sample time of 0.0.
*/
ssSetSampleTimeEvent(S, 0, 0.0);
ssSetOffsetTimeEvent(S, 0, 0.0);
}
/*
* mdlInitializeConditions - initializes the states for the S-Function
*/
static void mdlInitializeConditions(x0, S)
double *x0;
SimStruct *S;
{
int *CountFlag = ssGetIWork(S);
int *CountNum = ssGetIWork(S) + 1;
int *LastTrig = ssGetIWork(S) + 2;
FILE *fp = (FILE *) ssGetPWork(S)[0];
*CountFlag = 0;
*CountNum = 0;
*LastTrig = 0;
fp = NULL;
}
/*
* mdlOutputs - computes the outputs of the S-Function
*/
static void mdlOutputs(y, x, u, S, tid)
double *y, *x, *u;
SimStruct *S;
int tid;
{
int *CountFlag = ssGetIWork(S);
int *CountNum = ssGetIWork(S) + 1;
int *LastTrig = ssGetIWork(S) + 2;
FILE *fp = (FILE *)ssGetPWork(S)[0];
double trigThreshold = mxGetPr(THRESHOLD)[0];
int numOutput = ssGetNumOutputs(S);
int i;
char filename[32];
char dataType[10];
char err_msg[256];
/* sprintf(err_msg, "numInput %i", numInput);
mexPrintf(err_msg);
*/
/*
* acquire the buffer data
*/
if ((u[0] >= trigThreshold) & (*LastTrig == 0)) {
/* debug line
sprintf(err_msg, "Count Plus one %f\n",u[numInput-1]);
mexPrintf(err_msg);
*/
#ifdef MATLAB_MEX_FILE
if (mxGetString(DATA_TYPE, dataType, sizeof(dataType)) != 0) {
mexErrMsgTxt("Error in Data Type specification.");
}
#endif
*CountNum += 1;
if (*CountFlag) {
/* action when count number is larger or equal to number count */
int NumberInBetween = (int)mxGetPr(NUM_IN_BT)[0];
if (*CountNum > NumberInBetween) {
/* reset Count */
*CountNum = 0;
if (fp != NULL) {
int test_eof;
if (strcmp(dataType, "float") == 0) {
float fbuffer[1];
for (i = 0; i < numOutput; i++) {
test_eof = fscanf(fp, "%g", fbuffer);
y[i] = (double)fbuffer[0];
}
} else if (strcmp(dataType, "integer") == 0) {
int ibuffer[1];
for (i = 0; i < numOutput; i++) {
test_eof = fscanf(fp, "%d", ibuffer);
y[i] = (double) ibuffer[0];
}
} else if ((strcmp(dataType, "ascii") == 0) || (strcmp(dataType, "ASCII") == 0)) {
char cbuffer[1];
for (i = 0; i < numOutput; i++) {
test_eof = fscanf(fp, "%c", cbuffer);
y[i] = (double)((int)cbuffer[0]);
}
} else if ((strcmp(dataType, "binary") == 0)) {
test_eof = fread(y, numOutput * sizeof(double), 1, fp);
} else {
#ifdef MATLAB_MEX_FILE
mexErrMsgTxt("Data type is not a legal string.");
#endif
}
if (test_eof == EOF) {
if (mxGetPr(RECURSIVE)[0] == 0) {
for (i = 0; i < numOutput; i++)
y[i] = 0;
} else {
rewind(fp);
if (strcmp(dataType, "float") == 0) {
float fbuffer[1];
for (i = 0; i < numOutput; i++) {
test_eof = fscanf(fp, "%g", fbuffer);
y[i] = (double) fbuffer[0];
}
} else if (strcmp(dataType, "integer") == 0) {
int ibuffer[1];
for (i = 0; i < numOutput; i++) {
test_eof = fscanf(fp, "%d", ibuffer);
y[i] = (double) ibuffer[0];
}
} else if ((strcmp(dataType, "ascii") == 0) || (strcmp(dataType, "ASCII") == 0)) {
char cbuffer[1];
for (i = 0; i < numOutput; i++) {
test_eof = fscanf(fp, "%c", cbuffer);
y[i] = (double)((int)cbuffer[0]);
}
} else if ((strcmp(dataType, "binary") == 0)) {
test_eof = fread(y, numOutput * sizeof(double), 1, fp);
} else {
#ifdef MATLAB_MEX_FILE
mexErrMsgTxt("Data type is not a legal string.");
#endif
}
}
}
} else {
#ifdef MATLAB_MEX_FILE
mexErrMsgTxt("File point lost.");
#endif
}
}
/* debug lines
sprintf(err_msg, " %c", y[0]);
mexPrintf(err_msg);
*/
} else {
i = 0;
if ((mxGetN(NUM_IN_BT) * mxGetM(NUM_IN_BT)) < 2) {
i = 1;
} else {
if (*CountNum > mxGetPr(NUM_IN_BT)[1])
i = 1;
}
if (i) {
/* this one will be run once only. */
/* debug line
sprintf(err_msg, "Get file name i %i", i);
mexPrintf(err_msg);
*/
mxGetString(FILENAME, filename, sizeof(filename));
/* debug line
sprintf(err_msg, "openfile %s", filename);
mexPrintf(err_msg);
*/
fp = fopen(filename, "r");
if (fp == NULL) {
#ifdef MATLAB_MEX_FILE
char err_msg[256];
sprintf(err_msg, "Error in opening the data file %s", filename);
mexErrMsgTxt(err_msg);
#endif
} else {
int test_eof;
ssGetPWork(S)[0] = (void *)fp;
if (strcmp(dataType, "float") == 0) {
float fbuffer[1];
for (i = 0; i < numOutput; i++) {
test_eof = fscanf(fp, "%g", fbuffer);
y[i] = (double) fbuffer[0];
}
} else if (strcmp(dataType, "integer") == 0) {
int ibuffer[1];
for (i = 0; i < numOutput; i++) {
test_eof = fscanf(fp, "%d", ibuffer);
y[i] = (double) ibuffer[0];
}
} else if ((strcmp(dataType, "ascii") == 0) || (strcmp(dataType, "ASCII") == 0)) {
char cbuffer[1];
for (i = 0; i < numOutput; i++) {
test_eof = fscanf(fp, "%c", cbuffer);
y[i] = (double)((int)cbuffer[0]);
}
} else if ((strcmp(dataType, "binary") == 0)) {
test_eof = fread(y, numOutput * sizeof(double), 1, fp);
} else {
#ifdef MATLAB_MEX_FILE
mexErrMsgTxt("Data type is not a legal string.");
#endif
}
if (test_eof == EOF) {
#ifdef MATLAB_MEX_FILE
mexErrMsgTxt("Data file is empty or data number is smaller than block output vector size.");
#endif
}
}
/* set flag, the Count flag setting avoid duplication of open file */
*CountFlag = 1;
*CountNum = 0;
}
/* debug line
sprintf(err_msg, " %c", y[0]);
mexPrintf(err_msg);
*/
}
} else if (ssGetT(S) <= 0) {
#ifdef MATLAB_MEX_FILE
if (mxGetString(DATA_TYPE, dataType, sizeof(dataType)) != 0) {
mexErrMsgTxt("Error in Data Type specification.");
} else {
if ((strcmp(dataType, "ascii") == 0) || (strcmp(dataType, "ASCII") == 0)) {
for (i = 0; i < numOutput; i++)
y[i] = 32;
}
}
#endif
}
if (u[0] >= trigThreshold) {
*LastTrig = 1;
} else {
*LastTrig = 0;
}
}
/*
* mdlUpdate - computes the discrete states of the S-Function
*/
static void mdlUpdate(x, u, S, tid)
double *x, *u;
SimStruct *S;
int tid;
{
}
/*
* mdlDerivatives - computes the derivatives of the S-Function
*/
static void mdlDerivatives(dx, x, u, S, tid)
double *dx, *x, *u;
SimStruct *S;
int tid;
{
}
/*
* mdlTerminate - called at termination of model execution.
*/
static void mdlTerminate(S)
SimStruct *S;
{
FILE *fp = (FILE *)ssGetPWork(S)[0];
if (fp != NULL)
fclose(fp);
}
#ifdef MATLAB_MEX_FILE /* Is this file being compiled as a MEX-file? */
#include "simulink.c" /* MEX-File interface mechanism */
#else
#include "cg_sfun.h" /* Code generation registration function */
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -