📄 netctrl.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)
*/
//--------------------------------------------------------------------------
// Net Control Shell Library
//--------------------------------------------------------------------------
// NETCTRL.C
//
// Shell functions for simplified net startup and shutdown
//
// The idea behind this API is to hide the user callable HAL/STACK functions
//
// Author: Michael A. Denio
// Copyright 1999, 2001 by Texas Instruments Inc.
//--------------------------------------------------------------------------
#include <std.h>
#include <sys.h>
#include <sem.h>
#include <tsk.h>
#include <netmain.h>
#include <_stack.h>
#include <_oskern.h>
// Static Event Object
static STKEVENT stkEvent;
// Network Halt Flag and Return Code
static int NetHaltFlag;
static int NetReturnCode;
// System Info
static int SystemOpen = 0;
static int SchedulerPriority = 0;
// Stack Event Scheduler
static void NetScheduler( uint const SerialCnt, uint const EtherCnt );
// User's Network start and stop functions
static uint flagSysTasks = 0; // Set if we've called user functions
static void (*NetStartFun)() = 0; // User start function ptr
static void (*NetStopFun)() = 0; // User stop function ptr
static void (*NetIPFun)(IPN,uint,uint) = 0; // User IP addr function ptr
//
// NC_SystemOpen()
//
// Initialize the OS to run NET applications
//
int NC_SystemOpen( int Priority, int OpMode )
{
SEM_Handle hSem = 0;
// Open the low-level enironment
// Set the network scheduler priority
if( Priority != NC_PRIORITY_LOW && Priority != NC_PRIORITY_HIGH )
return(NC_OPEN_ILLEGAL_PRIORITY);
SchedulerPriority = Priority;
// Check the operating mode
if( OpMode != NC_OPMODE_POLLING && OpMode != NC_OPMODE_INTERRUPT )
return(NC_OPEN_ILLEGAL_OPMODE);
// Polling at high priority is illegal
if( Priority==NC_PRIORITY_HIGH && OpMode==NC_OPMODE_POLLING )
return(NC_OPEN_ILLEGAL_OPMODE);
// Intialize the task environment
_TaskInit();
// Initialize memory
if( !_mmInit() )
return(NC_OPEN_MEMINIT_FAILED);
// Create the event semaphore
if( OpMode==NC_OPMODE_INTERRUPT && !(hSem = SEM_create(0,0)) )
return(NC_OPEN_EVENTINIT_FAILED);
// Initialize our Event object
STKEVENT_init( &stkEvent, hSem );
// Open the packet buffer manager
PBM_open();
// Initialize our part of the configuration system
NS_PreBoot();
SystemOpen = 1;
return(NC_OPEN_SUCCESS);
}
//
// NC_SystemClose()
//
// Complete closing down the NET environment
//
void NC_SystemClose()
{
SystemOpen = 0;
// Delete the event semaphore
if( stkEvent.hSemEvent )
{
SEM_delete( stkEvent.hSemEvent );
stkEvent.hSemEvent = 0;
}
// Close the packet buffer manager
PBM_close();
// Close the task environment
_TaskShutdown();
// Perform final memory check (should be no allocated blocks)
_mmCheck( MMCHECK_SHUTDOWN, &printf );
}
//
// NC_NetStart()
//
// Initialize stack environment
//
int NC_NetStart( HANDLE hCfg, void (*NetStart)(),
void (*NetStop)(), void (*NetIP)(IPN,uint,uint) )
{
uint EtherDeviceCount = 0;
uint SerialDeviceCount = 0;
uint i;
HANDLE hEther[4] = { 0, 0, 0, 0 };
// Make sure we're ready to run
if( !SystemOpen )
return(0);
// Initialize our state to be "not halted"
NetHaltFlag = 0;
// Initialize the timer
//
// If we wanted, we could initialize the timer value with the
// seconds elapsed from some standard time (1-1-70, 1-1-80, etc.).
//
_llTimerInit( &stkEvent, 0 );
// Initialize the User LED driver
_llUserLedInit();
// Initialize the serial port
SerialDeviceCount = _llSerialInit( &stkEvent );
if( SerialDeviceCount > 1 )
SerialDeviceCount = 1;
// Initialize the packet drivers
EtherDeviceCount = _llPacketInit( &stkEvent );
if( EtherDeviceCount > 4 )
EtherDeviceCount = 4;
// Set the deault config handle
CfgSetDefault( hCfg );
// Record the function pointers
NetStartFun = NetStart;
NetStopFun = NetStop;
NetIPFun = NetIP;
// Initialize the stack executive
ExecOpen();
// Enter the kernel
llEnter();
// Create an Ethernet Device for each physical device
for(i=0; i<EtherDeviceCount; i++)
{
// Create the Ethernet object. Note the physical index
// is "1" based.
hEther[i] = EtherNew(i+1);
// We must configure the Ethernet device. This is so
// we can handle non-standard devices.
if( hEther[i] )
EtherConfig( hEther[i], 1518, 14, 0, 6, 12, 4 );
}
// Exit the kernel
llExit();
// Boot the configuration
TaskCreate( NS_BootTask, "ConfigBoot", OS_TASKPRINORM, 4096,
(UINT32)hCfg, 0, 0 );
// Start running the stack
NetScheduler(SerialDeviceCount,EtherDeviceCount);
// Disable the configuration
CfgExecute( hCfg, 0 );
// Call the Net stop function
if( !flagSysTasks )
printf("\n\nWARNING: Boot thread has not completed!\n\n");
else
{
flagSysTasks = 0;
if( NetStopFun )
(*NetStopFun)();
}
//
// In order for the system to settle out properly, we must
// be "OS_SCHEDULER_LOWPRI" at this point.
//
TSK_setpri( TSK_self(), OS_SCHEDULER_LOWPRI );
llEnter();
// Close our Ether devices
for(i=0; i<EtherDeviceCount; i++)
if( hEther[i] )
EtherFree( hEther[i] );
llExit();
// Shutdown the stack
ExecClose();
// Clear function callbacks
NetStartFun = 0;
NetStopFun = 0;
NetIPFun = 0;
// Clear the deault config handle
CfgSetDefault( 0 );
// Shutdown the low-level environment
_llPacketShutdown();
_llSerialShutdown();
_llUserLedShutdown();
_llTimerShutdown();
return( NetReturnCode );
}
//
// NC_NetStop()
//
// Initiate system shutdown
//
void NC_NetStop( int rc )
{
NetReturnCode = rc;
NetHaltFlag = 1;
}
//
// NC_BootComplete()
//
// Boot thread has completed
//
void NC_BootComplete()
{
if( !flagSysTasks )
{
flagSysTasks = 1;
if( NetStartFun )
(*NetStartFun)();
}
}
//
// NC_IPUpdate( IPN IPAddr, uint fAdd )
//
// Boot thread has completed
//
void NC_IPUpdate( IPN IPAddr, uint IfIdx, uint fAdd )
{
if( NetIPFun )
(*NetIPFun)( IPAddr, IfIdx, fAdd );
}
//--------------------------------------------------------------------
// NetScheduler()
//
// Check for stack related events for Timer, Ethernet, and Serial.
//
// Returns: Stack exit code
//--------------------------------------------------------------------
#define FLAG_EVENT_TIMER 1
#define FLAG_EVENT_ETHERNET 2
#define FLAG_EVENT_SERIAL 4
static void NetScheduler( uint const SerialCnt, uint const EtherCnt )
{
register int fEvents;
// Set the scheduler priority
TSK_setpri( TSK_self(), SchedulerPriority );
// Enter scheduling loop
while( !NetHaltFlag )
{
if( stkEvent.hSemEvent )
{
SEM_pend( stkEvent.hSemEvent, SYS_FOREVER );
SEM_reset( stkEvent.hSemEvent, 0 );
}
// Clear our event flags
fEvents = 0;
// First we do driver polling. This is done from outside
// kernel mode since pure "polling" drivers can not spend
// 100% of their time in kernel mode.
// Check for a timer event and flag it
if( stkEvent.EventCodes[STKEVENT_TIMER] )
{
stkEvent.EventCodes[STKEVENT_TIMER] = 0;
fEvents |= FLAG_EVENT_TIMER;
}
// Poll only once every timer event for ISR based drivers,
// and continuously for polling drivers. Note that "fEvents"
// can only be set to FLAG_EVENT_TIMER at this point.
if( fEvents || !stkEvent.hSemEvent )
{
// Poll Ethernet Packet Devices
if( EtherCnt )
_llPacketServiceCheck( fEvents );
// Poll Serial Port Devices
if( SerialCnt )
_llSerialServiceCheck( fEvents );
}
//
// Note we check for Ethernet and Serial events after
// polling since the ServiceCheck() functions may
// have passively set them.
//
// Check for a Ethernet event and flag it
if(EtherCnt && stkEvent.EventCodes[STKEVENT_ETHERNET] )
{
// We call service check on an event to allow the
// driver to do any processing outside of kernel
// mode that it requires, but don't call it if we
// already called it due to a timer event or by polling
if( !(fEvents & FLAG_EVENT_TIMER) && stkEvent.hSemEvent )
_llPacketServiceCheck( 0 );
// Clear the event and record it in our flags
stkEvent.EventCodes[STKEVENT_ETHERNET] = 0;
fEvents |= FLAG_EVENT_ETHERNET;
}
// Check for a Serial event and flag it
if(SerialCnt && stkEvent.EventCodes[STKEVENT_SERIAL] )
{
// We call service check on an event to allow the
// driver to do any processing outside of kernel
// mode that it requires, but don't call it if we
// already called it due to a timer event or by polling
if( !(fEvents & FLAG_EVENT_TIMER) && stkEvent.hSemEvent )
_llSerialServiceCheck( 0 );
// Clear the event and record it in our flags
stkEvent.EventCodes[STKEVENT_SERIAL] = 0;
fEvents |= FLAG_EVENT_SERIAL;
}
// Process current events in Kernel Mode
if( fEvents )
{
// Enter Kernel Mode
llEnter();
// Check for timer event
if( fEvents & FLAG_EVENT_TIMER )
ExecTimer();
// Check for packet event
if( fEvents & FLAG_EVENT_ETHERNET )
llPacketService();
// Check for serial port event
if( fEvents & FLAG_EVENT_SERIAL )
llSerialService();
// Exit Kernel Mode
llExit();
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -