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

📄 tmtask.c

📁 wince host 和 target PCI驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*---------------------------------------------------------------------------- 
COPYRIGHT (c) 1996 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. 

THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT ANY PRIOR NOTICE
AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY Philips Semiconductor. 

PHILIPS ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF THIS SOFTWARE
ON PLATFORMS OTHER THAN THE ONE ON WHICH THIS SOFTWARE IS FURNISHED.
----------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------- 
	tmtask.c

	HISTORY
	#define	TR	Tilakraj Roy
	960610	TR	Created
	960827	TR 	Added task creation and integration with msg and strm.

	Contains implementation of the task related functions.

	Internal implementation Notes :
	There are seperate callbacks for the system message and strem channels
	and for the user task message and stream channels.

	The users task advise notification handler needs to know the source of the
	advise and other related inforamtion. This information is task specific and
	has nothing to do with messages and channels from the object point of view.
	So the message and the stream objects make seperate callbacks.
	These callbacks which are a part task object. 
	The non-system related callbacks call the Task Advise notification callback
	across the ring.

	How is the system task created ?
	Generally with this architecture, all task creation requests are routed via
	tmldr which acts as a daemon for servicing requests from the VxD for task
	downloading. The system task from this prepective is just like any other
	task since it used messages and channels and hence should be downloaded 
	and created by tmldr - however the factors that distinguish the system 
	task are :-
	.	When creating the system task there is no "system task available" for
		servicing the "create" request.
	. 	The system task is pre-linked and started as a part of the libtmman.a
		initialization process.
	.	The system task requires 4 pre-determined message and stream channels.
		The channels numbers for these channels are fixed 0 - 3. This imposes
		some unique requirements on channel creation.
	.	tmldr can start communicating with the DSP task only after all the 
		channels for the system task are created.

	These points require the following implementaion changes.

	.	The host initializes the RTOS via the call to tmLoadRTOS. 
	. 	The pSOS Root task calls tmLibraryCreate
	.	This initialization function picks up it's parameters from 
		TMHD_PARAMETER_BLOCK.
	.	Creates the managers and ipc.
	.	Creates the tmman system task.
	.	Creates the message and stream channels, to enable the system task
		to communicate with the host.
	.	Starts the tmman system task.
	.	The system task starts running and blocks to the message queue from 
		the host.

----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------
          SYSTEM INCLUDE FILES
----------------------------------------------------------------------------*/
#define WANTVXDWRAPS
#include <basedef.h>
#include <vmm.h>
#include <vxdwraps.h>

/*----------------------------------------------------------------------------
          DRIVER SPECIFIC INCLUDE FILES
----------------------------------------------------------------------------*/
#include "vxstd.h"
#include "vxwin.h"
#include "vxdbg.h"
#include "tmwincom.h"

#include "tmhd.h"
#include "tmman32.h"
#include "tmif.h"
#include "tmtask.h"
#include "tmshare.h"

#include "cqueue.h"



#pragma VxD_LOCKED_CODE_SEG
#pragma	VxD_LOCKED_DATA_SEG

STATUS	taskValidateHandle ( PVOID  TaskObject );

STATUS	taskmOnTaskSend ( PVOID pvContext ) 
{
	return TMOK;
}

STATUS	taskmOnTaskAdvise ( 
	PVOID pvContext, 		/* handle to the task */
	PVOID pvPacket )			/* pointer to the TMSTD_PACKET structure */
{
	PTMTASK_MGR_OBJECT		this = ( PTMTASK_MGR_OBJECT) pvContext;
	PTMSTD_PACKET			pPacket = (PTMSTD_PACKET)pvPacket;
	TMIF_ADVISORY_REQUEST	Advise;
	TMSTD_PACKET			Packet;
	PTMTASK_OBJECT			pTask;
	STATUS					Status;
	DWORD					ClientHandle;
	
	this->fRequestInService = FALSE;
		
	pTask = (PTMTASK_OBJECT)pPacket->dwArgument[TMHD_TASK_ARGHOSTTASK];
	Status = pPacket->dwArgument[TMHD_TASK_ARGSTATUS];
	Advise.dwCallback	= pTask->Callback;
	Advise.dwObjHandle	= (DWORD)pTask;
	Advise.pContext  	= pTask->pContext ;
	ClientHandle		= pTask->ClientHandle;

	switch ( pPacket->dwCommand )
	{
		case TMHD_TASK_CREATE :
		Advise.dwMessage	= TMMAN_ADVISE_TASK_CREATE;
		pTask->dwDSPTaskHandle = pPacket->dwArgument[TMHD_TASK_ARGDSPTASK];
		break;

		case TMHD_TASK_START :
		Advise.dwMessage	= TMMAN_ADVISE_TASK_START;
		break;

		case TMHD_TASK_STOP :
		Advise.dwMessage	= TMMAN_ADVISE_TASK_STOP;
		break;

		case TMHD_TASK_SIGNAL :
		Advise.dwMessage	= TMMAN_ADVISE_TASK_SIGNAL;
		break;

		case TMHD_TASK_DESTROY :
		Advise.dwMessage = TMMAN_ADVISE_TASK_DESTROY;
		if ( taskValidateHandle ( pTask ) == TMOK )
		{
			// task object cleanup steps.
			pTask->Flags = 0;
			pTask->Size = 0;
			this->AllocatedCount--;
			this->pTaskTab[pTask->Idx] = NULL;
			vxdFree ( pTask );
		}
		else
		{
			DP(0, "vtmman:PANIC:taskmOnTaskAdvise:INVALIDTASKHANDLE:HANDLE[%x]\n", 
				pTask );
		}
		break;

		default :
		DP(0, "vtmman:PANIC:taskmOnTaskAdvise:DEFAULT:Cmd[%x]\n", 
			pPacket->dwCommand );
		goto taskmOnTaskAdviseExit;	
	}
	
	Advise.Packet		= *pPacket;

	// the value of Packet->Command is of type TMHD_ TASK_XXXX which is a TMMAN
	// internal define, so we change the value of Advise.Packet->Command to 
	// Advise Message  to that the user mode application can comprehend it.
	Advise.Packet.dwCommand = pPacket->dwCommand;

	if ( ( Status = clntAdvise ( ClientHandle, &Advise ) ) != TMOK )
	{
		DP(0, "vtmman:taskOnMsgAdvise:clntAdvise:FAIL[%x]\n", Status );
		return Status;
	}
	
	// get the next request out of the queue and dump it to the dsp.
	if ( cqueueDelete ( this->pTaskRequestQ, &Packet ) == FALSE )
	{
			//no more pending requests
			return TMOK;
	}

	pTask = (PTMTASK_OBJECT)Packet.dwArgument[TMHD_TASK_ARGHOSTTASK];
	this->pSharedData->dwPriority = pTask->dwPriority;
	this->pSharedData->dwStackSize = pTask->dwStackSize;
	vxdStrCopy ( pTask->szTaskFile, this->pSharedData->szTaskFile );

	if ( ( Status = chnlPacketSend ( this->pSysChnlSend, &Packet ) ) != TMOK )
	{
		Advise.dwMessage	= TMMAN_ADVISE_TASK_FAIL;
		Advise.dwCallback	= pTask->Callback;
		Advise.dwObjHandle	= (DWORD)pTask;
		Advise.pContext  	= pTask->pContext ;
		Advise.Packet		= *pPacket;

		if ( ( Status = clntAdvise ( pTask->ClientHandle, &Advise ) ) != TMOK )
		{
			DP(0, "vtmman:taskOnMsgAdvise:clntAdvise:FAIL[%x]\n", Status );
			// no need to exit out here.
		}
	}
	else
	{
		this->fRequestInService = TRUE;
	}

taskmOnTaskAdviseExit :
	return TMOK;	
}


/* 
	taskInit

	Task Init is independent of Message and Stream. The message and stream
	channels that will be used by the tmldr will not be dealt with at this 
	level. tlmldr will be just another client to tmman32.dll
*/
STATUS	taskmCreate ( PVOID pContainer, DWORD TaskCount, PVOID *ppTaskMgr )
{
	PTMTASK_MGR_OBJECT	this;
	DWORD	IdxTask;
	STATUS	Status;

	if ( ( this = vxdMalloc ( sizeof ( TMTASK_MGR_OBJECT ) ) ) == NULL )
	{
		Status = TM_STATUS ( TMTASK_ERR_MGROBJALLOCFAIL );
		goto taskmCreateFail1;
	}

	this->Flags = 0;

	FlagSet ( this->Flags, TMTASK_FLAG_DYNAMICMGROBJ);
	

	if ( ( this->pTaskTab = 
		(PVOID)vxdMalloc ( sizeof ( PVOID ) * TaskCount ) ) == NULL )
	{
		Status = TM_STATUS ( TMTASK_ERR_OBJPTRTABMALLOCFAIL );
		goto	taskmCreateFail2;
	}

	for ( IdxTask = 0 ; IdxTask < TaskCount ; IdxTask ++ )
	{
		this->pTaskTab[IdxTask] = NULL;
	}

	this->Size = sizeof (TMTASK_MGR_OBJECT);
	this->pContainer = pContainer;
	this->TaskCount = TaskCount;
	this->AllocatedCount = 0;
	this->pSysChnlRecv = NULL;
	this->pSysChnlSend = NULL;
	this->fRequestInService = FALSE;

	if ( ( Status = chnlmCreateChnl ( GetChnlMgrObject(this->pContainer), 
		TMCHNL_DIRECTION_RECV, 
		0, 0x10,  /* HARDCODED */
		(PVOID)taskmOnTaskAdvise, this, &this->pSysChnlRecv ) ) != TMOK )
	{
		Status = TM_STATUS ( TMTASK_ERR_SYSCHNLRECVCREATEFAIL );
		goto taskmCreateFail3;
	}

	if ( ( Status = chnlmCreateChnl ( GetChnlMgrObject(this->pContainer), 
		TMCHNL_DIRECTION_SEND,
		1, 0x10, /* HARDCODED */
		(PVOID)taskmOnTaskSend, this, &this->pSysChnlSend ) ) != TMOK )
	{
		Status = TM_STATUS ( TMTASK_ERR_SYSCHNLSENDCREATEFAIL );
		goto taskmCreateFail4;
	}

	if ( ( Status = shmemAllocate ( GetShMemObject(this->pContainer), 0 ,
		sizeof ( TMHD_TASK_SHARED ), &this->pSharedData,
		&this->SharedDataPhys ) ) != TMOK )
	{
		goto	taskmCreateFail5;
	}

	this->pTaskRequestQ  = NULL;

	if ( cqueueCreate ( 0x10, sizeof ( TMSTD_PACKET ), 
		NULL, &this->pTaskRequestQ ) == FALSE )
	{
		Status = TM_STATUS ( TMTASK_ERR_QUEUECREATEFAIL );	
		goto taskmCreateFail6;
	}

	boardParameterDWORDSet ( this->pContainer, TMHD_PARAM_TASK,
		this->SharedDataPhys );

	*ppTaskMgr = this;
	return TMOK;

taskmCreateFail6 :
	shmemFree ( GetShMemObject(this->pContainer), this->pSharedData );

taskmCreateFail5 :
	chnlDestroy ( this->pSysChnlSend );

taskmCreateFail4 :
	chnlDestroy ( this->pSysChnlRecv );

taskmCreateFail3 :
	vxdFree ( this->pTaskTab );

taskmCreateFail2 :
	vxdFree ( this );

taskmCreateFail1 :
	return Status;

}

⌨️ 快捷键说明

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