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

📄 s0_usertel_txd.c

📁 simulink real-time workshop for dragon12 development board from
💻 C
📖 第 1 页 / 共 2 页
字号:

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

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

			/* initialise all pointers with NULL */
			for(i=0; i<MAX_UCOM_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("s0_usertel_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 BufferAdminVar to the base workspace */
			mexPutVariable("base", "BufferAdminVar", BufferAdminVar);

		}
		else {

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

			/*  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("s0_usertel_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 BufferAdminVar to the base workspace */
				mexPutVariable("base", "BufferAdminVar", BufferAdminVar);

			}
			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
	
	/* target S-Function */
	
	{
		
		myUsrBuf	*admin;

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

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

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

		/* increase counter for the number of active user channels */
		num_user_channels_active++;

		/* store channel ID in user_txd_queue[] and increase 'next_user_channel_index' */
		user_txd_queue[next_user_channel_index++] = CHANNEL_NO;

	}

	#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		*BufferAdminVar;
		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 'BufferAdminVar' */
			if((BufferAdminVar = mexGetVariable("base", "BufferAdminVar")) == NULL) {

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

			}
			else {

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

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

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

			}

		}
		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

	/* target S-Function */
	{
	
		/* free instance local data buffer */
		free(admin->buf);
		free(admin);

		/* reset global buffer access pointer to NULL */
		userTelBuf[CHANNEL_NO] = NULL;

	}

	#endif

}


// the define 'MATLAB_MEX_FILE' has to be specified when recompiling this module to a DLL.
#ifdef MATLAB_MEX_FILE
   #include "simulink.c"
#else
   #include "cg_sfun.h"
#endif

⌨️ 快捷键说明

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