www.pudn.com > communicationmatlab.rar > 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/* needed for declaration of sprintf */ #include /* 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