📄 s0_usertel_txd.c
字号:
/* 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 + -