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

📄 intermodel_txd.c

📁 simulink real-time workshop for dragon12 development board from
💻 C
📖 第 1 页 / 共 2 页
字号:
	/* host S-Function (DLL) */

	{

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

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

			/* FreeBufferAdminVar doesn't exist -> create & initialise it */
			FreeBufferAdminVar = mxCreateNumericMatrix(MAX_FREECOM_CHANNELS, 1, mxUINT32_CLASS, mxREAL);

			/* initialise the array to be stored in variable FreeBufferAdminVar */
			myPtr = (myUsrBuf **)mxGetPr(FreeBufferAdminVar);

			/* initialise all pointers with NULL */
			for(i=0; i<MAX_FREECOM_CHANNELS; i++) myPtr[i] = NULL;

			/* allocate memory for buffer (buf_size bytes) and its admin structure, returns the access pointer */
			if((admin = AllocateUserBuffer(CHANNEL_NO, buf_size, data_type)) == NULL) {

				mexErrMsgTxt("FreePortComms_txd: Problem during memory allocation [insufficient memory].\n");

			}
			
			//mexPrintf("Channel %d access count: %d\n", CHANNEL_NO, admin->access_count);

			/* store the access pointer in the workspace variable */
			myPtr[CHANNEL_NO] = admin;

			/* retain a local copy for fast access */
			PWork[0] = admin;

			/* export variable FreeBufferAdminVar to the base workspace */
			mexPutVariable("base", "FreeBufferAdminVar", FreeBufferAdminVar);

		}
		else {

			/* FreeBufferAdminVar exist */
			myPtr = (myUsrBuf **)mxGetPr(FreeBufferAdminVar);

			/*  check if the buffer has already been initialised */
			if(myPtr[CHANNEL_NO] == NULL) {

				/* this channel has not been initialised yet -> do so now... */
				if((admin = AllocateUserBuffer(CHANNEL_NO, buf_size, data_type)) == NULL) {

					mexErrMsgTxt("FreePortComms_txd: Problem during memory allocation [insufficient memory].\n");

				}

				//mexPrintf("Channel %d access count: %d\n", CHANNEL_NO, admin->access_count);

				/* store the access pointer in the workspace variable */
				myPtr[CHANNEL_NO] = admin;

				/* retain a local copy for fast access */
				PWork[0] = admin;

				/* export variable FreeBufferAdminVar to the base workspace */
				mexPutVariable("base", "FreeBufferAdminVar", FreeBufferAdminVar);

			}
			else {

				/* channel already initialised (rxd side) -> fetch it from there... */
				admin = myPtr[CHANNEL_NO];
				
				/* ... and increase access count (to '2') */
				admin->access_count++;
			
				//mexPrintf("Channel %d access count: %d\n", CHANNEL_NO, admin->access_count);
			
				/* retain a local copy for fast access */
				PWork[0] = admin;

			}
			
		}

	} /* context */


	#else
	
		/* not used here -- see corresponding TLC file */

	#endif

}



/*
 * mdlOutputs - compute the outputs
 *
 * In this function, you compute the outputs of your S-function
 * block.  The outputs are placed in the y variable.
 */
static void mdlOutputs(SimStruct *S, int_T tid)
{

	myUsrBuf	*admin = ssGetPWorkValue(S, 0);


	/* check 'buffer full' flag */
	if(admin->buffer_full == 0) {

		uint_T  channel		= (uint_T)admin->buf[1];
		uint_T	size		= admin->buf_size;
		uint8_T *buf		= (uint8_T *)&(admin->buf[4]);
		uint8_T	*blockInput	= (uint8_T *)ssGetInputPortSignal(S, 0);

		/* buffer empty -> check if new user data has arrived */
		if(memcmp(buf, blockInput, size) != 0) {

			/* new block input data available -> copy to the data buffer */
			memcpy(buf, blockInput, size);

			/* set 'buffer full' flag */
			admin->buffer_full = 1;
	

			#ifdef MATLAB_MEX_FILE
		
			/* host DLL -> echo... */
			
			#ifdef VERBOSE
			{

				uint_T	i;

				mexPrintf("TxD > Channel[%d] ", channel);

				/* new buffer... */
				for(i=0; i<size; i++)
					mexPrintf(":%d", (uint_T)buf[i]);

				mexPrintf(":\n");

			}
			#endif /* VERBOSE */

			#endif /* MATLAB_MEX_FILE */

		} /* if : new user data available */

	} /* if : buffer full flag reset */

}


/*
 * mdlTerminate - called when the simulation is terminated.
 *
 * In this function, you should perform any actions that are necessary
 * at the termination of a simulation.  For example, if memory was allocated
 * in mdlInitializeConditions, this is the place to free it.
 */
static void mdlTerminate (SimStruct *S)
{
	
	myUsrBuf	*admin = ssGetPWorkValue(S, 0);


	#ifdef MATLAB_MEX_FILE

	/* host S-Function (DLL) */
	{

		mxArray		*FreeBufferAdminVar;
		myUsrBuf	**myPtr;

		/* check if this is the last remaining access to this channel */
		if(admin->access_count == 1) {

			/* yep -> close channel and free memory */
			free(admin->buf);
			free(admin);

			/* update workspace variable 'FreeBufferAdminVar' */
			if((FreeBufferAdminVar = mexGetVariable("base", "FreeBufferAdminVar")) == NULL) {

				mexErrMsgTxt("s0_usrtel_txd: Error accessing workspace variable FreeBufferAdminVar (mdlTerminate).\n");

			}
			else {

				/* get base access pointer */
				myPtr = (myUsrBuf **)mxGetPr(FreeBufferAdminVar);

				/* reset the channel specific access pointer */
				myPtr[CHANNEL_NO] = NULL;

				/* export variable FreeBufferAdminVar to the base workspace */
				mexPutVariable("base", "FreeBufferAdminVar", FreeBufferAdminVar);

			}

		}
		else {
			
			/* decrease access counter, channel will be closed from the other side */
			admin->access_count--;

			//mexPrintf("Channel %d access count: %d\n", CHANNEL_NO, admin->access_count);

		}

	}


	#else

		/* not used here -- see corresponding TLC file */

	#endif

}


// the define 'MATLAB_MEX_FILE' has to be specified when recompiling this module to a DLL.
// this is only required if the format of the call-up parameters is modified... (FW-06-01)
#ifdef MATLAB_MEX_FILE
   #include "simulink.c"
#else
# error "Attempt to use InterModel_txd.c as non-inlined S-function"
#endif

⌨️ 快捷键说明

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