6885|1

5

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

OMAPL138以太网通讯ping通老是超时 [复制链接]

我用的是OMAPL138的芯片,网卡是KSZ8041FTL,用的平台是CCS3.3,调试dsp,并且移植了Ucos操作系统,我把板子的网口和主机的网口用网线连起来,然后在主机的cmd中ping板子的IP地址,到目前为止就出现2次ping通,而且ping通了一下就超时了,一次丢包率是50%,另一次是75%。到目前为止我还找不到啥问题,可否请知道的人士请帮忙啊,我现在没有在linux下用,只在平常的PC机上用CCS,而且程序里面移植了Ucos代码,现在不知道从何下手了,网络部分初始化都是按照MDIO&EMAC文档上面操作的,其他的话,也不知道从何调试开始。


代码其中之一:                                                        //-----------------------------------------------------------------------------
// \file    evmomapl138_emac.c
// \brief   implementation of the emac/mdio driver for the OMAP-L138 EVM.
//
//-----------------------------------------------------------------------------
#include "stdio.h"
#include "string.h"
#include "os_cpu_isr.h"
#include "includes.h"
#include "inc/evmomapl138_emac.h"
#include "inc/types.h"
#include "evmomapl138.h"
#include "evmomapl138_timer.h"
#include "inc/ethernet_smsc.h"
#include "inc/evmomapl138_gpio.h"
#include "inc/evmomapl138_i2c_gpio.h"
#include "inc/evmomapl138_cdce913.h"
#include "evmomapl138_aintc.h"   // add_ISR需要
#include "netif/etharp.h"
#include "Emac_des.h"
#include "ethernetif.h"
#ifndef USE_HDTIME_DLY
#define USTIMER_delay(x)               
#endif //USE_HDTIME_DLY
#define MAX_POLLING_NUM                (0x0FFFFFFF)
//-----------------------------------------------------------------------------
// Private Defines and Macros
//-----------------------------------------------------------------------------
// INTCONTROL >> INTPRESCALE , number of EMAC clk period within a 4 us time window
#define NUM_INTPRESCALE    (4*SYSCLOCK4_HZ/1000000)  //4/(1000000/SYSCLOCK4_HZ) , 4us
// mdio clock divide down value.
#define MDIO_CLK_FREQ_HZ   (2000000)  //2M HZ
#define MDIO_CLK_DIVISOR   ((SYSCLOCK4_HZ / MDIO_CLK_FREQ_HZ) - 1)
// rx / tx desriptor memory offsets.
#define RX_DESC_OFFSET     (0)
#define TX_DESC_OFFSET     (0x1000)
//MII pinmux
#define PINMUX_MII_REG_0         (2)
#define PINMUX_MII_MASK_0        (0xFFFFFFF0)
#define PINMUX_MII_VAL_0         (0x88888880)
#define PINMUX_MII_REG_1         (3)
#define PINMUX_MII_MASK_1        (0xFFFFFFFF)
#define PINMUX_MII_VAL_1         (0x88888888)
//RMII pinmux
#define PINMUX_RMII_REG_0        (14)
#define PINMUX_RMII_MASK_0       (0xFFFFFF00)
#define PINMUX_RMII_VAL_0        (0x88888800)
#define PINMUX_RMII_REG_1        (15)
#define PINMUX_RMII_MASK_1       (0x000000FF)
#define PINMUX_RMII_VAL_1        (0x00000080)
//MDIO pinmux
#define PINMUX_MDIO_REG          (4)
#define PINMUX_MDIO_MASK         (0x000000FF)
#define PINMUX_MDIO_VAL          (0x00000088)
//GPIO pinmux
#define PINMUX_MII_MDIO_EN_REG         (6)
#define PINMUX_MII_MDIO_EN_MASK         (0x000000F0)
#define PINMUX_MII_MDIO_EN_VAL         (0x00000080)
//
#define EMAC_RMII_SPEED_100                 (0x00008000)
//-----------------------------------------------------------------------------
// Private Static Variables
//-----------------------------------------------------------------------------
static uint8_t g_active_phy_id = 0x0; //我们选用的L138是phy_id是为0的
//-----------------------------------------------------------------------------
// Private Function Prototypes
//-----------------------------------------------------------------------------
static uint32_t initMdioPhy(void);
static uint8_t isLinkActive(uint8_t in_phy);
static uint16_t phyRegRead(uint8_t in_phy, uint8_t in_reg);
static void phyRegWrite(uint8_t in_phy, uint8_t in_reg, uint16_t in_data);
//----------------------------------------------------------------------------
//Public value definitions
//----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Public Function Definitions
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// \brief   initialize the EMAC and MDIO for use.
//
// \param   none.
//
// \return  uint32_t
//    ERR_NO_ERROR - everything is ok...emac ready to use.
//    ERR_INIT_FAIL - something happened during initialization.
//-----------------------------------------------------------------------------
uint32_t Lowlevel_Emac_Init(void)
{
   uint32_t rtn = 0;
   uint32_t i;
  SYS_ARCH_DECL_PROTECT(sr);
  SYS_ARCH_PROTECT(sr);
   // reset emac module.
   EMAC->SOFTRESET = 1;
        while (EMAC->SOFTRESET != 0) {;}
        //init emac control module
        //----------------------------------------
        // AddISR() -- configuration of the interrupt to the CPU.
        //AINTC --Number34 core0 Receive Interrupt
        AddISR(34,L138Ethif_RxHandler,(void *)0);
        aintcRegs->SICR = 34; //clear index status
        aintcRegs->CMR8 = 0x00170000;//(Sets channel map, system interrupt --> host channel interrupt )
    aintcRegs->EISR = 34; //Enable Index Set Register
        aintcRegs->SECR2 = 0x00000004; //34 status clear  
        //configure Tx Interrupt Handler
        AddISR(35,L138Ethif_TxHandler,(void *)0);
        aintcRegs->SICR = 35; //clear index status
        aintcRegs->CMR8 = 0x18000000; //SETS CHannel map
        aintcRegs->EISR = 35; //Enable Index Set Register
        aintcRegs->SECR2 = 0x00000008; //clear 35 status register ...
        // configure INTCONTORL , CnRXIMAX, CnTXIMAX,
        EMAC_CTRL->INTCTL = (NUM_INTPRESCALE| 0x00000300);
        EMAC_CTRL->C0RXIMAX = 2;
        EMAC_CTRL->C0TXIMAX = 2;
        //--& init emac module.
   //------------------
   
        // make sure emac control interrupts are disabled.
   EMAC_CTRL->C0RXTHRESHEN = 0;
   EMAC_CTRL->C1RXTHRESHEN = 0;
   EMAC_CTRL->C2RXTHRESHEN = 0;
   EMAC_CTRL->C0RXEN = 0;
   EMAC_CTRL->C1RXEN = 0;
   EMAC_CTRL->C2RXEN = 0;
   EMAC_CTRL->C0TXEN = 0;
   EMAC_CTRL->C1TXEN = 0;
   EMAC_CTRL->C2TXEN = 0;
   EMAC_CTRL->C0MISCEN = 0;
   EMAC_CTRL->C1MISCEN = 0;
   EMAC_CTRL->C2MISCEN = 0;
   EVMOMAPL138_pinmuxConfig(PINMUX_MDIO_REG, PINMUX_MDIO_MASK, PINMUX_MDIO_VAL);                                           //MDIO shared by both RMII and MII
//   EVMOMAPL138_pinmuxConfig(PINMUX_MII_MDIO_EN_REG, PINMUX_MII_MDIO_EN_MASK, PINMUX_MII_MDIO_EN_VAL); //pinmux to select gpio bank2 pin6
            
           //PINMUXING
    EVMOMAPL138_pinmuxConfig(PINMUX_MII_REG_0, PINMUX_MII_MASK_0, PINMUX_MII_VAL_0);
    EVMOMAPL138_pinmuxConfig(PINMUX_MII_REG_1, PINMUX_MII_MASK_1, PINMUX_MII_VAL_1);
      
    SYSCONFIG->KICKR[0] = KICK0R_UNLOCK;
    SYSCONFIG->KICKR[1] = KICK1R_UNLOCK;
    CLRBIT(SYSCONFIG->CFGCHIP[3], 0x00000100); //select mii mode !
        //as software reset consideration, do this here
   EVMOMAPL138_lpscTransition(PSC1, DOMAIN0, LPSC_EMAC, PSC_ENABLE);
   // clear MAC control register, receive control register, transmiter control register
        EMAC->MACCONTROL = 0;
        EMAC->RXCONTROL = 0;
        EMAC->TXCONTROL = 0;
  // init header descriptor pointer regs to 0.
     for (i = 0; i < 8; i++)
     {
       EMAC->TXHDP = 0;
       EMAC->RXHDP = 0;
     }
   // clear all statistic register
#ifndef BOOT
   memset((uint8_t *)NET_STAT_REG_BASE, 0, NET_STAT_REG_NUM_BYTES);
#endif
   // setup local MAC address, only channel 0 is valid.
   // program all 8, only need to set MACADDRHI for index = 0.
   // use duplicate address for all unused channels.
   // TODO: read MAC address from SPI flash.
   //写的顺序是MACINDEX, ADDRHI, ADDRLO,由于高40bits是共享的
   //只用了通道0,EMAC->MACADDRLO = 0X000000506 |VALID|MATCHFILT
   for (i = 1; i < 8; i++)
   {
      EMAC->MACINDEX = i;
          EMAC->MACADDRHI = 0x42020304; //index -> hi -> lo
      EMAC->MACADDRLO = 0x00000506;         
   }
   EMAC->MACINDEX = 0;
   EMAC->MACADDRHI = 0x42020304;
   // channel bit = 0, match mac address = 1
   EMAC->MACADDRLO = 0x00000506 | MACADDRLO_VALID | MACADDRLO_MATCHFILT;
    // for use tx DMA descriptor configuration:
    EMAC->MACSRCADDRHI = 0x42020304;
        EMAC->MACSRCADDRLO = 0x00000506;
   // initialize receive channel free buffer count regs, if buffer flow
   // control is to be enabled.
   // NOTE: this example does not use buffer flow control.
   // enable unicast chan 0 only.
   EMAC->RXUNICASTSET = 0x01;
   
   // no multicast addresses, clear MAC address hash registers.
   EMAC->MACHASH1 = 0;
   EMAC->MACHASH2 = 0;
   // 只允许broadcast的ARP数据包,和发给自己的包,以太网的其他数据不放入Memmory里去.
   //但是我单独设置RxBroadEn却没有作用。
   EMAC->RXMBPENABLE = 0;
   SETBIT(EMAC->RXMBPENABLE, (RXBROADEN|RXCAFEN));
// EMAC->RXMBPENABLE = 0x01E02020;                //enable reception of almost all frames inc error
   
   //11. configure MACCONTROL (Don't set GMIIEN Bit)
   SETBIT(EMAC->MACCONTROL, (RMIISPEED|FULLDUPLEX|TXPACE)); //RMII_SPEED,为了适应RMII
  
        // 12. Clear all unused channel interrupt bits by writing the receive interrupt mask clear register
        //(RXINTMASKCLEAR) and the transmit interrupt mask clear register (TXINTMASKCLEAR).
        EMAC->RXINTMASKCLEAR |= 0xFE; //RX channel 0的中断不屏蔽
        EMAC->TXINTMASKCLEAR |= 0xFE; //TX CH0 中断屏蔽
        //13. Modify RXINTMASKSET, TXINTMASKSET,MACINTMASKSET
        EMAC->RXINTMASKSET |= 0x01;
        EMAC->TXINTMASKSET |= 0x01;
        EMAC->MACINTMASKCLR = 0x03; //disabled host mask , stat interrupt
   
   //14 init receive buffer offset and max length.
   EMAC->RXBUFFEROFFSET = 0;
   EMAC->RXMAXLEN = MAX_PACKET_SIZE;
   
   // initialize receive/transmit descriptor list queues.
   Emac_des_init(); //modify 04/18
   //16 enable receive / transmit DMA controllers...set GMIIEN.
   EMAC->RXCONTROL = 1;
   EMAC->TXCONTROL = 1;
   SETBIT(EMAC->MACCONTROL, GMIIEN );
#if 1   //文档说未经测试,删除貌似没效果啊,先不管它
   SETBIT(EMAC->EMCONTROL, SOFT);
#endif
   // -->& init mdio / phy, 再加上MAC中断
   //-----------------
   rtn = initMdioPhy();
//   if (rtn != ERR_NO_ERROR)
//      return (rtn);
    SYS_ARCH_UNPROTECT(sr);
   //17>Enable the device interrupt in EMAC control module registers CnRXTHRESHEN, CnRXEN, CnTXEN,
   //and CnMISCEN. -- LP Add
        EMAC_CTRL->C0RXEN = 1; //C0RXPULSE Is Enabled for RX channel 0   
        EMAC_CTRL->C0TXEN = 1; //C0TXPULSE IS enabled for tx channel 0
        return (rtn);
}
//-----------------------------------------------------------------------------
// \brief   power on the phy.
//
// \param   none.
//
// \return  uint32_t
//    ERR_NO_ERROR - everything is ok...phy is on.
//    ERR_FAIL - something happened and could not power on.
//-----------------------------------------------------------------------------
uint32_t EMAC_phyPowerOn(void)
{
   uint32_t rtn;
   uint16_t ctrl_reg;
   ctrl_reg = phyRegRead(g_active_phy_id, SMSC_REG_BASIC_CTRL);
   if (!CHKBIT(ctrl_reg, BASIC_CTRL_POWER_DOWN))
   {
      // phy is already on...nothing left to do.
      #if DEBUG
      printf("phy powered, basic ctrl reg: %04x\n", ctrl_reg);
      #endif
      rtn = ERR_NO_ERROR;
   }
   else
   {
      // clear power down bit and write back to phy.
      CLRBIT(ctrl_reg, BASIC_CTRL_POWER_DOWN);
      phyRegWrite(g_active_phy_id, SMSC_REG_BASIC_CTRL, ctrl_reg);
      // short delay, then read the reg back to verify loopback is enabled.
      USTIMER_delay(500);
      ctrl_reg = phyRegRead(g_active_phy_id, SMSC_REG_BASIC_CTRL);
      if (!CHKBIT(ctrl_reg, BASIC_CTRL_POWER_DOWN))
      {
         // phy is powered...return success.
         #if DEBUG
         printf("phy powered, basic ctrl reg: %04x\n", ctrl_reg);
         #endif
         rtn = ERR_NO_ERROR;
      }
      else
      {
         // power down bit did not clear...return error.
         #if DEBUG
         printf("power down did not clear: %04x\n", ctrl_reg);
         #endif
         rtn = ERR_FAIL;
      }
   }
   return (rtn);
}
//-----------------------------------------------------------------------------
// \brief   power down the phy.
//
// \param   none.
//
// \return  uint32_t
//    ERR_NO_ERROR - everything is ok...phy is powered down.
//    ERR_FAIL - something happened and could not power down.
//-----------------------------------------------------------------------------
uint32_t EMAC_phyPowerDown(void)
{
   uint32_t rtn;
   uint16_t ctrl_reg;
   ctrl_reg = phyRegRead(g_active_phy_id, SMSC_REG_BASIC_CTRL);
   if(CHKBIT(ctrl_reg, BASIC_CTRL_ISOLATE) && CHKBIT(ctrl_reg, BASIC_CTRL_POWER_DOWN))
   {
      // phy is already powered down...nothing left to do.
      #if DEBUG
      printf("phy powered down, basic ctrl reg: %04x\n", ctrl_reg);
      #endif
      rtn = ERR_NO_ERROR;
   }
   else
   {
      // set power down bit and write back to phy.
      SETBIT(ctrl_reg, BASIC_CTRL_ISOLATE | BASIC_CTRL_POWER_DOWN);
      phyRegWrite(g_active_phy_id, SMSC_REG_BASIC_CTRL, ctrl_reg);
      // short delay, then read the reg back to verify loopback is disabled.
      USTIMER_delay(500);
      ctrl_reg = phyRegRead(g_active_phy_id, SMSC_REG_BASIC_CTRL);
      if(CHKBIT(ctrl_reg, BASIC_CTRL_ISOLATE) && CHKBIT(ctrl_reg, BASIC_CTRL_POWER_DOWN))
      {
         // phy is powered down...return success.
         #if DEBUG
         printf("phy powered down, basic ctrl reg: %04x\n", ctrl_reg);
         #endif
         rtn = ERR_NO_ERROR;
      }
      else
      {
         // power down bit did not set...return error.
         #if DEBUG
         printf("power down bit did not set: %04x\n", ctrl_reg);
         #endif
         rtn = ERR_FAIL;
      }
   }
   return (rtn);
}
//-----------------------------------------------------------------------------
// \brief   put the phy into loopback mode.
//
// \param   none.
//
// \return  uint32_t
//    ERR_NO_ERROR - everything is ok...phy is in loopback mode.
//    ERR_FAIL - something happened and could not enter loopback.
//-----------------------------------------------------------------------------
uint32_t EMAC_phyEnterLoopback(void)
{
   uint32_t rtn;
   uint16_t ctrl_reg;

   ctrl_reg = phyRegRead(g_active_phy_id, SMSC_REG_BASIC_CTRL);
   rtn = ERR_NO_ERROR;
   if (ctrl_reg & BASIC_CTRL_LOOPBACK)
   {
      // loopback is already enabled...nothing left to do.
      #if DEBUG
      printf("loopback enabled, basic ctrl reg: %04x\n", ctrl_reg);
      #endif
      rtn = ERR_NO_ERROR;
   }
   else
   {
      // set loopback bit and write back to phy.
      ctrl_reg |= BASIC_CTRL_LOOPBACK;
      phyRegWrite(g_active_phy_id, SMSC_REG_BASIC_CTRL, ctrl_reg);
      // short delay, then read the reg back to verify loopback is enabled.
      USTIMER_delay(500);
      ctrl_reg = phyRegRead(g_active_phy_id, SMSC_REG_BASIC_CTRL);
      if (ctrl_reg & BASIC_CTRL_LOOPBACK)
      {
         // loopback is enabled...return success.
         #if DEBUG
         printf("loopback enabled , basic ctrl reg: %04x\n", ctrl_reg);
         #endif
         rtn = ERR_NO_ERROR;
      }
      else
      {
         // loopback bit did not get set...return error.
         #if DEBUG
         printf("loopback did not set: %04x\n", ctrl_reg);
         #endif
         rtn = ERR_FAIL;
      }
   }
   return (rtn);
}
//-----------------------------------------------------------------------------
// \brief   remove the phy from loopback mode.
//
// \param   none.
//
// \return  uint32_t
//    ERR_NO_ERROR - everything is ok...phy is out of loopback mode.
//    ERR_FAIL - something happened and could not disable loopback.
//-----------------------------------------------------------------------------
uint32_t EMAC_phyExitLoopback(void)
{
   uint32_t rtn;
   uint16_t ctrl_reg;
   ctrl_reg = phyRegRead(g_active_phy_id, SMSC_REG_BASIC_CTRL);
   if (!(ctrl_reg & BASIC_CTRL_LOOPBACK))
   {
      // loopback is already disabled...nothing left to do.
      #if DEBUG
      printf("loopback disabled, basic ctrl reg: %04x\n", ctrl_reg);
      #endif
      rtn = ERR_NO_ERROR;
   }
   else
   {
      // clear loopback bit and write back to phy.
      ctrl_reg &= ~BASIC_CTRL_LOOPBACK;
      phyRegWrite(g_active_phy_id, SMSC_REG_BASIC_CTRL, ctrl_reg);
      // short delay, then read the reg back to verify loopback is disabled.
      USTIMER_delay(5);
      ctrl_reg = phyRegRead(g_active_phy_id, SMSC_REG_BASIC_CTRL);
      if (!(ctrl_reg & BASIC_CTRL_LOOPBACK))
      {
         // loopback is disabled...return success.
         #if DEBUG
         printf("loopback disabled , basic ctrl reg: %04x\n", ctrl_reg);
         #endif
         rtn = ERR_NO_ERROR;
      }
      else
      {
         // loopback bit did not clear...return error.
         #if DEBUG
         printf("loopback did not clear: %04x\n", ctrl_reg);
         #endif
         rtn = ERR_FAIL;
      }
   }
   return (rtn);
}
//-----------------------------------------------------------------------------
// Private Function Definitions
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// initialize the mdio module and identify the active phy.
//-----------------------------------------------------------------------------
uint32_t initMdioPhy(void)
{
   uint32_t i = 0;
   uint16_t phy_reg;
   // init the mdio regs.
   MDIO->CONTROL = MDIO_CTRL_ENABLE |
                     MDIO_CTRL_FAULT |
                     MDIO_CTRL_FAULTENB |
                     MDIO_CLK_DIVISOR;
   while (CHKBIT(MDIO->CONTROL, MDIO_CTRL_IDLE)) {;}
#if DEBUG_MDIO_LINK
   // look for an active phy...takes up to 50 us for each phy to be checked.
   //以下只是调试时有用,真正烧入程序中去时,是不行的,因为没插上网线,AddISR还要上的。
   for (i = 0; i < MAX_POLLING_NUM; i++)
   {
      if (MDIO->ALIVE)
      {
         // at least one phy has acknowledged us...break the loop.
         break;
      }
      USTIMER_delay(50);  // polling , 采用polling方式,LP- delete
   }
   while(!(MDIO->ALIVE)); //还是没有找到PHY,它就在此处挂住
#else
        while(!(MDIO->ALIVE)) //没有网线连接
        {
                i++;
                if(i >= MAX_POLLING_NUM)
                {
                        break;
                }
        }//只是为了延时让phy与PC自适应的时涞却??
#endif
//
   g_active_phy_id = 0; //确实是个发生错误,现在可以读到PHY。
   MDIO->USERPHYSEL0 = 0;        //USERPHYSEL0 = 0,表示PHY0被选中监控。
#if DEBUG_MDIO_LINK
   phy_reg = phyRegRead(g_active_phy_id,0x02); //phy-id,查看phyRegRead是否正确;
   if(phy_reg != 0x0022) //不等则芯片焊错
   {
        while(1);
   }
#endif
   return (ERR_NO_ERROR);
}
//-----------------------------------------------------------------------------
// returns if the link is currently active...1 -> active, 0 -> not active.
//-----------------------------------------------------------------------------
uint8_t isLinkActive(uint8_t in_phy)
{
   uint16_t status;
   status = phyRegRead(in_phy, SMSC_REG_BASIC_STAT);
   
   if (CHKBIT(status, BASIC_STAT_LINK_STAT))
      return (1);
   else
      return (0);
}
//-----------------------------------------------------------------------------
// read a phy register using the MDIO.
//-----------------------------------------------------------------------------
uint16_t phyRegRead(uint8_t in_phy, uint8_t in_reg)
{
   // make sure mdio is not busy.
   while (CHKBIT(MDIO->USERACCESS0, USERACC_GO)) {}
   MDIO->USERACCESS0 = USERACC_GO |
                        (in_reg << USERACC_SHIFT_REG) |
                        (in_phy << USERACC_SHIFT_PHY);
   while (CHKBIT(MDIO->USERACCESS0, USERACC_GO)) {}
   return ((uint16_t)(MDIO->USERACCESS0 & USERACC_MASK_DATA));
}
//-----------------------------------------------------------------------------
// write a phy register using the MDIO.
//-----------------------------------------------------------------------------
void phyRegWrite(uint8_t in_phy, uint8_t in_reg, uint16_t in_data)
{
   // make sure mdio is not busy.
   while (CHKBIT(MDIO->USERACCESS0, USERACC_GO)) {}
   MDIO->USERACCESS0 = USERACC_GO |
                        USERACC_WRITE |
                        (in_reg << USERACC_SHIFT_REG) |
                        (in_phy << USERACC_SHIFT_PHY) |
                        in_data;
}

代码其中之二:
/** Emac_des.c
** 由于在接收的过程中,可能存在一定的descriptor 问题,同时在与pbuf结合的情况
** 也存在着一些问题,故作如下修改。
** 现在决定作如下修改:
************************************/
#include "includes.h"
#include "Emac_des.h"
#include "evmomapl138.h"
#include "lwip/def.h"
#include "lwip/pbuf.h"
#include "lwip/sys.h"
#include "lwip/opt.h"
#include "inc/evmomapl138_emac.h"
#include "etharp.h"
#include "ethernetif.h"
/* CPPI RAM size in bytes */
#ifndef SIZE_CPPI_RAM
#define SIZE_CPPI_RAM              0x2000   //8K, L138也一样
#endif

#define MAX_ALE_ENTRIES            1024
#define ENTRY_TYPE                 0x30
#define ENTRY_TYPE_IDX             7
#define ENTRY_FREE                 0
/* MDIO input and output frequencies in Hz */
#define MDIO_FREQ_INPUT            125000000
#define MDIO_FREQ_OUTPUT           1000000
//flag --> 一样的描述
#define CPDMA_BUF_DESC_OWNER       0x20000000
#define CPDMA_BUF_DESC_SOP         0x80000000
#define CPDMA_BUF_DESC_EOP         0x40000000
#define CPDMA_BUF_DESC_EOQ         0x10000000
#define MAX_TRANSFER_UNIT          1518 // Lp modified
#define PBUF_LEN_MAX               MAX_TRANSFER_UNIT
#define MAX_RX_PBUF_ALLOC          20   //使用20个看看
#define MIN_PKT_LEN                60
/* Define those to better describe the network interface. */
#define IFNAME0                   'e'
#define IFNAME1                   'n'

/* TX Buffer descriptor data structure */
struct cpdma_tx_bd {
  volatile struct cpdma_tx_bd *next;
  volatile u32_t bufptr;
  volatile u32_t bufoff_len;
  volatile u32_t flags_pktlen;
  
  /* 添加了一个这样的数据结构 */
  volatile struct pbuf *pbuf;
}cpdma_tx_bd;
/* RX Buffer descriptor data structure */
struct cpdma_rx_bd {
  volatile struct cpdma_rx_bd *next;
  volatile u32_t bufptr;
  volatile u32_t bufoff_len;
  volatile u32_t flags_pktlen;
  /*添加了pbuf数据结构*/
  volatile struct pbuf *pbuf;
}cpdma_rx_bd;
/**为的是编程者更好的处理RX channel发生的事件。***/
struct rxch {
  volatile struct cpdma_rx_bd *free_head;
  volatile struct cpdma_rx_bd *active_head;
  volatile struct cpdma_rx_bd *active_tail;
  u32_t freed_pbuf_len;
}rxch;
/** 是TX Channel 更好的处理事件 ***/
struct txch {
  volatile struct cpdma_tx_bd *free_head;
  volatile struct cpdma_tx_bd *active_tail;
  volatile struct cpdma_tx_bd *next_bd_to_process;
}txch;

/**
** 这个是整个EMAC的操作界面数据结构 -- 不需要
*/
struct emac_trif {
  /* The tx/rx channels for the interface */
  struct txch txch;
  struct rxch rxch;
}emac_trif;
/*
** 初始化buffer descriptor
** 换了一个方式,用一个pbuf 链的方式来接收,免去拷贝。
*/
err_t
Emac_des_init( void )
{
  u32_t num_bd, pbuf_cnt = 0;
  volatile struct cpdma_tx_bd *curr_txbd, *last_txbd;
  volatile struct cpdma_rx_bd *curr_bd, *last_bd;
  struct txch *txch;
  struct rxch *rxch;
  struct pbuf *p, *q;
  //初始化.... 结构体..
  //struct emac_trif {
  memset((u8_t *)&emac_trif, 0, sizeof(emac_trif));
  //struct txch {
  memset((u8_t *)&txch, 0, sizeof(txch));
  //struct rxch
  memset((u8_t *)&rxch, 0, sizeof(rxch));
  //struct cpdma_rx_bd {
  memset((u8_t *)&cpdma_rx_bd, 0, sizeof(cpdma_rx_bd));
  //struct cpdma_tx_bd {
  memset((u8_t *)&cpdma_tx_bd, 0, sizeof(cpdma_rx_bd));
  //取出txch的地址,以便操作
  txch = &(emac_trif.txch);
//EMAC_RAM_BASE是L138的buffer descriptor 所在CPPI RAM的起始地址
  txch->free_head = (volatile struct cpdma_tx_bd*)(EMAC_RAM_BASE);
  txch->next_bd_to_process = txch->free_head;
  txch->active_tail = (volatile struct cpdma_tx_bd *)NULL;
//多少个buffer desc, tx_bd... 特意SIZE_CPPI_RAM/2
  num_bd = (SIZE_CPPI_RAM >> 1) / sizeof(cpdma_tx_bd);
  
  curr_txbd = txch->free_head;
  /* Initialize all the TX buffer Descriptors */
  while(num_bd--) {
    curr_txbd->next = curr_txbd + 1;
        curr_txbd->bufptr = 0; //初始化为0
    curr_txbd->bufoff_len = 0; //也初始化为0
    curr_txbd->flags_pktlen = 0;
    curr_txbd->pbuf = 0;//现在还并没有pbuf要准备发送
    last_txbd = curr_txbd;
    curr_txbd = curr_txbd->next;
  }
  last_txbd->next = txch->free_head;
  
  /* Initialize the descriptors for the RX channel */
  rxch = &(emac_trif.rxch);
  rxch->active_head = (volatile struct cpdma_rx_bd*)(curr_txbd + 1);
  
  rxch->free_head = (volatile struct cpdma_rx_bd *)NULL;
  rxch->freed_pbuf_len = 0;
  num_bd = ((SIZE_CPPI_RAM >> 1) / sizeof(cpdma_rx_bd) - 1);
  curr_bd = rxch->active_head;
  last_bd = curr_bd;
  /*
** 该驱动一个最大的不同就在此处,将接收的数据直接用DMA传送到pbuf,
** 以前我们都是用全局ram接收,而后拷贝至pbuf,还有一个不同就是
** 这里使用了EMAC部的CPPI_RAM空间,这样达到最好的效率。
** 但是为了考虑字节对齐的问题,还需要做点小小的修改
  */
  while(pbuf_cnt < MAX_RX_PBUF_ALLOC) {//产生10个pbuf..供接收DMA传送
#if ETH_PAD_SIZE
    p = pbuf_alloc(PBUF_RAW,(PBUF_LEN_MAX+ETH_PAD_SIZE), PBUF_POOL); //10 * 1500
        pbuf_header(p, -ETH_PAD_SIZE); //向后移2个字节,接收过后,刚刚好
#endif //ETH_PAD_SIZE
    pbuf_cnt++;
   
    if(p != NULL) {
      /* write the descriptors if there are enough numbers to hold the pbuf*/
      if(((u32_t)pbuf_clen(p)) <= num_bd) {
          // pbuf_clen(p)计算从p开始,pbuf链的长度
          //如果pbuf_alloc产生比num_bd更大长度的描述符,那么就是个悲剧了。
        for(q = p; q != NULL; q = q->next) {
          curr_bd->bufptr = (u32_t)(q->payload); //buffer_ptr
          curr_bd->bufoff_len = q->len; //buffoff & buffer_len
          curr_bd->next = curr_bd + 1; //next buffer descriptor
          curr_bd->flags_pktlen = CPDMA_BUF_DESC_OWNER; //flag set or clear
         
          /* Save the pbuf */
          curr_bd->pbuf = q;
          last_bd = curr_bd;
          curr_bd = curr_bd->next;
          num_bd--;
        }//for
      }//if <= num_bd
   
      /* free the allocated pbuf if no free descriptors are left */
      else {
        pbuf_free(p);
        break;
      }//else pbuf chain len > num_bd
    }//if p != NULL
    else {
      break;
    }//else p== NULL
  }//while 产生10个
  last_bd->next = (volatile struct cpdma_rx_bd *)NULL; //buff des chain 构造完成
  rxch->active_tail = last_bd; //rxch控制着整个rxch的接收方式
  EMAC->RXHDP[0] = (u32_t)(rxch->active_head); //add - lp
  return ERR_OK;
}

/**
** 使用该rx_inhandler处理接收中断
** 每个pbuf链在处理之前必须要向前移ETH_PAD_SIZE个字节,以便4字节对齐
** 当你还要产生pbuf的时候,也要向后移ETH_PAD_SIZE个字节,以便接收。
* @param netif the lwip network interface structure for this ethernetif
* @return none
*/
void
Emac_rxint_handler(struct netif *netif) {
  struct rxch *rxch;
  volatile struct cpdma_rx_bd *curr_bd, *processed_bd, *curr_tail, *last_bd;
  volatile struct pbuf *pbuf, *q, *new_pbuf;
  u32_t ex_len = 0, len_to_alloc = 0;
  u16_t tot_len;
//  sitaraif = netif->state;
  rxch = &(emac_trif.rxch);
  //得到当前的rxch buffer desc
  curr_bd = rxch->active_head;
  last_bd = rxch->active_tail;
  
  //pbuf链中,SOP只出现一次,但是curr_bd已将buffer链推向下一个可能出现
  //SOP的开头,所以这种方式更加严谨和有效。        
   while(curr_bd->flags_pktlen & CPDMA_BUF_DESC_SOP) {
  //用while是因为pbuf链来处理的
    ex_len = 0;
    len_to_alloc = 0;
    //当OWNER被EMAC清掉的时候,EMAC就放弃了buff desc,可以做一些处理
    if((curr_bd->flags_pktlen & CPDMA_BUF_DESC_OWNER)
       != CPDMA_BUF_DESC_OWNER) {
      if(rxch->free_head == NULL) {
        /* this bd chain will be freed after processing */
        rxch->free_head = curr_bd;     
      }//if NULL
     
          //得到该接收到packet_len的长度
      tot_len = (curr_bd->flags_pktlen) & 0xFFFF;
      //保存当前接收的起始pbuf
      q = curr_bd->pbuf;
         //以下循环体为了更新除pbuf->payload除外,在结构体pbuf中
         //的len,tot_len数据
      do {
                //得到当前pbuf地址
        pbuf = curr_bd->pbuf;
        
        /* If the earlier pbuf ended, update the chain */
        if(pbuf->next == NULL) {
          pbuf->next = (struct pbuf*)(curr_bd->next)->pbuf;
        } //if Null
      
                //len_to_alloc , pbuf链中的len的总和
        len_to_alloc += pbuf->len;
        /* Update the len and tot_len fields for the pbuf in the chain*/
        pbuf->len = (curr_bd->bufoff_len) & 0xFFFF; //当前pbuf长度
        pbuf->tot_len = tot_len - ex_len ; //当前pbuf后的tot_len长度(含自己)
        processed_bd = curr_bd; //处理中的desc
        ex_len += pbuf->len;
        curr_bd = curr_bd->next;
      } while((processed_bd->flags_pktlen & CPDMA_BUF_DESC_EOP)
              != CPDMA_BUF_DESC_EOP);
      /**
       * Close the chain for this pbuf. A full packet is received in
       * this pbuf chain. Now this pbuf can be given to upper layers for
       * processing. The start of the pbuf chain is now 'q'.
      */
      pbuf->next = (struct pbuf *)NULL;
  
//在q处理之前,需要加上ETH_PAD_SIZE个空间,以便4字节对齐
#if ETH_PAD_SIZE
        if(q != NULL)
        {
            pbuf_header((struct pbuf *)q, ETH_PAD_SIZE);
#endif //ETH_PAD_SIZE
//为了节省中断的处理效率,这里节省时间,直接post msg给tcpip_thread
                if((netif->input((struct pbuf *)q,netif)) != ERR_OK)
                {
                        pbuf_free((struct pbuf *)q);
                        q = (volatile struct pbuf *)NULL;
                }
#if ETH_PAD_SIZE
        } //ETH_PAD_SIZE
#endif //ETH_PAD_SIZE
      /* Acknowledge that this packet is processed */
//      CPSWCPDMARxCPWrite(sitaraif->cpsw_cpdma_base, 0, (unsigned int)processed_bd);
          EMAC->RXCP[0] = (u32_t)processed_bd;
      rxch->active_head = curr_bd;
   
      /**
       * The earlier pbuf chain is freed from the upper layer. So, we need to
       * allocate a new pbuf chain and update the descriptors with the pbuf info.
       * To support chaining, the total length freed by the upper layer is tracked.
       * Care should be taken even if the allocation fails.
       */   
      /**
       * now len_to_alloc will contain the length of the pbuf which was freed
       * from the upper layer
       */
      rxch->freed_pbuf_len += len_to_alloc;
      new_pbuf = pbuf_alloc(PBUF_RAW, ((rxch->freed_pbuf_len)+ETH_PAD_SIZE), PBUF_POOL);
      /* Write the descriptors with the pbuf info till either of them expires */
      if(new_pbuf != NULL) {
#if ETH_PAD_SIZE
                   pbuf_header((struct pbuf *)new_pbuf, -ETH_PAD_SIZE);
#endif //ETH_PAD_SIZE
        curr_bd = rxch->free_head; //free_head,已经被释放的head,需要重新set
                //以下循环体添加新的pbuf到curr_bd中去
        for(q = new_pbuf; (q != NULL) && (curr_bd != rxch->active_head); q = q->next) {
          curr_bd->bufptr = (u32_t)(q->payload);
         
          /* no support for buf_offset. RXBUFFEROFFEST register is 0 */
          curr_bd->bufoff_len = (q->len) & 0xFFFF;
          curr_bd->flags_pktlen = CPDMA_BUF_DESC_OWNER;
         
          rxch->freed_pbuf_len -= q->len;
         
          /* Save the pbuf */
          curr_bd->pbuf = q;
          last_bd = curr_bd;
          curr_bd = curr_bd->next;
        }//for
         
        /**
         * At this point either pbuf expired or no rxbd to allocate. If
         * there are no, enough rx bds to allocate all pbufs in the chain,
         * free the rest of the pbuf
         */
        if(q != NULL) {
          pbuf_free((struct pbuf *)q);
        }
      
        curr_tail = rxch->active_tail;
        last_bd->next = (volatile struct cpdma_rx_bd *)NULL;
      
        curr_tail->next = rxch->free_head;
        
        /**
         * Check if the reception has ended. If the EOQ flag is set, the NULL
         * Pointer is taken by the DMA engine. So we need to write the RX HDP
         * with the next descriptor.
         */
        if(curr_tail->flags_pktlen & CPDMA_BUF_DESC_EOQ) {
//          CPSWCPDMARxHdrDescPtrWrite(sitaraif->cpsw_cpdma_base,
//                                   (u32_t)(rxch->free_head), 0);
                        EMAC->RXHDP[0] = (u32_t)(rxch->free_head);
        }//if EOQ
        rxch->free_head  = curr_bd;
        rxch->active_tail = last_bd;
      }//if new_pbuf
    }//if OWNER
    curr_bd = rxch->active_head;
//以下这句,L138未做要求.
//    CPSWCPDMANumFreeBufSet(sitaraif->cpsw_cpdma_base, 0, 1);
// -----------括号不要删-------------------------------
  }//While ....
//-------------------------------------------
// 以下在外面写
//  CPSWCPDMAEndOfIntVectorWrite(sitaraif->cpsw_cpdma_base, CPSW_EOI_TX_PULSE);  
//  CPSWCPDMAEndOfIntVectorWrite(sitaraif->cpsw_cpdma_base, CPSW_EOI_RX_PULSE);  
}
//---------------------------------------------------------------
//以下是发送部分
//---------------------------------------------------------------
/**
** 这个函数将pbuf链的数据发送给物理层,可能buffer_des连接多处,因为是
** pbuf链连接而成的
* @return None
**/
void Emac_transmit(struct pbuf *pbuf) {
  struct pbuf *q;
  struct txch *txch;
  volatile struct cpdma_tx_bd *curr_bd, *active_head, *bd_end;
// 取地址。
  txch = &(emac_trif.txch);
//得到可以使用的空闲head
  curr_bd = txch->free_head;
  //激活的head
  active_head = curr_bd;
  //更新该头的packet len 字段
  curr_bd->flags_pktlen &= ~0xFFFF;
  curr_bd->flags_pktlen |= pbuf->tot_len;
  //交给EMAC之前,置位flags, SOP,OWNER
  curr_bd->flags_pktlen |= (CPDMA_BUF_DESC_SOP | CPDMA_BUF_DESC_OWNER);
  //把pbuf信息构建成buffer desc 链
  for(q = pbuf; q != NULL; q = q->next) {
    /* Intialize the buffer pointer and length */
    curr_bd->bufptr = (u32_t)(q->payload);
    curr_bd->bufoff_len = (q->len) & 0xFFFF;
    bd_end = curr_bd;
    curr_bd->pbuf = pbuf;
    curr_bd = curr_bd->next;
  }
  //将buffer desc结尾
  bd_end->next = (volatile struct cpdma_tx_bd *)NULL;
  bd_end->flags_pktlen |= CPDMA_BUF_DESC_EOP;
  //free_head指向下一个空的buff descriptor 处
  txch->free_head = curr_bd;
  //经过初始化之后,txch->active_tail指向NULL,但是发送buffer desc是一个
  //单向的循环链表。所以这也是上面为什么bd_end->next要赋NULL值
  if(txch->active_tail == NULL) {
// 第一次发送active_head
                EMAC->TXHDP[0] = (u32_t)active_head;
  }
  /*
  **第1次发送过后,假如发送完了,那么transmiter 将会halt,这样CPU在
  **发送之前必须确认EOQ是否set,如果set,那么对于CPU来讲可以写HDP启动
  **TXDMA发送了。
  */
  else {
    curr_bd = txch->active_tail;
    curr_bd->next = active_head;
    if(curr_bd->flags_pktlen & CPDMA_BUF_DESC_EOQ) {
     //假如EOQ被EMAC set之后,就启动tx DMA
                EMAC->TXHDP[0] = (u32_t)active_head;
    }
  }
  txch->active_tail = bd_end;
}
/**
* This function will send a packet through the emac if the channel is
* available. Otherwise, the packet will be queued in a pbuf queue.
*
* @param netif the lwip network interface structure for this ethernetif
* @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
* @return ERR_OK if the packet could be sent
*         an err_t value if the packet couldn't be sent
*
*/
err_t
OmapEmac_output(struct netif *netif, struct pbuf *p)
{
  INT8U os_err = 0;
  SYS_ARCH_DECL_PROTECT(lev);
  //等待有效的信号量才能发送
//  OSSemPend(TxCmpSem, 1000, &os_err); // --LP , 2012/04/28 DLT
  /**
   * This entire function must run within a "critical section" to preserve
   * the integrity of the transmit pbuf queue.
   *
   */
  SYS_ARCH_PROTECT(lev);
//在选择发送之前,要调整p->payload的两字节,因为它们不能发送出去
#if ETH_PAD_SIZE
  pbuf_header(p, -ETH_PAD_SIZE);
#endif
  /* adjust the packet length if less than minimum required */
  if(p->tot_len < MIN_PKT_LEN) {
     p->tot_len = MIN_PKT_LEN;
     p->len = MIN_PKT_LEN;
  }
  /**
   * Bump the reference count on the pbuf to prevent it from being
   * freed till we are done with it.
   *
   */
  pbuf_ref(p);
   
  //Emac物理层的发送。DMA 用了TX中断的方式
  Emac_transmit(p);
  /* Return to prior interrupt state and return. */
  SYS_ARCH_UNPROTECT(lev);
  
  return ERR_OK;
}
/**
** lower level 已经启动DMA发送了吗,这里是为了软件清掉SOP和EOP,然后就是pbuf
** 链表的回收。
* @param netif the lwip network interface structure for this ethernetif
* @return none
*/
void
Emac_txint_handler(struct netif *netif) {
  struct txch *txch;
  volatile struct cpdma_tx_bd *curr_bd, *next_bd_to_process;  
  
//取txch结构体的地址
  txch = &(emac_trif.txch);
//下一待处理的buff des, next_bd_to_process被初始化为(EMAC_RAM_BASE)   
  next_bd_to_process = txch->next_bd_to_process;
// 用curr_bd来处理  
  curr_bd = next_bd_to_process;
  
  /* Check for correct start of packet */
  while((curr_bd->flags_pktlen) & CPDMA_BUF_DESC_SOP) {
   
    /* Make sure that the transmission is over */
    while((curr_bd->flags_pktlen & CPDMA_BUF_DESC_OWNER)
          == CPDMA_BUF_DESC_OWNER);
   
    /* Traverse till the end of packet is reached */
    while(((curr_bd->flags_pktlen) & CPDMA_BUF_DESC_EOP) != CPDMA_BUF_DESC_EOP) {
       curr_bd = curr_bd->next;
    }//while(!EOP)
    next_bd_to_process->flags_pktlen &= ~(CPDMA_BUF_DESC_SOP);
    curr_bd->flags_pktlen &= ~(CPDMA_BUF_DESC_EOP);
    /**
     * If there are no more data transmitted, the next interrupt
     * shall happen with the pbuf associated with the free_head
     */
    if(curr_bd->next == NULL) {
      txch->next_bd_to_process = txch->free_head;
    }
  
    else {
      txch->next_bd_to_process = curr_bd->next; //接着处理下一帧数据包
    }
   
    //写TXCP[],该帧数据包已经写完
//    CPSWCPDMATxCPWrite(sitaraif->cpsw_cpdma_base, 0, (u32_t)curr_bd);
        EMAC->TXCP[0] = (u32_t)curr_bd;
    pbuf_free((struct pbuf *)curr_bd->pbuf);
//    LINK_STATS_INC(link.xmit);
   
    next_bd_to_process = txch->next_bd_to_process;
    curr_bd = next_bd_to_process;
  }
  //发送信号量给发送部分保证发送的完整性。
//        OSSemPost(TxCmpSem);  //--lp , 2012/04/28 delete,查看效果。
//在外面写的
//  CPSWCPDMAEndOfIntVectorWrite(sitaraif->cpsw_cpdma_base, CPSW_EOI_TX_PULSE);
//  CPSWCPDMAEndOfIntVectorWrite(sitaraif->cpsw_cpdma_base, CPSW_EOI_RX_PULSE);
}
/********************* this file is end ****************************/
代码其中之三:
/**************************************************************************
*                                                                         *
*   PROJECT     : TMON (Transparent monitor)                              *
*                                                                         *
*   MODULE      : LWIP.c                                                  *
*                                                                         *
*   AUTHOR      : Michael Anburaj                                         *
*                 URL  : http://geocities.com/michaelanburaj/             *
*                 EMAIL: michaelanburaj@hotmail.com                       *
*                                                                         *
*   PROCESSOR   : Any                                                     *
*                                                                         *
*   Tool-chain  : gcc                                                     *
*                                                                         *
*   DESCRIPTION :                                                         *
*   LwIP master source file.                                              *
*                                                                         *
**************************************************************************/
#include "tcpip.h"
#include "ethernetif.h"
#include "netconf.h"
/* ********************************************************************* */
/* Global definitions */
netif_t     main_net;
/* ********************************************************************* */
/* File local definitions */

/* ********************************************************************* */
/**
*** 初始化LwIP的协议栈
  */
void LwIP_Init( void )
{
  struct ip_addr ipaddr;
  struct ip_addr netmask;
  struct ip_addr gw;
      
  tcpip_init(NULL, NULL);
  
/** 在此处初始化IP地址 **/
  IP4_ADDR(&ipaddr,192,168,1,88); //该宏需要执行的!
  IP4_ADDR(&netmask,255,255,255,0);
  IP4_ADDR(&gw,192,168,0,1);
  MEMCPY(main_net.name,"glzn",4);
#if LWIP_NETIF_HOSTNAME  
  main_net.hostname = GetHostName();
#endif
  /* - netif_add(struct netif *netif, struct ip_addr *ipaddr,
            struct ip_addr *netmask, struct ip_addr *gw,
            void *state, err_t (* init)(struct netif *netif),
            err_t (* input)(struct pbuf *p, struct netif *netif))
   
   Adds your network interface to the netif_list. Allocate a struct
  netif and pass a pointer to this structure as the first argument.
  Give pointers to cleared ip_addr structures when using DHCP,
  or fill them with sane numbers otherwise. The state pointer may be NULL.
  The init function pointer must point to a initialization function for
  your ethernet netif interface. The following code illustrates it's use.*/
  
  
  netif_add(&main_net, &ipaddr, &netmask, &gw, NULL, ðernetif_init, &tcpip_input);
  /*  Registers the default network interface.*/
  netif_set_default(&main_net);  //可以删除 --2012/02/02, netif_default
  /*  When the netif is fully configured this function must be called.*/
   netif_set_up(&main_net); //this functional
}


/* ********************************************************************* */
代码其中之四:
//主程序
//修改成适应LwIP v140的协议,此为系统main主函数
#include
#include
#include "dspint.h"
#include "sample.h"
#include "edma.h"
#include "norflash.h"
#include "evmomapl138.h"
#include "evmomapl138_gpio.h"
#include "evmomapl138_uart.h"
#include "evmomapl138_rtc.h"
#include "io.h"
#include "fpga_emifa.h"
#include "test_fpga.h"
//推荐的任务堆栈区大小为2048 OS_STK,即8192 byte
#define COMMON_STACK_LEN 2048
//给各个任务分配的堆栈区
OS_STK  TaskLWIPStk[COMMON_STACK_LEN];
OS_STK        TaskAppMainStk[COMMON_STACK_LEN];
OS_STK        TaskMMIStk[COMMON_STACK_LEN];
OS_STK        TaskFpgaUPPStk[COMMON_STACK_LEN];
OS_STK        TaskFpgaEMIFAStk[COMMON_STACK_LEN * 32];
//OS_STK        TaskTestStk[COMMON_STACK_LEN];
//各个任务进程主函数
void TaskAppMain(void *pd);
void TaskMMI(void *pd);//通过upp总线刷液晶数据,触发dsp中断,启动upp发送
extern void TaskLWIP(void *p_arg); //TaskLWIP任务
//extern void TaskTest(void *pd);

int main()
{
        //初始化中断向量
        OS_CPU_InitExceptVect();
        //初始化uC/OS-II实时内核
    OSInit();
        //创建系统主进程任务(放在最高优先级,包括装置定值、参数自检测,并作为其他任务的WatchDog。)
        OSTaskCreate(TaskAppMain, (void *)0, (OS_STK*)&TaskAppMainStk[COMMON_STACK_LEN-1], 2);
    //启动操作系统内核
        OSStart();
}
//系统主进程任务
void TaskAppMain(void *pd)
{
        unsigned char ucErr;
        tmr0_init();
        GPIOInit();
        chipint_init();
        memset((unsigned char *)TaskLWIPStk, 0, (COMMON_STACK_LEN*sizeof(OS_STK)));
//初始化由Lwip任务堆栈开辟的堆栈区域
        //INT8U enledflag = /;
        //INT32U counter = 0;
        //创建任务
        //OSTaskCreate(TaskFPGA_UPP, (void *)0, (OS_STK*)&TaskFpgaUPPStk[COMMON_STACK_LEN-1], 11);
//        OSTaskCreate(TaskFPGA_EMIFA, (void *)0, (OS_STK*)&TaskFpgaEMIFAStk[COMMON_STACK_LEN-1], 12);
//        OSTaskCreate(TaskMMI, (void *)0, (OS_STK*)&TaskMMIStk[COMMON_STACK_LEN-1], 13);
        //OSTaskCreate(TaskTest, (void *)0, (OS_STK*)&TaskTestStk[COMMON_STACK_LEN-1],100);
        OSTaskCreate(TaskLWIP,(void *)0,(OS_STK *)&TaskLWIPStk[COMMON_STACK_LEN -1],10);
        while(1)
        {
                  /*asm(" nop");
        counter++;
                if(counter >=20)
                {
                   enledflag ^=0x01;
           inb(ARM_DSP_CMD) = enledflag;
                   DspintArmtrip(DSPINTTYPE_2);
           counter = 0;
                }
                if(enledflag == 0)
                {
                        ledchange();
                }*/
//                OSTimeDly(500);
//                OSMboxPend(RxCntMbox,0,&ucErr);
            OSTimeDly(1000);
                asm(" nop");
        }
}
//
#define  SHAREMMI_ADR    (0x80000200)     //共享液晶显示数据区地址
#define  MMI_LNUM        (240)            //液晶显示一屏数据的行数目
#define  MMI_LBYTE       (40)             //液晶显示一屏数据的行字节数目320/8
#define  MMI_DATALEN     (MMI_LNUM*MMI_LBYTE) //液晶显示缓冲区长度
#define  SHARERAW_ADR    (0x8002800)     //共享原始数据区地址
#define  SHAREMEA_ADR    (0x8001f000)     //共享测量结果区地址
//显存
#define LCD_XSIZE        (320)       // X方向像素
#define LCD_YSIZE        (240)       // Y方向像素
#define LCDMLEN ((LCD_XSIZE*LCD_YSIZE)/8)
INT8U LcdMemory[LCDMLEN];
void loadMMIdata()
{
   INT8U *pobject;
   INT16U i;
   static INT8U showdata = 0;
   static INT8U changeflag = 0;
   changeflag++;
   if(changeflag==6)
   {
                changeflag=0;
                showdata++;
   }
   pobject =LcdMemory;//(INT8U*)SHAREMMI_ADR;
   if(showdata == 0)
   {
                for(i=0;i
            {
               *pobject++ = (i+1)&0xff;
            }
   }
   else
   {
                for(i=0;i
           {
               *pobject++ = showdata;
           }
   }   
}
void TaskMMI(void *pd)
{
        while(1)
        {
            
                //pushus(0);
        //loadMMIdata();
                //EDMA0config(0,(void*)LcdMemory,(void*)SHAREMMI_ADR,LCDMLEN);
               
                //pushus(1);
                RelayTest();
                OSTimeDly(100);
        }
}

代码其中之五:
/* main.c
** test lwip
***************************************************/
#include
#include "evmomapl138.h"
#include
#include
#include
#include "lwip/mem.h"
#include "lwip/memp.h"
#include "lwip/netif.h"
#include "lwip/tcpip.h"
#include "lwip.h"
// LwIP task stk Information
/**
** DEBUG Information
****************************************************/
/**
** global value
***************************************************/
/**
** function decl
**************************************************/
static void BSP_Init(void );
void tcpip_init_done(void *arg);
/* App_LwipTask
**
************************************************************************/
void TaskLWIP(void *parg)
{
        //加载网卡驱动
        //加载L138本身自带的EMAC驱动
        //Lwip_v140使用lwip.c处理初始化网口的信息,主任务只要调用lwip_Init()即可
        LwIP_Init();
        while(1)
        {
                OSTimeDly(2000);
        }
}
/* BSP_Init()
** 配置启动的时钟,貌似omapL138_app/boot.asm 中
** 有初始化STACK等配置,但是没有见到其内有时钟配置,工程初始化时也没有发现。
** 故要初始化PLL
********************************************/
void BSP_Init(void)
{
        EVMOMAPL138_Init();
}
我贴了一些代码,请看看帮帮忙,我真不知道该如何解决啦...

最新回复

我的6678,也是ping不通,不知道楼主解决没  详情 回复 发表于 2016-1-25 14:50
点赞 关注
 

回复
举报

2

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
我的6678,也是ping不通,不知道楼主解决没
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表