📄 task.c
字号:
/*
* Copyright 2006 by Texas Instruments Incorporated.
* All rights reserved. Property of Texas Instruments Incorporated.
* Restricted rights to use, duplicate or disclose this code are
* granted through contract.
*
* @(#) TCP/IP_Network_Developers_Kit 1.91.00.08 08-22-2006 (ndk-a08)
*/
//--------------------------------------------------------------------------
// OS Demonstration Software
//--------------------------------------------------------------------------
// Task.c
//
// Task Management Functions
//
// Author: Michael A. Denio
// Copyright 1999, 2001 by Texas Instruments Inc.
//-------------------------------------------------------------------------
#include <std.h>
#include <sys.h>
#include <tsk.h>
#include <sem.h>
#include <hook.h>
#include <netmain.h>
#include <_stack.h>
#include <_oskern.h>
//
// Low Resource Flag
//
// We can only process a low resource condition when
// we are not in kernel mode, so we use a flag and
// then process it on a call to llExit()
//
uint _TaskFlagLowResource = 0;
//
// Hook ID
//
// The Hook ID is used to set our environment pointer for
// slot zero. It must be valid!! (Check in SetEnv function)
//
static HOOK_Id hookId = 0xffffffff;
static uint hookOK = 0;
//
// This hookInit() function must be hooked into DSP/BIOS for
// the NDK to work properly.
//
void NDK_hookInit( HOOK_Id id )
{
hookId = id;
}
//
// This hookCreate() function is needed to init the environment
// to zero.
//
void NDK_hookCreate( TSK_Handle h )
{
hookOK = 1;
if( hookId != 0xffffffff )
HOOK_setenv( (TSK_Handle)h, hookId, 0 );
}
//--------------------------------------------------------------------
// llEnter / llExit - Kernel Mode gate functions
//--------------------------------------------------------------------
// NOTE: There are two versions of the llEnter()/llExit() pairing.
// The default version uses task priority to implement exclusion. The
// second version uses a semaphore. The priority based version is
// faster, but not as safe if care is not taken when setting task
// priorities.
//
// NOTE: Whether or not to use a semaphore for exclusion is independent
// of the choice to use a semaphore for scheduling in NETCTRL.
// The concepts are unrelated.
//
// To enable the semaphore version, set the below #define to 1
// Note that when _NDK_EXTERN_CONFIG is defined, this USE_LL_SEMAPHORE
// is defined outside the module.
//--------------------------------------------------------------------
#ifndef _NDK_EXTERN_CONFIG
#define USE_LL_SEMAPHORE 0
#endif
static SEM_Handle hSemGate = 0;
static volatile int InKernel = 0;
#if USE_LL_SEMAPHORE
//--------------------------------------------------------------------
// llEnter()
//
// Enter the IP stack
//--------------------------------------------------------------------
void llEnter()
{
// If we don't have our semaphore yet, allocate one with "1" entry
if( !hSemGate )
{
if( !(hSemGate = SEM_create( 1, 0 )) )
{
DbgPrintf(DBG_ERROR,"Could not create llEnter() semaphore");
return;
}
}
// Wait on entering the stack.
SEM_pend( hSemGate, SYS_FOREVER );
// If case something goes wrong with the semaphore, track
// problems entering the stack
if( InKernel )
DbgPrintf(DBG_ERROR,"Illegal call to llEnter()");
InKernel=1;
}
//--------------------------------------------------------------------
// llExit()
//
// Release the IP stack
//--------------------------------------------------------------------
void llExit()
{
// Handle the low resource condition
if( _TaskFlagLowResource )
{
ExecLowResource();
_TaskFlagLowResource = 0;
}
// The "InKernel" flag traps calls to llExit() before calling
// llEnter().
if( !InKernel )
{
DbgPrintf(DBG_ERROR,"Illegal call to llExit()");
return;
}
InKernel=0;
// Signal that we've exited the stack.
SEM_post( hSemGate );
}
#else
static int OldPriority = 0;
//--------------------------------------------------------------------
// llEnter()
//
// Enter the IP stack
//--------------------------------------------------------------------
void llEnter()
{
int tmpOldPriority;
// If we don't have our semaphore yet, allocate one with "0" entry
if( !hSemGate )
{
if( !(hSemGate = SEM_create( 0, 0 )) )
{
DbgPrintf(DBG_ERROR,"Could not create llEnter() semaphore");
return;
}
}
// Since this task is running (assume for now it has a priority LESS
// THAN the kernel level - we know that nothing is running at the
// kernel level.
// We try to use priority to block other calls from coming into
// llEnter(). However, if we are re-entered, we'll fall back to
// using the semaphore
// Set this task's priority at kernel level
tmpOldPriority = TaskSetPri( TaskSelf(), OS_TASKPRIKERN );
// Verify this call was legal
if( tmpOldPriority >= OS_TASKPRIKERN )
{
if( InKernel )
DbgPrintf(DBG_ERROR,"Illegal reentrant call to llEnter()");
else
DbgPrintf(DBG_ERROR,"Illegal priority call to llEnter()");
return;
}
// Verify there has been no "reentrance".
// If there was, use the semaphore.
if( ++InKernel > 1 )
{
// Wait on entering the stack.
SEM_pend( hSemGate, SYS_FOREVER );
}
// Store the priority of the task that owns kernel mode
OldPriority = tmpOldPriority;
}
//--------------------------------------------------------------------
// llExit()
//
// Release the IP stack
//--------------------------------------------------------------------
void llExit()
{
// Handle the low resource condition
if( _TaskFlagLowResource )
{
ExecLowResource();
_TaskFlagLowResource = 0;
}
// Verify we were at kernel level
if( !InKernel )
{
DbgPrintf(DBG_ERROR,"Illegal call to llExit()");
return;
}
// If a task is waiting at llEnter(), signal it
if( --InKernel > 0 )
{
// Signal that we've exited the stack.
SEM_post( hSemGate );
}
// Restore this task's priority
TaskSetPri( TaskSelf(), OldPriority );
}
#endif
//--------------------------------------------------------------------
// TaskCleanup()
//
// Private function called to cleanup tasks. The calling argument
// is a flag specifying if the task needs to clean itself.
//
// DSP/BIOS does not automatically delete tasks, so we must do it
// ourselves. This function deletes the last task (if any), and
// holds the new task handle to be deleted the next time
// TaskCleanup() is called.
//--------------------------------------------------------------------
static void TaskCleanup( uint fCleanSelf )
{
static TSK_Handle hNextTask = 0;
uint oldpri;
// We need to prevent pre-emption
oldpri = TaskSetPri( TaskSelf(), 15 );
// Delete the last task to call this function
if( hNextTask )
TSK_delete( hNextTask );
// Setup the next task handle to be deleted
if( fCleanSelf )
hNextTask = TaskSelf();
else
{
hNextTask = 0;
// Since this thread not quitting, restore priority
TaskSetPri( TaskSelf(), oldpri);
}
}
//--------------------------------------------------------------------
// TaskInit() - Called from NETCTRL init
//--------------------------------------------------------------------
void _TaskInit()
{
}
//--------------------------------------------------------------------
// TaskShutdow() - Called from NETCTRL shutdown
//--------------------------------------------------------------------
void _TaskShutdown()
{
// Delete any old task handle in TaskCleanup()
TaskCleanup( 0 );
}
//--------------------------------------------------------------------
// TaskCreate()
//
// Create a task
//--------------------------------------------------------------------
HANDLE TaskCreate( void(*pFun)(), char *Name, int Priority, uint StackSize,
UINT32 Arg1, UINT32 Arg2, UINT32 Arg3 )
{
struct TSK_Attrs ta;
TSK_Handle htsk;
// Assign to default attributes
ta = TSK_ATTRS;
// Create the system tasks
ta.priority = Priority;
ta.stack = 0;
ta.stacksize = StackSize;
ta.stackseg = 0;
ta.environ = 0;
ta.name = Name;
ta.exitflag = 0;
htsk = TSK_create( (Fxn)pFun, &ta, Arg1, Arg2, Arg3 );
return( (HANDLE)htsk );
}
//--------------------------------------------------------------------
// TaskDestroy()
//
// Destroy a task
//--------------------------------------------------------------------
void TaskDestroy( HANDLE h )
{
if( h == TSK_self() )
TaskExit();
TSK_delete( (TSK_Handle)h );
TaskCleanup( 0 );
}
//--------------------------------------------------------------------
// TaskSetEnv
//
// Sets the task's Environment pointer
//--------------------------------------------------------------------
void TaskSetEnv( HANDLE h, int Slot, HANDLE hEnv )
{
if( Slot )
return;
if( hookId == 0xffffffff )
{
DbgPrintf(DBG_ERROR,"FATAL: NDK_hookInit() must be set in DSP/BIOS HOOK config");
return;
}
if( !hookOK )
{
DbgPrintf(DBG_ERROR,"FATAL: NDK_hookCreate() must be set in DSP/BIOS HOOK config");
return;
}
HOOK_setenv( (TSK_Handle)h, hookId, (Ptr)hEnv );
}
//--------------------------------------------------------------------
// TaskGetEnv
//
// Gets the task's Environment pointer
//--------------------------------------------------------------------
HANDLE TaskGetEnv( HANDLE h, int Slot )
{
if( Slot )
return(0);
if( hookId == 0xffffffff )
{
DbgPrintf(DBG_ERROR,"FATAL: NDK_hookInit() must be set in DSP/BIOS HOOK config");
return(0);
}
if( !hookOK )
{
DbgPrintf(DBG_ERROR,"FATAL: NDK_hookCreate() must be set in DSP/BIOS HOOK config");
return(0);
}
return( (HANDLE)HOOK_getenv( (TSK_Handle)h, hookId ) );
}
//--------------------------------------------------------------------
// TaskExit()
//
// Exits and destroys a task
//--------------------------------------------------------------------
void TaskExit()
{
TaskCleanup( 1 );
TSK_exit();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -