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

📄 tmtask.c

📁 wince host 和 target PCI驱动程序
💻 C
字号:
/*---------------------------------------------------------------------------- COPYRIGHT (c) 1996 by Philips SemiconductorsTHIS 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 OTHERPERSON. THE OWNERSHIP AND TITLE OF THIS SOFTWARE IS NOT TRANSFERRED. THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT ANY PRIOR NOTICEAND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY Philips Semiconductor. PHILIPS ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF THIS SOFTWAREON 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----------------------------------------------------------------------------*//* CRT includes */#include <stdio.h>/* TriMedia standard shared includes */#include "tmman.h"#include "tmhd.h"/*#include "tmshare.h" */#include "tmos.h"#include "tmtask.h"#include "cqueue.h"#include "sys_conf.h"#include "psos.h"#include "probe.h"#include "DynamicLoader.h"STATUS	taskmCreateTask ( PVOID	pObject, DWORD dwHostHandle, PDWORD Handle );VOID TaskSystem( VOID );STATUS	taskmDestroy ( PVOID pTaskMgr );STATUS	taskDestroy ( DWORD dwHandle );STATUS	taskStop ( DWORD dwHandle );STATUS	taskStart ( DWORD dwHandle );STATUS	taskmOnTaskRecv ( PVOID pvContext, 	PVOID pPacket );STATUS	taskmOnTaskSend ( PVOID pvContext ); STATUS	taskmCreate ( DWORD TaskCount, PVOID *ppTaskMgr );unsigned long TMMANTaskDebug = 0;#define	PRINTF(x) if ( TMMANTaskDebug == 1 ) printf x /*#define	PRINTF(x)  */VOID TaskSystem( VOID ){	TMSTD_PACKET	Packet;	TMTASK_MESSAGE	QueueMessage;	DWORD	PSOSStatus;	PTMTASK_MGR_OBJECT	this	=  GetTaskMgrObject();	STATUS	Status;    PRINTF(("TaskSystem:STARTED\n"));	for ( ; ; )	{		/* wait for a message to come via a message queue */		PSOSStatus = q_receive ( this->QueueIDSystem, Q_WAIT, 0, &QueueMessage);        PRINTF(("TaskSystem:q_receive:Command[%x] \n", QueueMessage.Command ));		/*sm_p( SemaphoreSystem, SM_WAIT , 0 ); */		switch ( QueueMessage.Command )		{			case	TMHD_TASK_CREATE :			QueueMessage.Status = taskmCreateTask ( this, QueueMessage.DSPTaskHandle,				&QueueMessage.DSPTaskHandle );			break;				case TMHD_TASK_START :			QueueMessage.Status = taskStart ( QueueMessage.DSPTaskHandle );				break;			case TMHD_TASK_STOP :			QueueMessage.Status = taskStop ( QueueMessage.DSPTaskHandle );			break;			case TMHD_TASK_DESTROY :			QueueMessage.Status = taskDestroy (  QueueMessage.DSPTaskHandle );			break;			case TMHD_TASK_SIGNAL :			((PTMTASK_OBJECT)(QueueMessage.DSPTaskHandle))->dwState = QueueMessage.Status;			QueueMessage.Status = TMOK;			break;			default :			PRINTF(("TaskSystem:chnlPacketSend:DEFAULT[%x]\n", QueueMessage.Command));			continue;		}		Packet.dwCommand = QueueMessage.Command;		Packet.dwArgument[TMHD_TASK_ARGHOSTTASK] = QueueMessage.HostTaskHandle;		Packet.dwArgument[TMHD_TASK_ARGDSPTASK] = QueueMessage.DSPTaskHandle;		Packet.dwArgument[TMHD_TASK_ARGSTATUS] = QueueMessage.Status;		if ( ( Status = tmMsgSend( this->MessageHandle, &Packet) ) != TMOK )		{			PRINTF(( "TaskSystem:chnlPacketSend:FAIL[%x]\n", Status ));		}			}}/*	OnSystemCmd	This function handles the callbacks genereated as a result of the 	host sending requests to the DSP on the System Message Channel	We have to send to replies to the host :-	1.	Ack the the request has been received 	2.	Reply when the command is completed*/STATUS	taskmOnTaskRecv ( 	PVOID pvContext, 		/* handle to the task maanger */	PVOID pvPacket )			/* pointer to the TMSTD_PACKET structure */{	PTMSTD_PACKET		pPacket = (PTMSTD_PACKET)pvPacket;	PTMTASK_MGR_OBJECT	pTaskMgr = (PTMTASK_MGR_OBJECT)pvContext;	TMTASK_MESSAGE		QueueMessage;	DWORD	PSOSStatus;		QueueMessage.Command = pPacket->dwCommand;	QueueMessage.HostTaskHandle = pPacket->dwArgument[TMHD_TASK_ARGHOSTTASK];	QueueMessage.DSPTaskHandle = pPacket->dwArgument[TMHD_TASK_ARGDSPTASK];	QueueMessage.Status = pPacket->dwArgument[TMHD_TASK_ARGSTATUS];	PSOSStatus = q_send ( pTaskMgr->QueueIDSystem, &QueueMessage );	return TMOK;}STATUS	taskmOnTaskSend ( 	PVOID pvContext ) 		/* handle to the task */{	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 ( DWORD TaskCount, PVOID *ppTaskMgr ){	PTMTASK_MGR_OBJECT	this;	DWORD	IdxTask;	STATUS	Status;	DWORD PSOSStatus;	TMMAN_MESSAGE_DESC MsgCreate;    PRINTF(("taskmCreate\n"));	/* allocate the task manager object */	if ( ( this = malloc ( sizeof ( TMTASK_MGR_OBJECT ) ) ) == NULL )	{		Status = TM_STATUS ( TMTASK_ERR_MGROBJALLOCFAIL );		PRINTF(( "tmos:taskmCreate:malloc:TMTASK_MGR_OBJECT:FAIL\n"));		goto taskmCreateFail1;	}	this->Flags = 0;	/* indicate that the task manager object is dynamically allocated */	FlagSet ( this->Flags, TMTASK_FLAG_DYNAMICMGROBJ);		/* allcoate the task object pointer table */	if ( ( this->pTaskTab = 		(PVOID)malloc ( sizeof ( PVOID ) * TaskCount ) ) == NULL )	{		Status = TM_STATUS ( TMTASK_ERR_OBJPTRTABMALLOCFAIL );		PRINTF(( "tmos:taskmCreate:malloc:this->pTaskTab:FAIL\n"));		goto	taskmCreateFail2;	}	for ( IdxTask = 0 ; IdxTask < TaskCount ; IdxTask ++ )	{		this->pTaskTab[IdxTask] = NULL;	}	this->Size = sizeof (TMTASK_MGR_OBJECT);	this->TaskCount = TaskCount;	this->AllocatedCount = 0;		/* create a message queue */	MsgCreate.pContext = this;	MsgCreate.Callback = (DWORD) taskmOnTaskRecv;	MsgCreate.ID = 0x0;	MsgCreate.Slots = 0x10;	if ((Status = tmMsgCreate(		&MsgCreate,		(PVOID *)&this->MessageHandle ) ) != TMOK ) 	{		PRINTF(("tmos:tmMsgCreate:FAIL[%x]\n", Status ));		goto	taskmCreateFail3;	}	tmParameterDWORDGet ( TMHD_PARAM_TASK, (PDWORD)&this->pSharedData );		if ( ( PSOSStatus = q_create ( 		"tmsq", 0, Q_NOLIMIT | Q_PRIOR, &this->QueueIDSystem  ) ) != 0 )	{		Status = TM_STATUS ( TMTASK_ERR_QUEUESYSCREATEFAIL );		PRINTF(("tmos:taskmCreate:q_create:tmsq:FAIL[%x]\n", PSOSStatus ));		goto taskmCreateFail4;	}        	/* create task to serve requests from teh host */	if ( ( PSOSStatus = t_create ( 		"tmst", 				/* 4 character task name */		230,						/* priority */		0x10000,				/* supervisor stack size */		0x10000,				/* user stack size */		0,						/* flags */		&this->TaskIDSystem 				/*  Ptr to Task ID */		) ) != 0 )	{		Status = TM_STATUS ( TMTASK_ERR_TASKSYSCREATEFAIL );		PRINTF(( "tmos:taskmCreate:t_create:tmst:FAIL[%x]\n", PSOSStatus ));		goto	taskmCreateFail4;	}	if ( ( PSOSStatus = t_start ( 					 		this->TaskIDSystem ,			/* task DI returned by t_create */		T_PREEMPT | T_TSLICE | T_ASR | T_ISR, /* flags */		TaskSystem,				/* task function */		0					/* task startup args */		) ) != 0 )	{		Status = TM_STATUS ( TMTASK_ERR_TASKSYSSTARTFAIL );		PRINTF(("tmos:taskmCreate:t_start:tmst:FAIL[%x]\n", PSOSStatus ));		goto	taskmCreateFail4;	}	*ppTaskMgr = this;	return TMOK;taskmCreateFail7 :	t_delete ( this->TaskIDSystem );taskmCreateFail5 :	q_delete ( this->QueueIDSystem );taskmCreateFail4 :	tmMsgDestroy( this->MessageHandle );taskmCreateFail3 :	free ( this->pTaskTab );taskmCreateFail2 :	free ( this );taskmCreateFail1 :	return Status;}/* 	taskmCreateTask	Since the task opening happens in different phases it has to be 	implemented as a finite state machine, that changes state every time there	is a callback from the DSP. */STATUS	taskmCreateTask ( PVOID	pObject, DWORD dwHostHandle, PDWORD Handle ){	PTMTASK_MGR_OBJECT	this	=  ( PTMTASK_MGR_OBJECT )pObject;	PTMTASK_OBJECT		pTask;	TMSTD_PACKET		Packet;	DWORD				IdxTask;	STATUS				Status;	DWORD PSOSStatus;	DynLoad_Status DynLoadStatus;	pTask = NULL;	if ( this->AllocatedCount >= this->TaskCount )	{		Status = TM_STATUS(TMTASK_ERR_OUTOFTASKS);		PRINTF(( "tmos:taskmCreateTask:No Mote Task Slots:FAIL\n"));		goto	taskmCreateTaskExit1;	}	for ( IdxTask = 0 ; IdxTask < this->TaskCount ; IdxTask ++ )	{		if ( ! this->pTaskTab[IdxTask] )		{			break;		}	}	if ( ( pTask = malloc ( sizeof ( TMTASK_OBJECT ) ) ) == NULL )	{		Status  = TM_STATUS ( TMTASK_ERR_OBJALLOCFAIL );		PRINTF(( "tmos:taskmCreateTask:NoMoreMemory:FAIL\n"));		goto	taskmCreateTaskExit1;	}	this->pTaskTab[IdxTask] = (PVOID)pTask;	this->AllocatedCount++;	FlagSet ( pTask->Flags, TMTASK_TASK_FLAG_ALLOCATED );	pTask->Idx = IdxTask;	pTask->dwHostHandle = dwHostHandle;	pTask->dwPriority = this->pSharedData->dwPriority;	pTask->dwStackSize = this->pSharedData->dwStackSize;	pTask->dwState = 0;	strcpy ( pTask->szTaskFile, this->pSharedData->szTaskFile );		if ( ( DynLoadStatus = DynLoad_load_application ( 		pTask->szTaskFile, 		(DynLoad_Code_Segment_Handle *)(&pTask->DynLoadHandle) ) ) != DynLoad_OK )	{		/* handle cannot find executable error here. */		Status  = TM_STATUS ( TMTASK_ERR_DLLOADFAIL );		PRINTF(("taskmCreateTask:DynLoad_load_application:TaskName[%s]:Status[%x]:FAIL\n", pTask->szTaskFile, DynLoadStatus ));		goto	taskmCreateTaskExit2;	}	PRINTF(("taskmCreateTask:DynLoad_load_application:TaskName[%s]:Status[%x]\n",	pTask->szTaskFile, DynLoadStatus ));	if ( ( PSOSStatus = t_create ( 		&pTask->dwHostHandle,	/* 4 character task name */		pTask->dwPriority,	/* priority */		0x10000,					/* supervisor stack size */		pTask->dwStackSize,	/* user stack size */		0,							/* flags */		&pTask->OSTaskID ) ) != 0 )	/*  Ptr to Task ID */	{		Status  = TM_STATUS ( TMTASK_ERR_TASKCREATEFAIL );		PRINTF(( "tmos:taskmCreateTask:t_create:FAIL[%x]\n",PSOSStatus));		goto	taskmCreateTaskExit3;	}	PRINTF(( "taskmCreateTask:t_create:TaskID[%x]:Status[%x]\n", pTask->OSTaskID, PSOSStatus ));		*Handle = (DWORD)pTask;	return TMOK;taskmCreateTaskExit4:	t_delete ( pTask->OSTaskID );taskmCreateTaskExit3:	DynLoad_unload_application ( pTask->DynLoadHandle);taskmCreateTaskExit2:	this->pTaskTab[IdxTask] = NULL;	this->AllocatedCount--;	FlagClr ( pTask->Flags, TMTASK_TASK_FLAG_ALLOCATED );	free ( pTask );taskmCreateTaskExit1:	return Status;}STATUS	taskStop ( DWORD dwHandle ){	PTMTASK_OBJECT		this = ( PTMTASK_OBJECT) dwHandle;	DWORD PSOSStatus;	PSOSStatus = t_suspend ( this->OSTaskID );	PRINTF(("tmos:taskStop:t_suspend:ID[%x]:FAIL[%x]\n",this->OSTaskID, PSOSStatus));	return TMOK;}STATUS	taskGetState ( DWORD OSTaskID, PDWORD StatePtr ){	PTMTASK_MGR_OBJECT		this = ( PTMTASK_MGR_OBJECT)GetTaskMgrObject ( );	STATUS				Status = TMOK;	DWORD				IdxTask;	for ( IdxTask = 0 ; IdxTask < this->TaskCount ; IdxTask ++ )	{		if ( this->pTaskTab[IdxTask]->OSTaskID == OSTaskID )		{			*StatePtr = this->pTaskTab[IdxTask]->dwState;			return TMOK;		}	}		return TMTASK_ERR_INVALIDOBJECT;}STATUS	taskStart ( DWORD dwHandle ){	PTMTASK_OBJECT		this = ( PTMTASK_OBJECT) dwHandle;	TMSTD_PACKET		Packet;	STATUS				Status = TMOK;	PTMTASK_MGR_OBJECT	pTaskMgr	=  GetTaskMgrObject ( );	DWORD PSOSStatus;	if ( ( PSOSStatus = t_start ( 					 		this->OSTaskID,	/* task DI returned by t_create */		T_PREEMPT | T_TSLICE | T_ASR | T_ISR, /* flags */		((DynLoad_Code_Segment_Handle)this->DynLoadHandle)->start,		0 ) ) != 0 )					/* task startup args */	{		PRINTF(("tmos:taskStart:t_create:ID[%x]:FAIL[%x]\n",this->OSTaskID, PSOSStatus));		Status  = TM_STATUS ( TMTASK_ERR_TASKSTARTFAIL );		goto taskStartExit1;	}		PRINTF(( "taskStart:t_start:Function[%x]:Status[%x] \n", 		((DynLoad_Code_Segment_Handle)this->DynLoadHandle)->start,		PSOSStatus ));	taskStartExit1:	return  Status;}STATUS	taskDestroy ( DWORD dwHandle ){	PTMTASK_OBJECT		this = ( PTMTASK_OBJECT) dwHandle;	PTMTASK_MGR_OBJECT	pTaskMgr	=  GetTaskMgrObject ( );	PRINTF(( "taskDestroy\n" ));	t_delete ( this->OSTaskID );	PRINTF(( "taskDestroy:t_delete\n" ));	DynLoad_unload_application ( this->DynLoadHandle );	PRINTF(( "taskDestroy:DynLoad_unload_application\n" ));	pTaskMgr->pTaskTab[this->Idx] = NULL;	pTaskMgr->AllocatedCount--;	FlagClr ( this->Flags, TMTASK_TASK_FLAG_ALLOCATED );	free ( this );	return TMOK;}STATUS	taskmDestroy ( PVOID pTaskMgr ){	PTMTASK_MGR_OBJECT	this = (PTMTASK_MGR_OBJECT)pTaskMgr;	t_suspend ( this->TaskIDSystem );	t_delete ( this->TaskIDSystem );		q_delete ( this->QueueIDSystem );		tmMsgDestroy ( this->MessageHandle );	free ( this->pTaskTab );	this->Size = 0;	this->Flags = 0;	free ( this );	return TMOK;}

⌨️ 快捷键说明

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