⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 s0_usertel_txd.c

📁 simulink real-time workshop for dragon12 development board from
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************/
/*                                                                            */
/* Name: s0_userTel_txd.c  - S-Function for the communication using the       */
/*                           asynchronous serial interface S0                 */
/*                                                                            */
/******************************************************************************/

// =============================================================================
// FW-01-03
//
// level 2 s-function
//
// To recompile this s-function into a Windows DLL use: 'recompile(name_of_the_mod_to_be_comp)'
// (==>  <toolbox>\C167\MC\recomp.m)
//
// error numbers: 34 -> 39
// =============================================================================

#define S_FUNCTION_NAME s0_userTel_txd
#define S_FUNCTION_LEVEL 2


/* undefine VERBOSE to run this DLL in silent mode */
//#define VERBOSE


#include <string.h>			/* memcpy, memcmp */
#include <simstruc.h>


#ifdef MATLAB_MEX_FILE
#define abort_LED(x) return
#else
#include "reg167_sfr.h"		/* adapted for GCC-166 (HighTec), C167CR, FW-06-01 */
#include "reg167_sbit.h"	/* adapted for GCC-166 (HighTec), C167CR, FW-06-01 */
#include "mc_signal.h"		/* abort_LED, etc. */
#endif


// -------------------------------------------------------------------------------
// Number of S-function Parameters and macros to access from the SimStruct
// -------------------------------------------------------------------------------

#define SAMPLE_TIME_ARG		ssGetSFcnParam(S,0)		/* Sample time in seconds */
#define CHANNEL_NO_ARG		ssGetSFcnParam(S,1) 	/* communication channel number (up to MAX_UCOM_CHANNELS) */
#define NUM_ELEMENTS_ARG	ssGetSFcnParam(S,2)		/* block output width ->  # of elements */
#define DATA_TYPE_ARG		ssGetSFcnParam(S,3) 	/* data type to be expected at block input */
#define NUMBER_OF_ARG		4              			/* Number of input arguments */


// -------------------------------------------------------------------------------
// Macros to access the S-function parameter values
// -------------------------------------------------------------------------------

#define SAMPLE_TIME     ((real_T)   mxGetPr (SAMPLE_TIME_ARG)[0])
#define CHANNEL_NO		((uint_T)   mxGetPr (CHANNEL_NO_ARG)[0])
#define NUM_ELEMENTS	((uint_T)   mxGetPr (NUM_ELEMENTS_ARG)[0])
#define DATA_TYPE		((int_T)    mxGetPr (DATA_TYPE_ARG)[0])



// ----------------------------------------------------------------------------------------------------
// global variables
// ----------------------------------------------------------------------------------------------------

// input signals may have the following bytes per element
const int_T	BuiltInDTypeSize[8] =	{
										4,    /* real32_T  */
    									1,    /* int8_T    */
    									1,    /* uint8_T   */
    									2,    /* int16_T   */
    									2,    /* uint16_T  */
    									4,    /* int32_T   */
    									4,    /* uint32_T  */
    									2     /* boolean_T */
									};




// ----------------------------------------------------------------------------------------------------
// local methods
// ----------------------------------------------------------------------------------------------------

// declaration of global user communication admin variables (only relevant for the target module, defined in ext_srv.h)
#include "s0_usertel.h"


/* allocate and initialise the communication variables associated with a particular channel (buffer, admin, ... ) */
static myUsrBuf *AllocateUserBuffer(uint_T channel, uint_T bufsize, uint8_T data_type_len) {

	uint8_T			*buf;
	static myUsrBuf	*admin = NULL;

	/* allocate memory for admin structure of this instance's data buffer */
	if((admin = (myUsrBuf *)calloc(1, sizeof(myUsrBuf))) == NULL)  return NULL;
		
	/* allocate memory for the buffer itself (buf_size '+ 4'  ->  telegram size, channel number, '0 0' [reserved]) */
	/* the additional '+3' has been introduced to allow safe byte-swapping -- required on the 9S12...  fw-03-05 */
	/* (the order of every group of 4 bytes gets reversed -> uint8_T transmissions might just end up on '+1' -> '+3' makes it dword aligned) */
	if((buf = (uint8_T *)calloc(bufsize + 4 + 3, sizeof(uint8_T))) == NULL)  return NULL;

	/* store pointer to buf in the admin structure */
	admin->buf = buf;

	/* store size of the actual data buffer */
	admin->buf_size = bufsize;

	/* initialise the access_count field */
	admin->access_count = 1;

	/* initialise the buffer_full flag */
	admin->buffer_full = 0;


	/* initialise buffer */

	/* set first field of the buffer to the number of bytes per user telegram (remains invariant)... */
	buf[0] = (uint8_T)(bufsize + 4);

	/* set second field of the buffer to the channel number (remains invariant)... */
	buf[1] = (uint8_T)channel;

	/* set third field of the buffer to the channel data type length: 1, 2, 4) (remains invariant)... */
	buf[2] = data_type_len;

	//mexPrintf("Setting channel %d data type length to: %d\n", channel, data_type_len);

	/* ... and clear the reserved byte (buf[3]) as well as the local data buffer */
	memset(&buf[3], 0, bufsize + 1);
	

	/* return access pointer */
	return admin;
}
		


// ----------------------------------------------------------------------------------------------------
// S-Function methods
// ----------------------------------------------------------------------------------------------------

/* Function: mdlCheckParameters ===============================================
 *
 */
#define MDL_CHECK_PARAMETERS
#if defined(MDL_CHECK_PARAMETERS)
static void mdlCheckParameters(SimStruct *S)
{
	// check parameter: SAMPLE_TIME
	if (mxGetNumberOfElements(SAMPLE_TIME_ARG) != 1)					abort_LED(36);	// parameter must be a scalar
	if ((SAMPLE_TIME < 0) && (SAMPLE_TIME != INHERITED_SAMPLE_TIME))	abort_LED(36);	// invalid negative sample time

	// check parameter: CHANNEL_NO
	if (mxGetNumberOfElements(CHANNEL_NO_ARG) != 1)						abort_LED(37);	// parameter must be a scalar
	if ((CHANNEL_NO < 0) || (CHANNEL_NO >= MAX_UCOM_CHANNELS))			abort_LED(37);	// invalid channel number

	// check parameter: NUM_ELEMENTS
	if (mxGetNumberOfElements(NUM_ELEMENTS_ARG) != 1)					abort_LED(38);	// parameter must be a scalar
	if ((NUM_ELEMENTS < 1) || 
		(BuiltInDTypeSize[DATA_TYPE-1] * NUM_ELEMENTS > MAX_BUF_SIZE))	abort_LED(38);	// inadmissible buffer size
}
#endif /* MDL_CHECK_PARAMETERS */



/* Function: mdlInitializeSizes ===============================================
 *
 */
static void mdlInitializeSizes (SimStruct *S)
{
int_T	i;

	ssSetNumSFcnParams(S, NUMBER_OF_ARG);											// expected number of parameters
	if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S))  abort_LED(35);			// incorrect number of parameters
	else {

		#ifdef MDL_CHECK_PARAMETERS
		mdlCheckParameters(S);							// check all parameters
		#endif
	}


	/* setup sizes of both work vectors and state vectors */
	//ssSetNumIWork (S, 0);						// no instance-local integer values
	//ssSetNumRWork (S, 0);						// no instance-local real values
	ssSetNumPWork (S, 1);						// instance-local pointer: access to this channel's buffer structure
	//ssSetNumDWork (S, 0);						// no instance-local user data types used
	//ssSetNumContStates (S, 0);				// width of the instance-local vector of continuous states
	//ssSetNumDiscStates (S, 0);				// width of the instance-local vector of discrete states
	

	/* define number of sample times used by this s-function */
	ssSetNumSampleTimes (S, 1);					// only 'one' sampletime in this S-Function

	// None of this s-functions's parameters are tunable during simulation (sample time, channel, buffer size, data type)
	for (i=0; i<NUMBER_OF_ARG; i++) ssSetSFcnParamNotTunable(S, i);


	if(!ssSetNumInputPorts(S, 1))	abort_LED(39);			// block has a single input...
	if(!ssSetNumOutputPorts(S, 0))	abort_LED(39);			// ... and no output (-> sink)

	ssSetInputPortWidth(S, 0, NUM_ELEMENTS);				// input width: number of elements

	//mexPrintf("Data type: %d\n", DATA_TYPE);

	ssSetInputPortDataType(S, 0, DATA_TYPE);				// block initialization code (mbc_userteltxd.m) adjusts this to '1' ... (no '0' = 'double')
	ssSetInputPortDirectFeedThrough(S, 0, 1);				// direct feedthrough (only executs after update of inputs)
	ssSetInputPortRequiredContiguous(S, 0, 1);				// ports to be stored contiguously in memory

}



/* Function: mdlInitializeSampleTimes =========================================
 *
 */
static void mdlInitializeSampleTimes (SimStruct *S)
{
   ssSetSampleTime(S, 0, SAMPLE_TIME);				// this S-Function only has 'one' sampletime -> index '0'
   ssSetOffsetTime(S, 0, 0.0);
}



/* Function: mdlStart =========================================================
 *
 */
#define MDL_START
static void mdlStart(SimStruct *S)
{
	
	void		**PWork = ssGetPWork(S);
	uint8_T		data_type = BuiltInDTypeSize[DATA_TYPE-1];		// first possible 'DATA_TYPE' is '1' ('sinle') -> map this to '0' (beginning of array)
	uint_T		buf_size = 	data_type * NUM_ELEMENTS;


	#ifdef MATLAB_MEX_FILE

	/* host S-Function (DLL) */

	{

		mxArray		*BufferAdminVar;
		myUsrBuf	*admin, **myPtr;
		int_T		i;
		
		/* all admin variables associated with a buffer are communicated via the workspace variable 'BufferAdminVar' */

		//mexPrintf("s0_usertel_txd: mdlStart.\n");
		
		/* check if variable 'BufferAdminVar' exists in the base workspace */
		if((BufferAdminVar = mexGetVariable("base", "BufferAdminVar")) == NULL) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -