📄 tmtask.c
字号:
/*----------------------------------------------------------------------------
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
----------------------------------------------------------------------------*/
/* 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 );
/*#define PRINTF(x) printf x */
#define PRINTF(x)
#define USE_DYNALOAD
#ifndef USE_DYNALOAD
VOID Task2 ( VOID )
{
DWORD Idx ;
for ( Idx = 0 ; ; Idx++ )
{
PRINTF(( "Task 1 Count [%x] \n", Idx ));
}
}
#endif
VOID TaskSystem( VOID )
{
TMSTD_PACKET Packet;
TMTASK_MESSAGE QueueMessage;
DWORD PSOSStatus;
PTMTASK_MGR_OBJECT this = GetTaskMgrObject();
STATUS Status;
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 = chnlPacketSend ( this->pSysChnlSend, &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;
/* allocate the task manager object */
if ( ( this = malloc ( sizeof ( TMTASK_MGR_OBJECT ) ) ) == NULL )
{
Status = TM_STATUS ( TMTASK_ERR_MGROBJALLOCFAIL );
DT(0, "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 );
DT(0, "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;
this->pSysChnlRecv = NULL;
this->pSysChnlSend = NULL;
if ( ( Status = chnlmCreateChnl ( GetChnlMgrObject(),
TMCHNL_DIRECTION_SEND,
0, 0x10, /* HARDCODED */
(PVOID)taskmOnTaskSend, this, &this->pSysChnlSend ) ) != TMOK )
{
DT(0, "tmos:taskmCreate:chnlmCreateChnl:Send:FAIL[%x]\n", Status );
goto taskmCreateFail3;
}
if ( ( Status = chnlmCreateChnl ( GetChnlMgrObject(),
TMCHNL_DIRECTION_RECV,
1, 0x10, /* HARDCODED */
(PVOID)taskmOnTaskRecv, this, &this->pSysChnlRecv ) ) != TMOK )
{
DT(0, "tmos:taskmCreate:chnlmCreateChnl:Recv:FAIL[%x]\n", Status );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -