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

📄 tmrun.c

📁 PNX系列设备驱动 PNX系列设备驱动
💻 C
字号:
/*
 *  COPYRIGHT (c) 1997 by Philips Semiconductors
 *
 *   +-----------------------------------------------------------------+
 *   | THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED |
 *   | AND COPIED IN ACCORDANCE WITH THE TERMS AND CONDITIONS OF SUCH  |
 *   | A LICENSE AND WITH THE INCLUSION OF THE THIS COPY RIGHT NOTICE. |
 *   | THIS SOFTWARE OR ANY OTHER COPIES OF THIS SOFTWARE MAY NOT BE   |
 *   | PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY OTHER PERSON. THE   |
 *   | OWNERSHIP AND TITLE OF THIS SOFTWARE IS NOT TRANSFERRED.        |
 *   +-----------------------------------------------------------------+
 *
 *  Revision history         : 
 *    10/26/96:  CJP		:	Tested and basically working.
 *								More error checking and reporting added.
 *
 *    970106:  Tilakraj Roy :	Added support for the TMCons in tmDSPRunExecutable.
 *								Commenetd the use of tmDSPRunExecutable
 *    970114:  Tilakraj Roy :	Added command line processing of windows size
 *    970128:  Tilakraj Roy :	Added tmDSPExecutableStop in exit function
 *    970327:  Tilakraj Roy :	Revamped the entire code for proper error handling
 *								Added the ExitEvent for proper cleanup.
 *    970630:  Tilakraj Roy :	Added multiprocessor support.
 *    970631:  Tilakraj Roy :	Added	new cruntime support.
 *    970728:  Tilakraj Roy :	Fixed exit code error bug.
 *    971010:  Tilakraj Roy :	Ported to TMMan version 5.0
 *
 *
 *  Description              :  
 *
 *		This module is driver for the
 *		host part of the PC version of the Level 2 
 *		Remote Procedure Call Server. An implementation
 *		of this is needed for each particular host of
 *		a TM-1 board which uses TCS's generic ANSI C library.
 *		
 *		In its current form this module is intended to run as
 *		an independent executable that must be
 *		started from a PC command line. Its first argument
 *		must be the name of a TM-1 executable which is to be 
 *		downloaded, started, and which is passed all additional
 *		command line arguments. Between starting the executable
 *		and receiving its termination message, this module behaves
 *		as a server for the HostCall interface.
 *
 */

/*---------------------------- Includes --------------------------------------*/

#include "windows.h"
#include "stdio.h"

#include "tmmanapi.h"
#include "tmcrt.h"
#include "TMObj.h"

HANDLE	hExitEvent;
DWORD	GlobalExitCode = (~0x0);
BOOL	Interactive = TRUE;
BOOL	Server = FALSE;
DWORD	DSPHandle;
DWORD	TargetArgumentOffset ;

BOOL WINAPI tmrunControlHandler ( DWORD dwCtrlType );
UInt32 ODS( UInt8* FormatString, ... );

/*******************************************************************************/
int main( int  argc, char *argv[] )
{
	TMStatus			Status;
	tmmanVersion		Version;
	WORD				wIdxArg;
	DWORD				DSPNumber = 0;
	DWORD				CRTHandle;
	CRunTimeParameterBlock	CRTParam;
	CHAR				szEventName[80];
	tmmanDSPInfo		DSPInfo;
	BOOL				TargetExitedNormally = FALSE;
	BOOL				DynamicApplication = FALSE;
	CHAR**				ArgumentVectorArray;
	DWORD				ArgumentCount;
	CHAR				TargetExecutableName[constTMManPathLength];
	DWORD				dwWindowLines = 0;

	TargetExecutableName[0] = '\0';

	CRTParam.OptionBitmap		= 0;
	CRTParam.StdInHandle		= (DWORD)GetStdHandle ( STD_INPUT_HANDLE );
	CRTParam.StdOutHandle		= (DWORD)GetStdHandle ( STD_OUTPUT_HANDLE );
	CRTParam.StdErrHandle		= (DWORD)GetStdHandle ( STD_ERROR_HANDLE );

	if ( argc == 1 )
	{
		goto mainUsage;
	}

	TargetArgumentOffset = argc;

	// process the command line parameters
	for ( wIdxArg = 1; wIdxArg < argc ; wIdxArg++ )
	{
		if( argv[wIdxArg][0] != '-' )
		{
			strcpy ( TargetExecutableName, argv[wIdxArg] );
			TargetArgumentOffset = wIdxArg;
			break;
		}

		switch ( toupper ( argv[wIdxArg][1]) )
		{
			case 'D' :
			if ( sscanf(&argv[wIdxArg][2], "%x", &DSPNumber ) != 1 )
			{
				goto mainUsage;
			}
			break;


			case 'V' :
			/* identify yourself! */
			fprintf (stderr, 
				"\nTMRun v%d.%d (c) 1998, Philips Semiconductors.\n", 
				constTMManDefaultVersionMajor, 
				constTMManDefaultVersionMinor );
			break;

			case 'S' :
			Server = TRUE;
			break;

			case 'B' :
			Interactive = FALSE;
			break;

			case 'W' :
			{
				COORD	ConsoleSize;
				if ( sscanf(&argv[wIdxArg][2], "%u", &dwWindowLines ) != 1 )
				{
					goto mainUsage;
				}
				ConsoleSize.X = 80;
				ConsoleSize.Y = (USHORT)dwWindowLines;
				SetConsoleScreenBufferSize (
					GetStdHandle ( STD_OUTPUT_HANDLE ), ConsoleSize );
			}
			break;
			
			// add other command line optons here
			case '?' : 
			default :
			goto mainUsage;
		}
	}

	// set the Windows size if it has not already been set
	// from the command line - do it here so that tmdbg, tmmon, tmgmon 
	// benefit from it BUG#503266, BUG#503264, BUG#503116
	if ( Server )
	{
		COORD	ConsoleSize;
		HKEY	RegistryHandle;

		if ( ERROR_SUCCESS == RegOpenKeyEx(  
			HKEY_LOCAL_MACHINE,
			constTMManRegistryPath,
			0,
			KEY_READ,
			&RegistryHandle ) )
		{
			ULONG	BytesXfered;
			DWORD	dwWindowLines;
			COORD	ConsoleSize;
			
			BytesXfered = sizeof ( ULONG );

			if ( ERROR_SUCCESS == RegQueryValueEx(
				RegistryHandle,
				TEXT("TMRunWindowSize"),
				NULL,
				NULL,
				(BYTE*)&dwWindowLines,
				&BytesXfered ) )
			{

				ConsoleSize.X = 80;
				if ( dwWindowLines > 500 ) dwWindowLines = 500; //BUG#503263
				ConsoleSize.Y = (USHORT)dwWindowLines;
				SetConsoleScreenBufferSize (
					GetStdHandle ( STD_OUTPUT_HANDLE ), ConsoleSize );

			}

			RegCloseKey ( RegistryHandle );
		}

	}

	// unused parameter
	CRTParam.CRTThreadCount		= 2;

	if ( ( ! Server ) && ( TargetExecutableName[0] == '\0' ) )
	{
		fprintf ( stderr, "TMRun : ERROR : Executable Image Name Missing\n");
		goto mainExit1;
	}

	// install a control C handler so that we can perform cleanup before exit.
	if ( SetConsoleCtrlHandler  ( tmrunControlHandler , TRUE ) != TRUE )
	{
		fprintf ( stderr, "TMRun : ERROR : Win32 SetConsoleCtrlHandler failed [0x%x]\n", GetLastError() );
		goto mainExit1;
	}

	/* check for compatible driver version */
	Version.Major = constTMManDefaultVersionMajor ; 
	Version.Minor = constTMManDefaultVersionMinor ;

	tmmanNegotiateVersion (  constTMManDefault, &Version );

	if ( ( Version.Major != constTMManDefaultVersionMajor ) ||
		( Version.Minor != constTMManDefaultVersionMinor) )
	{
		fprintf (stderr, "TMRun : ERROR :  tmrun.exe Version[%d.%d] is INCOMPATIBLE With TMMan32.dll Version[%d.%d]\n",
			constTMManDefaultVersionMajor, constTMManDefaultVersionMinor, 
			Version.Major, Version.Minor );

		goto	mainExit1;
	}

	Status = tmmanDSPOpen( 
		DSPNumber, 
		&DSPHandle);

	if ( Status != statusSuccess )
	{
		fprintf (stderr, "TMRun : ERROR : tmmanDSPOpen failed [0x%x](%s) \n", 
			Status, tmmanGetErrorString(Status) );
		goto	mainExit1;
	} 

	Status = tmmanDSPGetInfo ( 
		DSPHandle, 
		&DSPInfo );

	if ( Status != statusSuccess )
	{
		fprintf (stderr, "TMRun : ERROR : tmmanDSPGetInfo [0x%x](%s) \n",
			Status, tmmanGetErrorString(Status) );
		goto	mainExit1;
	} 

	wsprintf( szEventName, "TMRunExitEvent%x", DSPInfo.DSPNumber );

	hExitEvent = CreateEvent ( NULL, 
		TRUE, // auto reset event
		FALSE, // initial state is not signalled
		szEventName );	// anonymous

	if ( hExitEvent == INVALID_HANDLE_VALUE )
	{
		fprintf (stderr, "TMRun : ERROR : Win32 CreateEvent[%s] failed (0x%x)\n", 
			szEventName, GetLastError() );
		goto mainExit2;
	}

	ArgumentVectorArray = &argv[TargetArgumentOffset];
	ArgumentCount = argc - TargetArgumentOffset;

	
	cruntimeInit();

	if ( ! Server )
	{
		UInt32				ImageType,ImageEndian;

		// BEGIN APPLOAD
		if ( tmmanGetImageInfo (
			TargetExecutableName,
			&ImageType,
			&ImageEndian ) != True )
		{
			fprintf (stderr,
				"\r\nTMMon: ERROR  : Loading Executable [%s]: FAIL (File Not Found)", 
				TargetExecutableName );
			goto mainExit3;
		}

		if ( ImageType == TMObj_AppSegment ) 
		{
			UInt32	IdxArg, Idx;
			UInt8	TCSPath[constTMManPathLength];


			DynamicApplication = TRUE;

			if ( ( ArgumentVectorArray = 
				malloc ( ( argc - TargetArgumentOffset ) * sizeof ( char *) ) ) == NULL )
			{
				fprintf (stderr, "TMRun : ERROR : malloc : Argument Buffer :FAIL\n" );
				goto mainExit3;

			}

			// if the component is of -btype app then we have to recreate
			// the arguemnt list  as the appshell.out has to be argv[0]
			// argv[0] will be dealt with later copy the rest of the 
			// arguemnts first.
			for ( Idx = 1, IdxArg = TargetArgumentOffset ; 
				IdxArg < ( argc ) ; 
				Idx ++, IdxArg++ )
			{
				ArgumentVectorArray[Idx] = argv[IdxArg];
			}

			ArgumentCount = Idx;

			if ( tmmanGetTCSPath ( 
				TCSPath,
				constTMManPathLength ) != True )
			{
				sprintf ( TargetExecutableName, "%s", "appshell.out" ); 
			}
			else
			{
				// TCS\lib\el\appshell.out
				sprintf ( TargetExecutableName, "%s\\lib\\%s\\WinNT\\appshell.out",
					TCSPath, 
					( ImageEndian == LittleEndian ) ? "el" : "eb"  ); 
			}

			ArgumentVectorArray[0] = TargetExecutableName;
		}
	

		// END APPLOAD

		Status = tmmanDSPLoad ( 
			DSPHandle, 
			constTMManDefault,
			TargetExecutableName );

		if ( Status != statusSuccess )
		{
			fprintf ( stderr, "TMRun : ERROR : tmmanDSPLoad (%s) failed [0x%x](%s) \n", 
				TargetExecutableName, Status, tmmanGetErrorString(Status) );
			goto mainExit4;
		}
	} 

	CRTParam.OptionBitmap |= constCRunTimeFlagsUseSynchObject;
	CRTParam.SynchronizationObject = (DWORD)hExitEvent;
	CRTParam.VirtualNodeNumber = 0;

	if ( ! Interactive )
	{
		CRTParam.OptionBitmap |= constCRunTimeFlagsNonInteractive;
	}

	if ( cruntimeCreate( 
		DSPNumber,
		ArgumentCount,
		ArgumentVectorArray,
		&CRTParam,
		&CRTHandle ) != True )
	{
		fprintf( stderr,
			"TMRun : ERROR : Cannot Initialize C Run Time Server : CRT I/O calls will not work\n" );
		goto	mainExit4;
	}

	if ( ! Server )
	{
		Status = tmmanDSPStart  ( 
			DSPHandle );

		if ( Status != statusSuccess )
		{
			fprintf( stderr,
				"TMRun: ERROR : tmmanDSPStart failed [0x%x](%s)\n", 
				Status, tmmanGetErrorString(Status) );
			goto mainExit5;
		}
	}
	
	/* wait until the server's exit function is called */
	WaitForSingleObject (hExitEvent, INFINITE );
	//fprintf(stderr, "[WaitForSingleObject|Signalled]\n" );

/* mainExit6: */
	if ( ! Server )
	{
		tmmanDSPStop ( DSPHandle ); 
	}

mainExit5:	
	TargetExitedNormally = cruntimeDestroy( CRTHandle, &GlobalExitCode  );
	//fprintf(stderr, "tmrun:cruntimeDestroy:TargetExitedNormally[%s]:Interactive[%s]:ExitCode[0x%x]\n", 
	//	TargetExitedNormally ? "TRUE" : "FALSE", 
	//	Interactive ? "TRUE" : "FALSE",
	//	GlobalExitCode );

mainExit4:	
	if ( DynamicApplication )
	{
		free ( ArgumentVectorArray );
	}

mainExit3 :
	CloseHandle ( hExitEvent );
	
mainExit2 :
	cruntimeExit();
	tmmanDSPClose ( DSPHandle );


mainExit1 :
	if ( ( Interactive ) && ( TargetExitedNormally ) )
	{
		fprintf (stderr, "\nTMRun:Press [ENTER] to close server >>");
		fflush(stdout);
		getchar();
	}
	else
	{
		//fprintf(stderr, "[tmrun:WaitForKeyPress:SKIPPED]\n" );
	}	
	return (GlobalExitCode);

mainUsage :
	fprintf (stderr, "usage:TMRun [-dDSPNumber] [-b] [-wWindowSize] [-s] ExecutableImageName [Arg1] [Arg2] ...\n" );
	goto	mainExit1;
}

BOOL WINAPI tmrunControlHandler ( DWORD dwCtrlType )
{

   fprintf ( stderr, "\nTMRun:Control C Detected : Performing Cleanup\n" );
   SetEvent ( hExitEvent );
   return TRUE;
}


UInt32 ODS( 
	UInt8* FormatString, 
	... )
{
	UInt32	Items;
	UInt8	Buffer[1024];
	
	va_list	Arguments;

	va_start ( Arguments, FormatString );

	Items = vsprintf ( Buffer,  FormatString, Arguments );

	va_end ( Arguments );

	OutputDebugString ( Buffer ); 
	OutputDebugString ( "\n" ); 
	return Items;
}

⌨️ 快捷键说明

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