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

📄 osport.c

📁 在ARM7和UC/OSII的平台上实现了GPS自动报站的功能,涉及GPS模块LEA_4S的驱动,位置速寻算法,语音芯片ISD4004的录放音驱动,LED页面管理等等.从启动代码到操作系统的移植以及到业
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * FILENAME: osport.c
 *
 * Copyright 1999- 2000 By InterNiche Technologies Inc. All rights reserved
 *
 *
 * MODULE: WIN32
 *
 * ROUTINES: WIN32MAIN(), dputchar(), LOCK_NET_RESOURCE(), 
 * ROUTINES: UNLOCK_NET_RESOURCE(), tcp_sleep(), usage(), post_net_setup(), 
 * ROUTINES: TK_NEWTASK(), blocklist(), npalloc(), npfree(), MEMCPY(), 
 * ROUTINES: MEMSET(), MEMMOVE(), lswap(), wintime_proc(), clock_init(), 
 * ROUTINES: clock_c(), TK_NETRX_BLOCK(), w32_tk_return(), clock_init(), 
 * ROUTINES: clock_c(), get_ptick(), tk_yield(),  *
 * PORTABLE: no
 */

/* osport.c
*/
#pragma warning(disable: 4244 4310 4115)

#define  _WINSOCKAPI_ 1
#include <windows.h>
#include "ipport.h"
#include "osport.h"

#include "winbase.h"


#ifdef USE_PPP
#include "ppp_port.h"
#include "comline.h"
#include "../mppp/mppp.h"

extern int ppp_default_type;  /* in ppp code */
extern int ppp_static;     /* number static PPP ifaces to set */
#endif /* USE_PPP */

DWORD dwVersion;
DWORD dwWindowsMajorVersion;

#define  TASK_STACK  7500  /* changeable accroding to your environment */

extern   int netmain(void);

extern   unsigned    bigbufsiz,  bigbufs, lilbufsiz,  lilbufs;
extern   char *   name;

extern   int   (*port_prep)(int);   /* hook in ..\inet\ipnet.c */
extern   int   prep_win32(int ifaces_found);
extern   int   wd_prep(int);        /* port iface prep routine to install */
extern   int   prep_ppp(int);       /* port iface prep routine to install */
extern   void  netmain_init(void);  /* initialize all modules */
int   (*ppp_type_callback)(LINEP);

int   ppp_type_setup(LINEP);

void   usage(void);

u_long   cticks   =  0; /* need to increment this later - 18 TPS? */

/* Semaphores for LOCK/UNLOCK net resource */

CRITICAL_SECTION WIN_RESID;    /* Lock for this win32 thread */

#ifdef INICHE_TASKS
static int net_task_sem = 0;   /* stack semaphore */
static int rcvq_sem = 0;       /* receiveq semaphore */
static int freeq_sem = 0;      /* free q semaphore */
static task * tk_blocked[10];  /* Tasks blocked.  Assumes max is 10 */
#else
extern void packet_chk(void);
extern int prep_modules(void);
#endif


/* When WIN32 build is used for the browser, then the WinMain()
 * would be present in the graphics libarary (MFC/PEG). Hence we need
 * to rename our main entry point. In such a case, a LIB (win32.lib) 
 * would be made from this directory, instead of an EXE (webport.exe).
 * - When webport.exe is to be made, code in this directory is compiled
 *   via "makefile". The ipport.h_h file (and other h_h files from this
 *   directory are used.
 * - When win32.lib is to be made, code in this directory is compiled
 *   via win32lib.mak, and TARGETLIB is defined in ipport.h. The ipport.h_h
 *   file in this directory is NOT used.
 */
#ifdef TARGETLIB
#define  WIN32MAIN   targmain 
#else
#define  WIN32MAIN   main 
#endif

/* scaling value to run cticks on Win2000 or Win98 */
static int os_scale;

/* FUNCTION: WIN32MAIN()
 * 
 * PARAM1: int argc
 * PARAM2: char * argv[]
 *
 * RETURNS: 
 */

int
WIN32MAIN(int argc, char * argv[])
{
   int   argx;
   char *   cp;

   /* Set windows version in global dwVersion */
   dwVersion = GetVersion();
   dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
   if (!(dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4))
   { 
      os_scale = 4;     /* Windows NT/2000 Version */
   }
   else  /* windows 98/ME */
   {
      os_scale = 1;     /* Windows 98-ish version */
   }


   /* preset buffer counts; may overwrite from command line */
   bigbufs = 50;
   lilbufs = 50;
   bigbufsiz = 1536;
   lilbufsiz = 128;

   argx = 0;
   while (++argx < argc)
   {
      if (*argv[argx] != '-')
      {
         Printu_Net("options must start with '-'\n");
         usage();
      }
      cp = argv[argx] + 1;

      switch (*cp)
      {
      case 'l':   /* large packet buffers */
         cp++;
         bigbufs = atoi(cp);
         if (bigbufs < 3 || bigbufs > MAXBIGPKTS)
         {
            printf("%s: '-l' option should be 1 - %u\n",
             name, MAXBIGPKTS);
            exit(1);
         }
         break;
      case 's':   /* small packet buffers */
         cp++;
         lilbufs = atoi(cp);
         if (lilbufs < 3 || lilbufs > MAXLILPKTS)
         {
            Printu_Net("%s: '-s' option should be 1 - %u\n",
             name, MAXLILPKTS);
            exit(1);
         }
         break;
         default:
         Printu_Net("station: invalid cmd line option %s;\n", cp);
         usage();
      }
   }

#ifdef WIN2K
   /* install win32 port prep routine in .\targport.c */
   port_prep = prep_win32;
#endif

#ifdef SUPERLOOP
   prep_modules();
#endif   /* SUPERLOOP */

#ifdef   USE_PPP
#ifdef   MINI_IP
   /* If we are using the mini IP layer and PPP, then  overwrite the 
    * NDIS hook with the PPP prep routine 
    */
   port_prep = prep_ppp;
#endif   /* MINI_IP */

   /* for all PPP inplementations, set a callback so the we can
    * set the device type of new PPP links 
    */
   ppp_default_type = LN_PORTSET;
   ppp_type_callback = ppp_type_setup;

   /* Set the number of static PPP ifaces. Allow one each for modem and
    * PPPOE, and two for Loopback-crossover.
    */
   ppp_static = 1;   /* base for modem or UART direct connect */

#ifdef LB_XOVER
   ppp_static += 2;
#endif


#ifdef NOTDEF
   /* This little block of code is usefully for testing PPPoE in loopback
    * on windows (e.g. bouncing the packets off the NDIS driver) but for
    * most purposes should not be used.
    */
#ifdef USE_PPPOE
#ifdef PPPOE_LBTEST
   ppp_static += 2;     /* loopback test needs 2 interfaces */
#else
   ppp_static++;
#endif   /* PPPOE_LBTEST */
#endif   /* USE_PPPOE */
#endif   /* NOTDEF */

#endif   /* USE_PPP */

   InitializeCriticalSection(&WIN_RESID);
#ifdef INICHE_TASKS
   {  /* parenthesis put so that "i" can be defined here */
      int i;
      for (i = 0; i < 10; i++)
         tk_blocked[i] = 0;
      return netmain();
   }
#else
   netmain_init(); 
#ifndef TARGETLIB
   /* for TARGETLIB, tk_yield() is called based on a timer. Hence
    * don't run it in infinite loop over here.
    */
   while (1)   /* loop, each module getting cycles in a round-robin fashion */ 
   {
      tk_yield();
   }
#endif
   return 0;
#endif
}


#ifdef   USE_PPP

/* FUNCTION: ppp_type_setup(M_PPP)
 *
 * This per port routine is called via ppp_type_callback whenver
 * ppp sets up a new PPP link. It should set the PPP line type 
 * (line->lower_type) based on local port configuration info 
 * (either hardcoded or read from FLASH). Possible options include:
 *
 * LN_ATMODEM - Hayes compatible dialup modem.
 * LN_PPPOE - PPP over ethernet (also needs some ethernet setup)
 * LN_LBXOVER - Loopback/crossover links for testing
 * LN_UART - direct connect via RS-232 (or similar) UART.
 *
 *    The MPPP passed already has the ifp attached and configured 
 * from NVparms, so you can use if name and IP addressing info to
 * select the types. If you need to set up other PPP mappings (like 
 * selecting a modem, uart, or ethernet device) this is a good place 
 * to do it.
 *
 * returns 0 if OK or ENP error code
 */

   /* Table to allocate PPPs in the following order:
    * 
    * #ifdef LB_XOVER, assign first two to LB_XOVER client & server
    * #ifdef USE_COMPORT, assign 1 to modem
    * #ifdef USE_PPPOE, assign 1 (or two if loopback) which will map to NDIS ethernet.
    */

static   int   ppps_already = 0;
static   int   ppp_types[] = 
{
#ifdef LB_XOVER
   LN_LBXOVER, LN_LBXOVER,
#endif
#ifdef USE_COMPORT
   LN_ATMODEM,
#endif
#ifdef USE_PPPOE
   LN_PPPOE,
#ifdef PPPOE_LBTEST
   LN_PPPOE,         /* PPPOE loopback test needs second interface */
#endif   /* PPPOE_LBTEST */
#endif USE_PPPOE

   /* extra entry are LB_XOVER for testing */
#ifdef LB_XOVER
   LN_LBXOVER, LN_LBXOVER,
   LN_LBXOVER, LN_LBXOVER,
#endif
};

extern int ifmap_bind(NET upper, NET lower);

int
ppp_type_setup(LINEP line)
{
   int err = 0;

   /* make sure we're not off the end of the static table */
   if(ppps_already > (sizeof(ppp_types)/sizeof(int)) )
   {
      /* If table is fully assigned, the set a default */
#ifdef USE_PPPOE
      line->lower_type = LN_PPPOE;
#else
      line->lower_type = LN_ATMODEM;
#endif
      dprintf("ppp_type_setup (win32) defaulting type to %d\n", line->lower_type);
   }

   line->lower_type = ppp_types[ppps_already++];  /* assign next type */

   /* If it's PPPoE we need to assign it to an ethernet interface too */
#ifdef USE_PPPOE
   if(ppp_types[ppps_already - 1] == LN_PPPOE)
   {
      NET ifp;

      /* find first ethernet interface */
      for(ifp = (NET)netlist.q_head; ifp; ifp = ifp->n_next)
      {
         if(ifp->mib.ifType == ETHERNET)
         {
            M_PPP mppp;
            /* bind PPP iface for this line (upper) to ethernet (lower) */
            mppp = (M_PPP)(line->upper_unit);
            ifmap_bind(mppp->ifp, ifp);
#ifdef PPPOE_LBTEST
            /* for PPPOE loopback it helps to add routes */
#endif   /* PPPOE_LBTEST */
            break;
         }
      }
      /* If no ethernet was found then set error code */
      if(!ifp)
         err = ENP_LOGIC;
   }
#endif   /* USE_PPPOE */

   return err;   /* OK return */
}
#endif   /* USE_PPP */


/* dputchar() - this is the port-dependant portion of the 
 * redirectable output package (ttyio.c). dstdio is NULL for the 
 * screen/keyboard, or a pointer to an output device, such as a file 
 * or socket. This sends each char to dstdio device. 
 */
extern   void *   dstdio;
extern   void putch(int);



/* FUNCTION: dputchar()
 * 
 * PARAM1: int chr
 *
 * RETURNS: 
 */

void
dputchar(int chr)    /* put character to DOS console device */
{
   putch(chr);
}





/* FUNCTION: usage()
 * 
 * PARAM1: 
 *
 * RETURNS: 
 */

void
usage()
{
   Printu_Net("usage: %s [-sX -lX] \n", name);
   Printu_Net("   -s sets the number of small packet buffers.\n");
   Printu_Net("   -l sets the number of large packet buffers.\n");
   exit(1);
}



#ifdef INICHE_TASKS

/* FUNCTION: tcp_sleep()
 * 
 * PARAM1: void * event
 *
 * RETURNS: 
 */

void
tcp_sleep(void * event)
{
   UNLOCK_NET_RESOURCE(NET_RESID);
   tk_ev_block(event);
   LOCK_NET_RESOURCE(NET_RESID);
}

/* post_net_setup() - no-op on this port */

/* FUNCTION: post_net_setup()
 * 
 * PARAM1: void
 *
 * RETURNS: 
 */

char *   
post_net_setup(void)
{
   return NULL;
}


/* FUNCTION: LOCK_NET_RESOURCE()
 * 
 * PARAM1: int resid
 *
 * RETURNS: void 
 *
 * This uses a Windows EnterCriticalSection call to protect the code.
 * It then increments a semaphore per resource as a way to lock the
 * resource.  In the case of NET_RESID only it blocks the calling
 * task and wakes it up in the UNLOCK_NET_RESOURCE call
 */

void
LOCK_NET_RESOURCE(int resid)
{
   int   i;
   EnterCriticalSection((LPCRITICAL_SECTION)&WIN_RESID);
   switch (resid)
   {
   case NET_RESID:

      /* block this task and wake it when the UNLOCK happens */

      while (net_task_sem)
      {
         /* If the task is already blocked, exit the for loop */
	 
         for (i=0; i < 10; i++)
         {
            if (tk_blocked[i] == 0)
            {
               tk_blocked[i] = tk_cur;
	       break;
            }
            else
	       if (strcmp(tk_blocked[i]->tk_name, tk_cur->tk_name) == 0)
                  break;
         }
	 if (i == 10)
	    panic("lock NetResid\n");
         tk_block();
      }

      net_task_sem++; /* lock the resource */
      break;

   case RXQ_RESID:
      if (rcvq_sem) 
         panic("lock ReceiveQ\n");
      rcvq_sem++;     /* lock the resource */
      break;

   case FREEQ_RESID:
      if (freeq_sem)
         panic("lock FreeQ\n");
      freeq_sem++;    /* lock the resource */
      break;
   }
   LeaveCriticalSection((LPCRITICAL_SECTION)&WIN_RESID);
}



/* FUNCTION: UNLOCK_NET_RESOURCE()
 * 
 * PARAM1: int resid
 *
 * RETURNS: void
 *
 * This call unlocks the respective semaphores by decrementing a global flag.
 * This also protects the code by using the Windows Critical Section macros.
 * In the case of NET_RESID only it wakes any blocked tasks. 
 */

void
UNLOCK_NET_RESOURCE(int resid)
{
   int   i; task *   tmp_task_ptr;
   EnterCriticalSection((LPCRITICAL_SECTION)&WIN_RESID);
   switch (resid)
   {
   case NET_RESID:
      net_task_sem--; /* unlock the resource */
      for (i = 0; i < 10; i++)
      {
         if (tk_blocked[i] != 0)
         {
            tmp_task_ptr = tk_blocked[i];
            tk_blocked[i] = 0;
            tk_wake(tmp_task_ptr);
            break;
         }
      }
      break;

   case RXQ_RESID:
      if (!rcvq_sem)
         panic("lock ReceiveQ\n");
      rcvq_sem--;  /* unlock the resource */
      break;

   case FREEQ_RESID:
      if (!freeq_sem)
         panic("lock FreeQ\n");
      freeq_sem--; /* unlock the resource */
      break;
   }
   LeaveCriticalSection((LPCRITICAL_SECTION)&WIN_RESID);
}



/* FUNCTION: TK_NEWTASK()
 * 
 * PARAM1: struct inet_taskinfo * nettask
 *
 * RETURNS: 
 */

int
TK_NEWTASK(struct inet_taskinfo * nettask)
{
   task * new_task;

   if (nettask == &nettasks[0])  /* should be at head of list */
   {
      if (*(nettask->name) != 'I')  /* double check */
         panic("nettask");
      new_task = tk_init( tk_getsp() - (TASK_STACK/sizeof(stack_t)), TASK_STACK);

      /* Some configurations need the clock running upon return from this
       * first call, so start it now rather than waiting for the callback
       * to clock_init() from the IP startup code. 
       */
      clock_init();
   }
   else
   {
      new_task = tk_new(tk_cur, nettask->entry, 
       nettask->stacksize, nettask->name, 0);
   }

   if (new_task)
   {
      *nettask->tk_ptr = new_task;
      return 0;
   }
   else
   {
      return 0;
   }
}

#endif   /* INICHE_TASKS */

/* **** InterNiche memory managment debug hooks **** */

⌨️ 快捷键说明

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