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

📄 pktdrv.c

📁 picoos源码。The RTOS and the TCP/IP stack will be built automatically.
💻 C
📖 第 1 页 / 共 2 页
字号:
  buf = lpPacket->Buffer;

  off=0;

  while (off<ulBytesReceived)
  { 
    //if (kbhit())return;
    hdr=(struct bpf_hdr *)(buf+off);
    tlen1=hdr->bh_datalen;
    cur_length=tlen1;
    tlen=hdr->bh_caplen;
    off+=hdr->bh_hdrlen;

    ulLines = (tlen + 15) / 16;
    if (ulLines > 5) ulLines=5;

    base =(char*)(buf+off);
    cur_packet=base;
    off=Packet_WORDALIGN(off+tlen);

    process_input();
  }
}

void update_adapter(void)
{
  if (PacketReceivePacket(lpAdapter,lpPacket,TRUE)==TRUE)
    ProcessPackets(lpPacket);
  cur_length=0;
  cur_packet=NULL;
}




/*-----------------------------------------------------------------------------------
 *  Hardware Emulation API
 *  The following code emulates a real hardware NIC.
 *  The registers of the NIC are defined in pktdrv.h
 *---------------------------------------------------------------------------------*/
#ifdef NIC_EMU

#define PEXTERN  extern
#include "pktdrv.h"
#include <port.h>

static unsigned long volatile intStatus;
static int           volatile runtasks;
static int           volatile rxtaskStopped;
static int           volatile txtaskStopped;
static HANDLE                 rxWaitSemaphore;
static HANDLE                 txWaitSemaphore;


void _pk_notify(volatile unsigned long* reg, unsigned long v)
{
  if (reg == &pkregister.notify_flags)
  {
    if (v & PK_NFLAG_TRANSMITNOW)
    {
      pkregister.txpsize[pkregister.txbuf_in] = pkregister.packetsize;
      pkregister.txbuf_in = (pkregister.txbuf_in + 1) % PK_TXBUFFER;
      ReleaseSemaphore(txWaitSemaphore, 1, NULL);
    }
    if (v & PK_NFLAG_RECEIVENEXT)
    {
      pkregister.rxbuf_out = (pkregister.rxbuf_out + 1) % PK_RXBUFFER;
      ReleaseSemaphore(rxWaitSemaphore, 1, NULL);
    }
    pkregister.notify_flags = 0;
  }
}


unsigned long _pk_readreg(volatile unsigned long* reg)
{
  unsigned long ret;
  long i;

  if (reg == &pkregister.int_status)
  {
    singleThreadEnter();
    ret = intStatus;
    intStatus = 0;
    singleThreadExit();
  }
  else
  if (reg == &pkregister.fifo_status)
  {
    ret = 0;
    i = (long)pkregister.txbuf_out - (long)pkregister.txbuf_in - 1;
    if (i < 0) i += PK_TXBUFFER;
    if (i > 0)
      ret |= PK_FSTATUS_TXBFREE;
    if (pkregister.rxbuf_in != pkregister.rxbuf_out)
      ret |= PK_FSTATUS_RECEIVED;
  }
  else
  if (reg == &pkregister.txbuf_adr)
  {
    ret = (unsigned long) &pkregister.txbuffer[pkregister.txbuf_in][0];
  }
  else
  if (reg == &pkregister.rxbuf_adr)
  {
    ret = (unsigned long) &pkregister.rxbuffer[pkregister.rxbuf_out][0];
  }
  else
  if (reg == &pkregister.packetsize)
  {
    ret = pkregister.rxpsize[pkregister.rxbuf_out];
  }
  else
  {
    ret = *reg;
  }
  return ret;
}


extern void nic_interrupt(void);

static void exec_interrupt(unsigned long irqstatus)
{
  unsigned long newis;
  if (((irqstatus & PK_ISTATUS_TX) && (pkregister.int_mask & PK_IMASK_TX)) ||
      ((irqstatus & PK_ISTATUS_RX) && (pkregister.int_mask & PK_IMASK_RX)))
  {
    newis = intStatus | irqstatus;
    if (newis != intStatus)
    {
      intStatus = newis;
      callInterruptHandler( nic_interrupt );
    }
  }
}


static void process_input(void)
{
  static const unsigned char bcast[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
  unsigned long i, o, n;

  if ((memcmp(cur_packet, ethaddr, 6) == 0) ||
      (memcmp(cur_packet, bcast,   6) == 0))
  {
    for (;;)
    {
      i = pkregister.rxbuf_in;
      o = pkregister.rxbuf_out % PK_RXBUFFER;
      n = (i + 1) % PK_RXBUFFER;
      if ((n == o) && (runtasks > 0))
      {
        WaitForSingleObject(rxWaitSemaphore, 50);
      }
      else
      {
        break;
      }
    }
    if (n != o)
    {
      if (cur_length > PK_TBUFSIZE)
        cur_length = PK_TBUFSIZE;
      memcpy(pkregister.rxbuffer[i], cur_packet, cur_length);
      pkregister.rxpsize[i] = cur_length;
      singleThreadEnter();
      pkregister.rxbuf_in = n;
      exec_interrupt(PK_ISTATUS_RX);
      singleThreadExit();
    }
  }
}


static DWORD WINAPI rx_thread(LPVOID param)
{
  (void) param;

  SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);
  while (runtasks == 0)  Sleep(5);

  while (runtasks > 0)
  {
    update_adapter();
  }
  rxtaskStopped = 1;
  return 0;
}


static DWORD WINAPI tx_thread(LPVOID param)
{
  unsigned long i;
  (void) param;

  SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);
  while (runtasks == 0)  Sleep(5);

  while (runtasks > 0)
  {
    i = pkregister.txbuf_out;
    if (i != pkregister.txbuf_in)
    {
      packet_send(pkregister.txbuffer[i], pkregister.txpsize[i]);
      singleThreadEnter();
      pkregister.txbuf_out = (i + 1) % PK_TXBUFFER;
      exec_interrupt(PK_ISTATUS_TX);
      singleThreadExit();
    }
    else
    {
      WaitForSingleObject(txWaitSemaphore, 50);
    }
  }
  txtaskStopped = 1;
  return 0;
}


int pktdrv_start(int adapter_num)
{
  int status;
  DWORD tid;
  HANDLE th;

  intStatus = 0;
  memset(&pkregister, 0, sizeof(pkregister));
  status = init_adapter(adapter_num);
  if (status >= 0)
  {
    pkregister.mac_lo = *((unsigned long*) (ethaddr+2));
    pkregister.mac_hi = *((unsigned long*) ethaddr) & 0xFFFF;

    PacketSetMinToCopy(lpAdapter, 1);
    PacketSetReadTimeout(lpAdapter, 50);

    rxWaitSemaphore = CreateSemaphore(NULL, 0, 1, NULL);
    if (rxWaitSemaphore == NULL)
    {
      shutdown_adapter();
      return -1;
    }
    txWaitSemaphore = CreateSemaphore(NULL, 0, 1, NULL);
    if (txWaitSemaphore == NULL)
    {
      CloseHandle(rxWaitSemaphore);
      shutdown_adapter();
      return -1;
    }

    runtasks = 0;
    rxtaskStopped = 0;
    txtaskStopped = 0;
    th = CreateThread(NULL, 0, rx_thread, NULL, 0, &tid);
    if (th == NULL)
    {
      CloseHandle(txWaitSemaphore);
      CloseHandle(rxWaitSemaphore);
      shutdown_adapter();
      return -1;
    }
    th = CreateThread(NULL, 0, tx_thread, NULL, 0, &tid);
    if (th == NULL)
    {
      runtasks = -1;
      ReleaseSemaphore(rxWaitSemaphore, 1, NULL);
      while (rxtaskStopped == 0) Sleep(10);
      CloseHandle(txWaitSemaphore);
      CloseHandle(rxWaitSemaphore);
      shutdown_adapter();
      return -1;
    }
    runtasks = 1;
    Sleep(10);
  }
  return status;
}


void pktdrv_stop(void)
{
  if (runtasks > 0)
  {
    runtasks = -1;
    ReleaseSemaphore(txWaitSemaphore, 1, NULL);
    ReleaseSemaphore(rxWaitSemaphore, 1, NULL);
    while ((rxtaskStopped == 0) || (txtaskStopped == 0))  Sleep(50);
  }
  CloseHandle(txWaitSemaphore);
  CloseHandle(rxWaitSemaphore);
  shutdown_adapter();
}


#endif /* NIC_EMU */

⌨️ 快捷键说明

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