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

📄 tmrun.c

📁 wince host 和 target PCI驱动程序
💻 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.
 *
 *
 *  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 "tmman32.h"
#include "tmtypes.h"
#include "tmcrt.h"

#include "TM1IF.h"
#include "tmobj.h"

#define  PGM_MAJOR_VERSION (4)
#define  PGM_MINOR_VERSION (0)


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

BOOL WINAPI tmrunControlHandler ( DWORD dwCtrlType );


/*******************************************************************************/
int main( int  argc, char *argv[] )
{
	STATUS               Status;
	TMSTD_VERSION_INFO   Version;
	TMMAN_TMCONS_PARAMS	TMConsControl;
	COORD			     ConsoleSize;
	WORD				wIdxArg;
	DWORD				DSPNumber = 0;
	DWORD				ThreadCount = 2;
	CRunTimeParameterBlock	CRTParam;
	DWORD				CRTHandle;
    DWORD              ImageType,ImageEndian;

	BOOL				DynamicApplication = FALSE;
	CHAR**				ArgumentVectorArray;
	DWORD				ArgumentCount;
	CHAR				TargetExecutableName[MAX_PATH];

	HANDLE				ImageFileHandle;
	TMObj_Module_Rec	ExecutableHeader;
	DWORD				BytesReturned;
	CHAR				szExecutablePath[MAX_PATH];


	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 'T' :
			if ( sscanf(&argv[wIdxArg][2], "%x", &ThreadCount ) != 1 )
			{
				goto mainUsage;
			}
			break;

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


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

			case 'B' :
			Interactive = FALSE;
			break;

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

	CRTParam.CRTThreadCount		= ThreadCount;

	if ( TargetExecutableName[0] == '\0' )
	{
		fprintf ( stderr, "tmrun:Executable Image Name Missing");
		goto mainExit1;
	}

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

	hExitEvent = CreateEvent ( NULL, // not running on workstation 4.0
		FALSE, // auto reset event
		FALSE, // initial state is not signalled
		NULL );	// anonymous

	if ( hExitEvent == INVALID_HANDLE_VALUE )
	{
		fprintf ( stderr, "tmrun:CreateEvent:FAIL:[%x]", GetLastError() );
		goto mainExit1;
	}


	/* check for compatible driver version */
	Version.dwMajor = TMMAN_DEFAULT_VERSION_MAJ ; 
	Version.dwMinor = TMMAN_DEFAULT_VERSION_MIN ;

	if ( ( Status = tmNegotiateVersion (  TMMAN_DEFAULT, &Version ) )!= TMOK )
	{
		fprintf (stderr, "tmrun: tmNegotiateVersion failed [0x%x](%s).\nDSP program not executed.\n",
			Status,
			tmGetErrorString(Status));
		goto	mainExit2;
	}


	Status = tmDSPOpen( DSPNumber, &DSPHandle);
	if ( Status != TMOK )
	{
		fprintf (stderr, "tmrun: Can't open DSP board. [0x%x](%s) \n", 
			Status,
			tmGetErrorString(Status) );
		goto	mainExit2;
	} 
	
	ArgumentVectorArray = &argv[TargetArgumentOffset];
	ArgumentCount = argc - TargetArgumentOffset;

	cruntimeInit();

	// BEGIN APPLOAD


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

    if ( ImageType == TMObj_AppSegment )
	{

		DWORD	PathIdx, IdxArg, Idx;

		CHAR	TCSPath[MAX_PATH]; // HARDCODED max 16 bytes for key number

		DynamicApplication = TRUE;

		if ( ( ArgumentVectorArray = 
			malloc ( ( (argc - TargetArgumentOffset) + 2 ) * sizeof ( char *) ) ) == NULL )
		{
			fprintf (stderr, "**Error: : malloc argv array : FAILED\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];
		}


		ArgumentVectorArray[Idx] = NULL;

		ArgumentCount = Idx;


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

		ArgumentVectorArray[0] = TargetExecutableName;

		
	}

	// END APPLOAD

	Status = tmDSPExecutableLoad ( 
		DSPHandle, 
		TMMAN_DEFAULT,
		TargetExecutableName, 
		0, 
		NULL );

	if ( Status != TMOK )
	{
		fprintf (stderr, "**Error: Can't load %s. [0x%x](%s) \n", 
			TargetExecutableName, 
			Status,
			tmGetErrorString(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( stdout,
			"\r\nTMRun: ERROR  : Cannot Initialize C Run Time Server : CRT I/O calls will not work"  );
		goto	mainExit4;
	}


	/*
	tmDSPExecutableRun invokes the TriMedia manager component TMCons.
	TMCons serves as the console for programs running on TriMedia. 
	TMCons internally loads RPCserv.dll in order to act as a server to the Unix L2 
	calls. For programs like TMRun which act as Unix L2 server itself cannot function
	correctly if TMCons is running since both of them try to use RPCserv.dll and act
	as servers. In order to solve this problem tmDSPExecutableRun allows the 
	caller to control the behaviour of TMCons in way that it doesn't hamper 
	normal the callers operations.

	The TMCONS_PARAM_STRUCT is passed to the tmDSPExecutableRun function to control
	the behaviour of TMCons. To specify default behaviour ( i.e invoke TMCons )
	pass this structure is NULL as shown below.

	tmDSPExecutableRun  ( tm1_board_handle, Caps.SDRAM.dwPhysical, NULL ) ;

	To prevent TMCons from runing ( as required in TMRun )  do the following
	TMConsControl.fIgnoreTMCons = TRUE;

	TMCons runs with a default Window size of 25 or 50 lines.
	To change the number of lines shown in the TMCons windows use :-
	TMConsControl.fUseWindowSize = TRUE;
	TMConsControl.dwWindowSize = 900; // or required number of lines

	TMCons, be default, opens a seperate console window to diaplay stdout and stderr.
	To change this behaviour, and make TMCons come up with its window minimized use 
	TMConsControl.fUseTMMonWindow = TRUE;

	To redirect the standard input /output / stderr of TMCons to a file, use
	TMConsControl.fRedirectedStdXXX = TRUE;
	strcpy ( TMConsControl.szFilenameStdXXX, FileName ); 
	where FileName is a fully qualified path of the file to be used for redirection 
	*/

	TMConsControl.fRedirectedStdin = FALSE;
	TMConsControl.fRedirectedStdout = FALSE;
	TMConsControl.fRedirectedStderr = FALSE;
	TMConsControl.fUseWindowSize = FALSE;
	TMConsControl.fIgnoreTMCons = TRUE;
	TMConsControl.fUseTMMonWindow = FALSE;

	Status = tmDSPExecutableRun  ( 
		DSPHandle, 
		TMMAN_DEFAULT, 
		&TMConsControl ) ;

	if ( Status != TMOK )
	{
		fprintf( stderr,
			"TMRun: ERROR : Cannot Start Target Executable [0x%x](%s) \n", 
			Status,
			tmGetErrorString(Status) );
		goto mainExit5;
	}
	
	/* wait until the server's exit function is called */
	WaitForSingleObject (hExitEvent, INFINITE );

/* mainExit6: */
	tmDSPExecutableStop ( DSPHandle ); 

mainExit5:	
	GlobalExitCode = cruntimeDestroy( CRTHandle );

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

mainExit3 :
	cruntimeExit();
	tmDSPClose ( DSPHandle );

mainExit2 :
	CloseHandle ( hExitEvent );

mainExit1 :
	if ( Interactive )
	{
		fprintf (stdout, "\nTMRun:Press a key to close server >>");
		fflush(stdout);
		getchar();
	}	
	return (GlobalExitCode);

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

BOOL WINAPI tmrunControlHandler ( DWORD dwCtrlType )
{

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

⌨️ 快捷键说明

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