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

📄 ext_transport232.c

📁 simulink real-time workshop for dragon12 development board from
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
 * Copyright 1994-2001 The MathWorks, Inc.
 *
 * File: ext_transport.c     $Revision: 1.7 $
 *
 * Abstract:
 *  Host-side, transport-dependent external mode functions and defs.  This    
 *  example file implements host/target communication using an RS232 serial
 *  connection (FW-09-02).Functionality supplied by this module includes:
 *
 *
 * >>>>> modified: FW-01-03
 *
 *
 *      o definition of 'UserData'
 *      o is target message pending
 *      o is target upload data pending
 *      o get bytes from target message line
 *      o set bytes on target message line
 *      o get bytes from target data upload line
 *      o close connection with target
 *      o open connection with target
 *      o create user data
 *      o destroy user data
 *      o process command line arguments
 *
 * Note: 
 *  This mex file specifies the signal, SIGPIPE, be ignored.
 *
 * The files relating to host-side external mode are:
 *  ext_main.c
 *      The mex file interface to Simulink.  This gets/sets message flags
 *      and data from/to Simulink and dispatches as approriate to ext_comm.c.
 *
 *      [THIS FILE SHOULD NOT NEED TO BE MODIFIED]
 *
 *  ext_comm.c
 *      Transport-independent external mode functions.  Handles external mode
 *      tasks and dispatches all transport-specific tasks (e.g., TCPIP) to
 *      this file (ext_custom.c).
 *
 *      [THIS FILE SHOULD NOT NEED TO BE MODIFIED FOR DIFFERENT TRANSPORT
 *       MECHANISMS] 
 *
 *  ext_transport.c
 *      This file.  Transport-dependent implementation of the mandatory
 *      support functions (e.g., set bytes, get bytes, open connection, etc).
 *
 *      [THIS FILE NEEDS TO BE MODIFIED TO IMPLEMENT VARIOUS DATA TRANSPORT
 *       MECHANISMS]
 *
 *  <matlabroot>/rtw/c/src/ext_transport_share.h
 *      Defininitions that are specific to the implemented transport mechanism
 *      and that are required on both the host and the target.
 *
 *      [THIS FILE NEEDS TO BE MODIFIED TO IMPLEMENT VARIOUS DATA TRANSPORT
 *       MECHANISMS]
 *
 *  ext_convert.c
 *      Conversion routines from host to target and vice versa.  All conversion
 *      is done on the host.  The target always sends and receives data in
 *      it's native format.
 *
 *      [THIS FILE DOES NOT NEED TO BE CUSTOMIZED FOR VARIOUS TRANSPORT
 *       MECHANISMS, BUT DOES NEED TO BE CUSTOMIZED FOR THE INTENDED TARGET.
 *       FOR EXAMPLE, IF THE TARGET REPRESENTS FLOATS IN TI FORMAT, THEN
 *       EXT_CONVERT MUST BE MODIFIED TO PERFORM A TI TO IEEE CONVERSION.
 *       THE CONVERSION ROUTINES IN THIS FILE ARE CALLED BOTH FROM
 *       EXT_COMM AND DIRECTLY FROM SIMULINK (VIA FUNCTION POINTERS)]
 *
 * **** SUMMARY ****
 * To implement a different transport mechanism you need to do the following
 * on the host:
 *  o modify this file
 *  o modify ext_transport_share.h
 *
 * For the target, see <matlabroot>/rtw/c/src/ext_svr_transport.c.
 */

#include <windows.h>			// BuildCommDCB, CloseHandle, CreateFile, EscapeCommFunction, GetCommState,
								// GetLastError, ReadFile, SetCommState, SetCommTimeouts, WriteFile, FlushFileBuffers
								// Sleep
#include <stdio.h>				// sprintf
#include <stdlib.h>				// malloc, calloc
#include <string.h>				// memcpy
#include <math.h>				// ceil

#include "tmwtypes.h"
#include "mex.h"
#include "extsim.h"
#include "extutil.h"

#include "ext_convert.h"		// slCopyNBytes (added: fw-02-05)
#include "ext_share.h"			// MsgHeader {(uint32_T)type, (uint32_T)size}, NUM_HDR_ELS (2)
#include "ext_transport232.h"	// Definition of UserData_tag, etc.



/* set verbosity of debugging messages (0, 1, 2, 3 or 4 -> set this to 0 in the release version) */
#define DEBUG_MSG_LVL	0

/* communication bytes (FW-01-03) */
#define ACK_SUCCESS		31
#define ACK_NO_SUCCESS	32
#define USR				33		/* user data telegrams */
#define DAT				34		/* log data telegrams */
#define MES				35		/* message telegrams */



/***************** DEFINE USER DATA HERE **************************************
 *                                                                            *
 * THE DEFINITION OF USER DATA IS SPECIFIC TO THE TRANSPORT IMPLEMENTATION.   *
 * IT IS EXPORTED AS AN 'OPAQUE' OR 'INCOMPLETE' TYPE IN EXT_TRANSORT.H.  SEE *
 * EXT_TRANSPORT.H FOR MORE INFO.                                             *
 *                                                                            *
 * NOTE THAT USERDATA MUST EXIST.  IF NOT NEEDED, DEFINE IT TO HAVE ONE DUMMY *
 * FIELD                                                                      *
 *                                                                            *
 ******************************************************************************/


// typedef struct UserData_tag {} UserData    ...    moved to 'ext_transport.h'


/* local data buffer  --  used to store intercepted data packages until Simulink gets'em */
static uint8_T	interceptDatBuf[1024];	
static uint8_T  tempSendMsgBuf[1024];   /* used in conjunction with targets that need byte re-ordering -- fw-02-05 */
static uint8_T	interceptMsgBuf[1024];	


/* declare global admin variables of the communication buffers (defined in ext_comm.c) */
typedef struct	myUsrBuf_tag {
					int_T	buffer_full;
					uint_T	access_count;
					uint_T	buf_size;
					uint8_T	*buf;
				} myUsrBuf;

extern myUsrBuf	*userTelBuf[];			/* pointer to the data buffers of outgoing user telegrams */




/***************** PRIVATE FUNCTIONS ******************************************
 *                                                                            *
 *  THE FOLLOWING FUNCTIONS ARE SPECIFIC TO THE TCPIP EXAMPLE OF HOST-        *
 *  TARGET COMMUNICATION.  SEE THE 'VISIBLE FUNCTIONS' SECTION FOR THE        *
 *  GENERIC SET OF FUNCTIONS THAT ARE CALLED BY EXTERNAL MODE.  TO IMPLEMENT  *
 *  A CUSTOM VERSION OF EXTERNAL MODE  (E.G. SHARED MEMORY, SERIAL CABLE, ETC)*
 *  THE BODIES OF THE FUNCTIONS IN THE 'VISIBLE FUNCTIONS' SECTION MUST BE    *
 *  REPLACED.                                                                 *
 *                                                                            *
 ******************************************************************************/


/* Function: checkCOMforData ===================================================
 * check if there's data in the COM buffer (FW-09-02)
 */
static int checkCOMforData(HANDLE fd) {

	COMSTAT		cs;
	DWORD		error;

	// reset error status (returns structure COMSTAT [winbase.h])
	if(!ClearCommError(fd, (LPDWORD)&error, (LPCOMSTAT)&cs)) {
		// error during call to ClearCommError
		mexPrintf("checkCOM4data: Error during call to ClearCommError.\n");

		// flag error to the calling function
		return(-1);
	}
	else {
		
		#if DEBUG_MSG_LVL >= 3
		mexPrintf("ExtTagetTelPending: checkCOMforData detected %d data bytes in COM buffer\n", (int)cs.cbInQue);
		#endif
		
		// return number of bytes in the buffer
		return((int)cs.cbInQue);
	}

} /* end checkCOMforData */






/***************** VISIBLE FUNCTIONS ******************************************
 *                                                                            *
 *  YOU MUST REPLACE EACH OF THE FOLLOWING FUNCTIONS TO IMPLEMENT A CUSTOM    *
 *  VERSION OF EXTERNAL MODE.                                                 *
 *                                                                            *
 *  ALSO SEE <MATLABROOT>/RTW/C/SRC/EXT_TRANSPORT_SHARE.H FOR ADDING DEFS FOR *
 *  YOUR CUSTOM IMPLEMENTATION THAT ARE REQUIRED BY BOTH THE HOST AND THE     *
 *  TARGET.                                                                   *
 *                                                                            *
 ******************************************************************************/


/* Function: ExtTargetTelPending ===============================================
 * Abstract:
 *  Returns true via the 'pending' arg, if a telegram is pending. The type of 
 *  data received (MES, DAT, USR) is stored in userData->TelType
 *  Returns EXT_NO_ERROR on success (no timeouts etc.), EXT_ERROR otherwise.
 */
PUBLIC boolean_T ExtTargetTelPending(
    ExternalSim		*ES,
    boolean_T       *pending,
    long int        timeOutSecs,
    long int        timeOutUSecs)
{
    UserData	*userData = (UserData *)esGetUserData(ES);
	uint_T		nBytesGot;
	int_T		lookforACK;
	char_T		dst;



	/* repeat this section a second time, in case a (trailing) acknowledgement is received */
	lookforACK = 1;
	while(lookforACK) {

		/* nothing has been received yet; -> check if new data is waiting in the COM buffer */
		if(checkCOMforData(userData->hCom) > 0) {

			#if DEBUG_MSG_LVL >= 2
			mexPrintf("ExtTagetTelPending: data available COM\n");
			#endif
	
			// there is... -> retrieve first byte to determine the telegram type [message / data / usr data]
			if(ReadFile(userData->hCom, (LPSTR)&dst, 1, &nBytesGot, NULL)) {
				
				if (nBytesGot == 1) {

					// determine telegram type
					switch((int_T)dst) {

					case ACK_SUCCESS:

						/* target is uploading a message (8 bytes) on the data channel -> remove trailing ACK_SUCCESS */
						#if DEBUG_MSG_LVL >= 2
						mexPrintf("ExtTagetTelPending: removing trailing ACK_SUCCESS signal.\n");
						#endif

						/* check if this is the trailing ACK_SUCCESS following ExtDisconnectConfirmed */
						if(userData->ExtDisconnectConfirmed == TRUE) {

							/* indeed... -> reset ExtDisconnectConfirmed flag */
							userData->ExtDisconnectConfirmed = FALSE;
							
							/* flag 'no telgram available' to the calling function and exit from the while loop */
							*pending = FALSE;
							lookforACK--;

						}

						/* else -> lookforACK remains '1'  ... go 'round the while loop */

						break; /* switch */


					case MES:

						#if DEBUG_MSG_LVL >= 2
						mexPrintf("ExtTagetTelPending: message telegram detected.\n");
						#endif
						
						userData->TelType = MES;				/* signal the receipt of an MES telegram */

						/* flag 'telegram available' to the calling function and return */
						*pending = TRUE;
						lookforACK--;

						break; /* switch */


					case USR:

						#if DEBUG_MSG_LVL >= 2
						mexPrintf("ExtTagetTelPending: user telegram detected.\n");
						#endif
						
						userData->TelType = USR;				/* signal the receipt of an USR telegram */

						/* flag 'telegram available' to the calling function and return */
						*pending = TRUE;
						lookforACK--;

						break; /* switch */

					
					case DAT:

						#if DEBUG_MSG_LVL >= 2
						mexPrintf("ExtTagetTelPending: data telegram detected.\n");
						#endif
						
						userData->TelType = DAT;				/* signal the receipt of an DAT telegram */

						/* flag 'telegram available' to the calling function and return */
						*pending = TRUE;
						lookforACK--;

						break; /* switch */

						
					default:

						/* communication error... unexpected telegram type */
						#if DEBUG_MSG_LVL >= 2
						mexPrintf("ExtTagetTelPending: unknown telegram detected (%d).\n", (int_T)dst);
						#endif

						#ifdef ERASE
						// debug only
						{
							int_T	i = 0;
							int_T	oneByteGot = 0;

							while((int_T)dst != 8 && i++ < 10) {
							
								if(ReadFile(userData->hCom, (LPSTR)&dst, 1, &oneByteGot, NULL)) {
								
									mexPrintf("next byte (%d): %d\n", (uint_T)dst, i);

								}
								else {

									mexPrintf("read error\n");

								}
							}
						}
						#endif
	
						/* return with an error */
						return EXT_ERROR;

					} /* switch */

				}
				else {

					/* nBytesGot != 1 -> TIMEOUT occurred during reception */
					mexPrintf ("ExtTagetTelPending: Timeout occurred during reception of telegram type (ReadFile).\n");
					{
						DWORD err = GetLastError();
						mexPrintf("Error code: %ld\n", err);
					}

					/* return with an error */
					return EXT_ERROR;

				}

			}
			else {

				/* unspecified error during data reception (ReadFile) */
				mexPrintf ("ExtTagetTelPending: Unspecified error during data reception (ReadFile).\n");
					
				/* return with an error */
				return EXT_ERROR;

			}
	
		} /* end of: check COM buffer if there is any data at all */

		else {

			/* nothing in COM -> return with 'FALSE' (currently nothing pending) */
			*pending = FALSE;
			lookforACK--;

		}

	} /* while(lookforACK) */
	
		
	/* successful detection of telegram type byte (or nothing) */
	return EXT_NO_ERROR;

} /* end ExtTagetTelPending */





/* Function: ExtGetTargetMsg ===================================================
 * Abstract:
 *  Attempts to get the specified number of bytes from the msg buffer.  The number
 *  of bytes read is returned via the 'nBytesGot' parameter.  EXT_NO_ERROR is
 *  returned on success, EXT_ERROR is returned on failure.
 *
 * NOTES:
 *  o it is not an error for 'nBytesGot' to be returned as 0
 *  o it is o.k. for this function to block if no data is available
 */
PUBLIC boolean_T ExtGetTargetMsg(
    ExternalSim		*ES,
    const int        nBytesToGet,
    int             *nBytesGot, /* out */
    char            *dst)       /* out */
{

    UserData	*userData = (UserData *)esGetUserData(ES);

	
	/* check if the ENTIRE message is already available in interceptMsgBuf[1 ... 8] (-> intercepted MsgHdr) */
	if(userData->MsgTelIntercepted == TRUE) {

		#if DEBUG_MSG_LVL >= 2
		mexPrintf("ExtGetTargetMsg: Previously intercepted message header available in interceptMsgBuf\n");
		#endif

		/* yep... -> fetch it from there */
		memcpy(dst, interceptMsgBuf, 8);

		/* adjust number of bytes received */
		*nBytesGot = 8;

		/* re-order bytes (ms9S12)   --  fw-02-05 */
		//slCopyNBytes(dst, dst, *nBytesGot, TRUE, 4);
		{
			int_T     i;
			char_T  dat;

			for(i=0; i<*nBytesGot; i +=4) {

                dat      = dst[i+3];
				dst[i+3] = dst[i+0];
				dst[i+0] = dat;
                dat      = dst[i+2];
				dst[i+2] = dst[i+1];
				dst[i+1] = dat;

			}
		}

		/* reset TelType & MsgTelIntercepted */
		userData->TelType = 0;
		userData->MsgTelIntercepted = FALSE;

		#if DEBUG_MSG_LVL >= 2
		{
			int_T	i;

			for(i=0; i<8; i++)
				mexPrintf("ExtGetTargetMsg: previously intercepted message [%d/8]) %d\n", i+1, (uint_T)(dst[i]));

⌨️ 快捷键说明

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